HTTP Live Streaming со звуковыми файлами различной длины - PullRequest
9 голосов
/ 26 апреля 2011

Я пытаюсь транслировать аудио на клиенты iOS и Safari, используя протокол Apple HTTP Live Streaming . В отличие от многих распространенных реализаций HTTP Live Streaming, моя цель - использовать короткие аудиоклипы различной длины, в основном в диапазоне 10-30 секунд. В дополнение к потоковой передаче аудио из этих сегментов, я хотел бы получить доступ к метаданным для каждого сегмента, чтобы я мог обновить отображение и / или предоставить пользователю дополнительные параметры для получения дополнительной информации о конкретном сегменте аудио.

В настоящее время я настроил несколько тестовых случаев, которые преобразуют мой исходный звук (MP3) в различные форматы и создают потоковые файлы M3U для тестирования на устройствах iOS, но ни один из моих подходов не работал должным образом (потоковая передача и передача метаданных в клиент). Я использую AVPlayer для загрузки и воспроизведения созданных файлов M3U:

_playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://localhost/sample.m3u8"]]
_player = [[AVPlayer alloc] initWithPlayerItem:_playerItem];
[_playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:NULL];

// ... wait for user input

[_player play];

Подход 1: сырые MP3-файлы

Я взял исходные файлы MP3 с метаданными id3v2 (v2.3.0) и добавил их в список воспроизведения M3U.

#EXTM3U
#EXT-X-TARGETDURATION:23
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:14
http://localhost/trk_01.mp3
#EXTINF:22
http://localhost/trk_02.mp3
#EXTINF:16
http://localhost/trk_03.mp3
#EXT-X-ENDLIST

Результаты: свойство timedMetadata обновляется, как только начинается воспроизведение с правильной информацией ID3 для первой дорожки. Первый трек воспроизводится, но обрывается ближе к концу. Данные ID3 для второй дорожки отображаются, но вторая дорожка не начинает воспроизводиться. Через несколько секунд я получаю сообщение об ошибке на консоли:

2011-04-26 07:04:52.668 TestClient[49756:601b] Prime: Exiting because mConverterError is '!buf' (0x800 req, 0x0 primed)
2011-04-26 07:04:52.668 TestClient[49756:601b] Prime failed ('!buf'); will stop (2048/0 frames)

Подход 2: Используйте медиа-файл Apple для создания отдельных файлов MP3

В этом подходе я использую mediafilesegmenter для создания нового файла MP3 для каждого сегмента. Инструмент сегментации Apple обычно используется для сегментации, но поскольку мои аудиоклипы все короткие и различной длины, это не очень подходит для моего приложения. Я передаю целевую длительность в 999 секунд утилите, чтобы она создавала один выходной файл для каждого входного файла, который я ей предоставляю. Вот команда, которую я использую для создания каждого отдельного трека:

mediafilesegmenter -t 999 -f "$OUTPUT_DIR" "$INPUT_FILE" && cp $OUTPUT_DIR/fileSequence0.mp3 $OUTPUT_FILE

Полученный файл MP3, похоже, содержит некоторые временные метки, поскольку vbindiff показывает мне изменение в заголовке файла, а строка "com.apple.streaming.transportStreamTimestamp" отображается в первых нескольких байтах нового файла. Исследование этой строки приводит к отрывку в черновой спецификации HTTP Live Streaming :

Элементарные аудиопотоки ДОЛЖНЫ сигнализировать метку времени первого образец в файле, добавив ID3 PRIV тег [ID3] с владельцем идентификатор "Com.apple.streaming.transportStreamTimestamp". Двоичные данные ДОЛЖНЫ быть 33-разрядными Программа MPEG-2 Элементарный поток отметка времени, выраженная как big-endian восьмеричное число, с верхним 31 биты установлены в ноль.

Затем я создаю файл M3U, как в подходе 1. (Обратите внимание, что с помощью mediafilesegmenter я также могу передавать информацию ID3 с помощью предварительно созданных файлов тегов ID3 ​​и метафайла, описывающего смещения времени ID3. Я пропускаю это здесь, потому что Я даже не могу заставить эти файлы воспроизводиться правильно.)

Результаты: первая дорожка воспроизводится так же, как в подходе 1. Трек снова обрезается ближе к концу, а вторая дорожка не воспроизводится. Метаданные отсутствуют, но их можно легко добавить с помощью параметра -M mediafilesegmenter.

Подход 3. Использование ffmpeg для создания файлов транспортного потока MPEG

Используя этот последний подход, я передаю исходные MP3-файлы через ffmpeg для создания данных транспортного потока MPEG:

ffmpeg -i "$INPUT_FILE" -f mpegts -acodec copy "$OUTPUT_FILE"

Затем я создаю M3U так же, как в первых двух подходах.

Результаты: этот подход действительно работает; все файлы передаются на клиент без проблем. Однако я не могу передать какие-либо метаданные клиенту. Я попытался передать аргументы типа -metadata title="My Title" в ffmpeg безуспешно.

Ответы [ 2 ]

1 голос
/ 29 апреля 2011

просто предложение .. Вы пробовали этот проект - https://github.com/DigitalDJ/AudioStreamer Я использую это в своем проекте, и это хорошо

обновление 1 -

вы можете перенести информацию метаданных в один файл в другой, используя параметр FFMPEG - "-map_meta_data"

вот пример -

ffmpeg -i /root/Desktop/new_tracks/02-drug-raps.mp3 -ab 24k /root/Desktop/new_tracks/converted/2.mp3 -map_meta_data /root/Desktop/new_tracks/02-drug-raps.mp3:/root/Desktop/new_tracks/converted/2.mp3;
0 голосов
/ 17 апреля 2012

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

Вы должны вводить строку # EXT-X-DISCONTINUITY всякий раз, когда декодеру необходимо выполнить сброс. Если у вас нет одного длинного mp3-файла, который сегментируется, вам нужно будет пометить разрыв перед каждым новым mp3.

...