Прямая трансляция по HTTP с аудиофайлами различной длины

#ios #safari #http-live-streaming

#iOS #safari #http-прямая трансляция

Вопрос:

Я пытаюсь транслировать аудио на клиенты iOS и Safari, используя протокол HTTP Live Streaming от Apple. В отличие от многих распространенных реализаций прямой трансляции по HTTP, моя цель — использовать короткие аудиоклипы, которые по своей природе имеют разную длину, в основном в диапазоне 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


#EXTINF:22

#EXTINF:16

#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. Используйте mediafilesegmenter от Apple для создания отдельных файлов MP3

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

 mediafilesegmenter -t 999 -f "$OUTPUT_DIR" "$INPUT_FILE" amp;amp; 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, выраженную в виде восьмиоктетного числа с большим порядковым номером, причем старшие 31 бит равны нулю.

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

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

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

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

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

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

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

Комментарии:

1. При использовании решения ffmpeg и передаче метаданных в этот поток, действительно ли ваши результирующие TS-файлы содержат текстовые метаданные? Если да, то какой именно формат используется для них?

2. Нет, они, похоже, не содержали никаких метаданных. По крайней мере, ничего такого, что я мог бы извлечь с помощью инструментов id3, exiftool , file или клиента AVPlayer от Apple.

3. Я не уверен, как и могут ли TS-файлы на самом деле содержать метаданные. Спецификации TS, на которые я смотрел, казались расплывчатыми по этому вопросу. Не могли бы вы разместить какие-либо из ваших результатов TS онлайн, чтобы я мог поближе взглянуть на них? В настоящее время я провожу много исследований вокруг TS / MPMoviePlayerController, следовательно, это соответствовало бы моей работе и, возможно, вам тоже могло бы принести пользу.

Ответ №1:

просто предложение.. вы пробовали этот проект — 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;
  

Комментарии:

1. Спасибо за предложение. Я просмотрел AudioStreamer, но не думаю, что он подходит для этого проекта, поскольку я воспроизводю довольно длинные аудиопотоки, состоящие из множества сегментов разной длины. AudioStreamer не поддерживает прямую трансляцию по HTTP. Что касается вашего замечания по ffmpeg, у меня нет проблем с получением метаданных в MP3-файлы или из них; моя проблема в том, что результирующие MP3-файлы не воспроизводятся должным образом при добавлении в плейлист прямой трансляции HTTP. Я смог надежно воспроизводить только файлы MPEG TS (Transport Stream), но у них нет метаданных.

2. Да, я столкнулся с теми же проблемами в одном из своих проектов, и я использовал AutioStreamer для этого проекта.

3. Привет, pix, откуда ты? я также делаю то же самое для потоковой передачи аудио, но на самом деле я не нахожу подходящего документа или исходного кода. пожалуйста, помогите мне выбраться из этого

Ответ №2:

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

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