У меня в жизни две страсти. Один занимается компьютерным программированием, а другой играет на саксофоне. Когда я говорю это людям, часто встречаю удивление. Кажется, что большинству людей эти две вещи кажутся совершенно разными. Для меня это не так, и я обычно отвечаю, что это одна и та же область моего мозга, которая работает, когда я делаю эти две разные вещи.

Однако эта статья не об этом. Речь идет о том, как программирование может быть полезно в повседневной жизни. Я хочу поговорить о ситуации, когда мне пришлось использовать оба этих навыка. Год назад мой друг Dareminder Blackseed попросил меня выступить на его выпускном концерте. Об этом я сообщил на своей странице в Facebook. У меня есть еще один друг, Радж, который работает в стартапе под названием Look8. Когда Радж увидел мой пост, он попросил меня транслировать концерт онлайн. Я неохотно согласился, полагая, что это потребует дополнительной работы, которая не позволит мне сосредоточиться на своей работе. Однако я заметил, что снимать видео было довольно весело. Я нашел место в задней части концертного зала, где я мог разместить свой мобильный телефон во время выступления.

Я подумал, что видео получилось неплохим, и я использовал приложение Look8, чтобы смотреть его снова и снова и показывать как можно большему количеству людей вокруг меня. Хочу выложить видео на YouTube. Я спросил Раджа, возможно ли это. Он сказал, что это запланированная функция, и Look8 в конечном итоге получит веб-страницу, на которой можно будет напрямую ссылаться на видео. Однако на данный момент этого нет.

Я не хочу, чтобы читатель воспринял эту статью как какую-либо критику службы Look8 или того факта, что функция загрузки видео еще не реализована. Я понимаю, что создание любой функции в компьютерном приложении занимает много времени, и я рад, что меня пригласили принять участие в бета-запуске Look8. Однако функции пока нет, что делать?

В такие моменты полезно запустить наш 80-символьный черный на белом терминал и провести некоторое расследование.

Сообщение в Facebook выглядит так. Некоторые устрашающие коды. Но давайте не будем пугаться и будем сохранять спокойствие. В конце концов, это всего лишь ссылка, и мы можем щелкнуть по ней правой кнопкой мыши и скопировать URL. URL-адрес выглядит так:

https://streaming.look8.me/hls/48209a8d-ba1c-46d0-8c58-2a08fe605798/index.m3u8

За URL-адресом в Интернете скрывается ресурс данных, состоящий из битов и байтов. Это просто набор данных. Когда мы посещаем веб-страницу, тот факт, что это просто данные, не так очевиден, потому что веб-браузер показывает нам визуализированную веб-страницу, а не только данные. Однако если мы посмотрим на фактические данные, они часто могут выявить интересные вещи. Мы можем сделать это с помощью инструмента командной строки под названием cURL. Если вы раньше использовали командную оболочку UNIX, вы знаете, что команды unix предназначены для соединения друг с другом. Связь между командами называется труба. Ресурс, который составляет данные в URL-адресе, может быть очень большим, поэтому мы можем направить вывод в команду с именем head, которая показывает нам только первые десять строк данных. Глядя на это, мы можем предположить, что мы на правильном пути, поэтому давайте попробуем:

Ага, это интересно. Мы видим несколько строк, начинающихся с символа #. Символ решетки обычно обозначает какой-то комментарий, поэтому не будем обращать внимания на эти строки. Если не принимать во внимание эти строки, оставшиеся строки будут 180.ts, 181.ts и 182.ts. Это похоже на некую последовательность имён файлов. Это имеет смысл, поскольку это поток, но что такое файлы .ts? Спросим у гугла.

Так что нам даже не нужно переходить по этой ссылке. Все, что нам нужно знать на данный момент, это то, что файлы .ts имеют какое-то отношение к потоковой передаче и являются своего рода файлами. Давайте попробуем взять одну из них и посмотреть, можно ли в нее сыграть, используя vlc или что-то в этом роде. Но где они? Это всего лишь имена файлов, это не URL: s, поэтому мы действительно не знаем, как их загрузить. Предположим, что это относительный URL: s к URL-адресу потока. Попробуем скачать данные с такого URL и посмотрим. В этом случае нас действительно не интересуют фактические данные, поскольку они, вероятно, являются двоичными, но интересно знать, есть ли там какие-то данные или мы просто получаем ошибку 404. Так давайте попробуем:

Ага, похоже, там что-то бинарное. Так может это быть видеофайл? Давайте скачаем его и поиграем с vlc.

Ага! Вот и на сцене Dareminder Blackseed! В порядке. Так. Теперь интересно, что имя файла было 180.ts. Может ли быть так, что до 180.ts, который был первой записью в индексном файле, на самом деле было больше файлов, которые фактически составляли бы недостающую пару до последних 10 минут? Например, давайте попробуем скачать 100.ts и посмотрим.

Потрясающий! Кажется, что поток состоит из группы файлов .ts. Так можем ли мы скачать их все и склеить вместе? Во-первых, сколько их? Предположим, они начинают с нуля, но как далеко они зайдут? Давайте загрузим исходный индексный файл потока и посмотрим на него еще раз. На этот раз мы направляем вывод в «хвост», а не в «голову», поскольку нас интересует конец, а не начало.

Итак, кажется, что последний - 329.ts, то есть на самом деле их 330, если первый - 0.ts. Итак, что нам нужно сделать сейчас, это загрузить все 330 файлов, а затем найти способ склеить их вместе. как нам это сделать? Очевидно, мы могли бы сделать это, выполнив 330 команд оболочки. Если предположить, что для ввода команды и ее выполнения требуется около минуты, это займет пять с половиной часов. Это выполнимо. Если бы мне пришлось потратить пять с половиной часов, чтобы получить эту трансляцию, я бы сделал это, так как мне это очень нужно. Однако тратить так много времени на одно и то же скучно. Конечно, есть способ лучше - написать программу, которая будет загружать за нас. Я написал программу на PHP:

<?php
$baseurl="https://streaming.look8.me/hls/48209a8d-ba1c-46d0-8c58-2a08fe605798/";
for ($num=0; $num<330; $num++) {
    echo $num."\n";
    $fn=$num.".ts";
    $curl=curl_init();
    $fp=fopen($fn,"w");
    curl_setopt($curl,CURLOPT_URL,$baseurl.$fn);
    curl_setopt($curl,CURLOPT_FILE,$fp);
    curl_exec($curl);
    $code=curl_getinfo($curl,CURLINFO_HTTP_CODE);
    if ($code!=200)
        exit("code: ".$code);
    curl_close($curl);
}

Эта программа также использует cURL. На этот раз это не инструмент командной строки, а версия cURL PHP-библиотека. Программа представляет собой простой цикл, который выполняется 330 раз для загрузки каждого файла. Он также проверяет, была ли загрузка успешной, поэтому мы можем быть уверены, что каждый файл действительно был загружен правильно.

Хорошо! Итак, теперь у нас есть все 330 файлов .ts, как нам объединить их в один файл фильма? Я погуглил, и похоже, что есть программа под названием TS Joiner. На странице даны инструкции по его использованию:

Объединить несколько файлов TS вместе очень просто. Просто перетащите все нужные файлы TS на шкалу времени этого приложения внизу. Затем перетащите их, чтобы переставить их в соответствии с порядком воспроизведения. Пожалуйста, не кладите один файл на другой, иначе вы разделите последний файл.

Значит, нам нужно перетащить все наши 330 файлов на временную шкалу? Мы также должны быть осторожны, чтобы случайно не положить один файл поверх другого, иначе мы можем испортить результат. Что в этом легкого? К счастью, есть инструмент командной строки для подобных вещей, и он называется ffmpeg. Чтобы использовать его, нам сначала нужен простой список всех файлов, которые следует объединить. Мы можем создать такой список, используя следующую команду:

for f in `ls *.ts|sort -n`; do echo "file '$f'" >> mylist.txt; done

Это сценарий bash, и я обычно не выбираю его, потому что программы, которые вы пишете на нем, будет ужасно трудно читать. Однако для таких мелких вещей, как создание списка файлов, это нормально. Итак, давайте возьмем список файлов и передадим его в ffmpeg, чтобы объединить файлы .ts:

ffmpeg -f concat -i mylist.txt -c copy output.avi

И вот у нас есть наш файл .avi, готовый к загрузке на YouTube!

Загрузив файл и разместив его здесь, на YouTube, я заметил, что видео и звук не полностью синхронизированы. Черт. Я считаю, что это проблема, связанная с созданием файла .avi путем объединения файлов .ts. Вероятно, можно было бы исправить это, передав правильные флаги в ffmpeg, но я не в правильном настроении, чтобы исследовать это прямо сейчас. Если есть кто-то, кто читает эту статью и знает, как решить эту проблему, дайте мне знать. Однако я очень горжусь своим саксофонным соло, которое начинается вскоре после 13:32 в видео.

Важное сообщение в этой статье не является явным, как загружать и объединять файлы .ts в файл .avi. Это скорее то, как навыки программирования и взлома могут быть действительно полезны в эту цифровую эпоху. Кстати, поймите, пожалуйста, «взлом» в первоначальном смысле этого слова:

Возиться с чем-то в позитивном смысле, то есть использовать игривую смекалку для достижения цели.

Никогда не знаешь, когда тебе могут понадобиться такие навыки. Если вы потратите время на их изучение, они, несомненно, дадут вам силы!