#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.