К сожалению в сети часто встречаются сайты отдающие аудио в RTMP формате, при
этом через предлагаемый Flash-плеер прослушать такие потоки не всегда удается
(в моем случае в произвольном месте трансляция прерывалась и начиналась с
начала). Для решения данной проблемы можно попытаться сохранить RTMP поток локально.
Рассмотрим процесс локального сохранения записей, на примере архива staroeradio.ru.
Загружаем и собираем пакет rtmpdump (http://rtmpdump.mplayerhq.hu/):
wget http://rtmpdump.mplayerhq.hu/download/rtmpdump-2.3.tgz
tar xzf rtmpdump-2.3.tgz
cd rtmpdump-2.3
make
Пользователи Ubuntu могут поставить rtmpdump из PPA
https://edge.launchpad.net/rtmpdump Кроме того, вместо rtmpdump можно
использовать урезанный форк flvstreamer
(http://savannah.nongnu.org/projects/flvstreamer), который доступен из
стандартных репозиториев.
В итоге будут собраны три программы: rtmpdump для непосредственной загрузки
потока и rtmpsuck и rtmpsrv для определения параметров потока.
Сперва для получения параметров потока была предпринята попытка использовать
Wireshark. Запускаем Wireshark. Выбираем активный сетевой интерфейс и в поле
фильтра указываем "rtmpt". Начинаем проигрывание потока штатным flash-плеером
через браузер. В списке перехваченных пакетов в Wireshark находим "Handshake
part 3". В нижних полях с детализацией раскрываем "Real Time Messagins
Protocol", далее "RTMP Body" и "AMF Objects". Переписываем себе пары
параметров из полей "AMF string", такие как
app = vod
flashVer = LNX 10,1,103,19
swfUrl = http://www.staroeradio.ru/sr-player32.swf
tcUrl = rtmp://server.audiopedia.su/vod
при этом обращаем внимание на появляющийся в нижней части hex-дамп, так как
некоторые строки могут отобразиться в обрезанном виде. Далее, ищем ниже по
списку перехваченный пакет "Ping | Invoke" для определения имени потока.
Находим в hex-дампе упоминание команды play и указанного рядом потока: "mp3:disk2/32".
Для выявления идентификатора конкретного потока можно посмотреть передаваемые
flash-плееру параметры, там будет примерно такая строка "<param
name="FlashVars" value="mp3ID=17139" />. 17139 также фигурирует в пути
изначально проигрываемой страницы "http://www.staroeradio.ru/audio/disk2/32/17139"
В итоге получаем путь: "rtmp://server.audiopedia.su/vod/mp3:disk2/32/17292"
Пытаемся инициировать загрузку:
./rtmpdump -r "rtmp://server.audiopedia.su/vod/" --playpath "mp3:disk2/32/17292" \
--swfUrl "http://www.staroeradio.ru/sr-player32.swf" --tcUrl "rtmp://server.audiopedia.su/vod" \
--pageUrl "http://www.staroeradio.ru/audio/17139" \
--app vod --swfVfy "http://www.staroeradio.ru/sr-player32.swf" -o test.flv
Вываливается ошибка.... Забегая вперед скажу, что она связана с неправильным
определением идентификатора потока, в котором вместо цифрового идентификатора
(17139) нужно было указать имя файла, набранного русскими буквами, которые не
отобразились как следует в Wireshark.
Воспользуемся более правильным методом, основанном на поднятии собственного
RTMP-сервера и перенаправления на него трафика.
Настраиваем редирект RTMP-трафика на локальный обработчик:
sudo iptables -t nat -A OUTPUT -p tcp --dport 1935 -j REDIRECT --to-ports 1935
Смотрим параметры первичного запроса, запускаем:
./rtmpsuck
RTMP Proxy Server v2.3
Streaming on rtmp://0.0.0.0:1935
Теперь инициируем проигрыванием потока в браузере и видим:
Processing connect
app vod
flashVer: LNX 10,1,103,19
swfUrl: http://www.staroeradio.ru/sr-player32.swf
tcUrl: rtmp://server.audiopedia.su/vod
pageUrl: http://www.staroeradio.ru/audio/17292
Для получения более полных данных запускаем RTMP-сервер:
./rtmpsrv
RTMP Server v2.3
Streaming on rtmp://0.0.0.0:1935
Еще раз инициируем проигрыванием потока в браузере и видим:
rtmpdump -r "rtmp://server.audiopedia.su/vod" -a "vod" -f "LNX 10,1,103,19"
-W "http://www.staroeradio.ru/sr-player32.swf" -p "http://www.staroeradio.ru/audio/17292"
-y "mp3:disk2/32 [skip]/disk2/большая коллекция/12.08.10/Н.Иванов - Мой Маяковский" -o "Н.Иванов - Мой Маяковский.flv"
Убираем редирект:
sudo iptables -t nat -D OUTPUT -p tcp --dport 1935 -j REDIRECT --to-ports 1935
Загружаем поток в локальный файл:
rtmpdump -r "rtmp://server.audiopedia.su/vod" -a "vod" -f "LNX 10,1,103,19" \
-W "http://www.staroeradio.ru/sr-player32.swf" -p "http://www.staroeradio.ru/audio/17292" \
-y "mp3:disk2/32 [skip]/disk2/большая коллекция/12.08.10/Н.Иванов - Мой Маяковский" -o test.flv
Все работает !
При массовой загрузки файлов запускать каждый раз редирект на rtmpsrv неудобно.
В процессе запуска flash-плеера со страницы ему передается только цифровой
идентификатор, на основании которого вычисляется полный путь к песне. Недолгие
эксперименты с tcpdump показали, что преобразование ID в имя композиции
производится через обращение к сервису
http://server.audiopedia.su:8888/getmp3parms.php?mp3id=N, где N - известный идентификатор.
Получить полное имя композиции можно примерно так:
curl http://server.audiopedia.su:8888/getmp3parms.php?mp3id=17292
<?xml version="1.0" encoding="UTF-8"?>
<mp3>
<fname>Н.Иванов - Мой Маяковский.mp3</fname>
<fullname>Н.Иванов - Мой Маяковский</fullname>
<dir>disk2/большая коллекция/12.08.10</dir>
<length>396</length><lowqualitydir>disk2/32 [skip]/</lowqualitydir>
</mp3>
Поле <lowqualitydir> определяет дополнение к адресу для потока низкого
качества. Если убрать из пути "disk2/32 [skip]" то поток будет грузиться не 32
kbit, а 128 kbit.
Преобразование загруженного в mp3:
ffmpeg -i 17292.flv -ab 128k -acodec copy 17292.mp3
PS. Если после загрузки в сохраненном потоке наблюдаются спонтанные сбои
позиционирования (повторы и скачки позиционирования) то при запуске rtmpdump
следует использовать флаг "--live".
|