iPhone - ищет в потоковом аудио - PullRequest
2 голосов
/ 16 марта 2009

Как я могу реализовать поиск (функция временной шкалы) в потоковом аудио на iPhone?

Метод AudioFileStreamSeek принимает смещение в байтах, с которого я хочу начать поиск. Я хочу иметь возможность получить текущую позицию воспроизводимого mp3 и позволить пользователю вернуться (искать) в ту же позицию в более поздний момент времени.

Но я не смог найти какой-либо способ узнать количество уже сыгранных байтов. Я могу узнать количество байтов, которые были переданы. Но не могу узнать, сколько байтов было сыграно. В качестве основы я использую пример потокового аудио Мэтта Галлахера.

Любая помощь очень ценится.

Спасибо.

Может быть, только сможет найти решение. AudioFileStreamSeek документация говорит

После вызова этой функции синтаксический анализатор предполагает, что следующие данные переданы функция AudioFileStreamParseBytes начинается с возвращенного байтового смещения в outAbsoluteByteOffset параметр.

Как мы это делаем? Должны ли мы использовать параметр Http Range? Если мы отправим байтовое смещение в Range, оно будет работать так, как ожидается? И как мне очистить существующие байты в буфере, чтобы избежать одновременного воспроизведения двух потоков?

Любая помощь с благодарностью. Благодарю.

Ответы [ 3 ]

2 голосов
/ 20 марта 2009

AudioFileStreamSeek работает с пакетами, а не с числом байтов. Итак, что вам действительно нужно отслеживать, так это количество пакетов.

В методе MyEnqueueBuffer в коде Мэтта буферы отправляются в AudioQueue для воспроизведения. Захватите заполненные пакеты и увеличьте переменную индекса, прежде чем заполненные пакеты будут сброшены до 0:

myData.absolutePackets = myData.absolutePackets + myData-> packagesFilled;

Моя проблема в том, что я не могу правильно реализовать AudioFileStreamSeek даже с этим значением. Так что, если у вас есть какой-то пример кода поиска работы с кодом Мэтта, пожалуйста, поделитесь.

Спасибо!

1 голос
/ 21 марта 2009

Я действительно не пробовал API AudioFileStream для этого (мы развернули наш собственный), но вот несколько вещей, о которых вы должны позаботиться.

Предполагая, что у вас нет проблем при случайном поиске потока байтов, вы должны отслеживать связь между номером кадра MP3 и абсолютным местоположением потока байтов, как говорит Пол. Я предполагаю, что вы можете сделать это в вашем AudioFileStream_PacketsProc, вызвав AudioFileStreamSeek по пути.

Вот самая сложная часть. Когда вы делаете случайный поиск, вы должны сбросить внутренние состояния AudioFileStream. Потому что он может находиться в некотором промежуточном состоянии, ожидая, что следующие входящие байты завершат текущий кадр. Я не уверен, что вы можете просто кормить нули, чтобы пропустить текущий кадр, и начать все сначала (что вы должны попробовать, так как я не вижу ничего похожего на AudioFileStreamReset в API; однако сама аудио-очередь делает есть функция сброса, что вы можете очистить уже в очереди кадра). В любом случае вы должны позаботиться и о AudioFileStream_PacketsProc, потому что вы собираетесь анализировать часть потока байтов, который вы уже отслеживали.

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

Я должен быстро добавить, что другим способом случайного поиска является просто "кэширование" (сохранение) проанализированных пакетов, если вы не воспроизводите действительно длинный и большой поток. Индекс кадра можно рассчитать из информации заголовка кадра. Для MP3 без VBR количество кадров в секунду является константой (например, 44100/1152 = 38,28125 кадров в секунду для стереофонического MP3 без 44 VBR 44,1 кГц; посмотрите, почему это так, в спецификации MP3).

0 голосов
/ 15 апреля 2009

вы можете использовать AudioQueueStart с mSampletime места, которое вы хотите искать?

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

inDeviceStartTime Время начала аудио-очереди.

Чтобы указать время начала относительно временной шкалы связанного аудиоустройства, используйте поле mSampleTime структуры AudioTimeStamp. Используйте NULL, чтобы указать, что аудио-очередь должна запуститься как можно скорее.

Возвращаемое значение Код результата. См. «Коды результата аудио-очереди».

Обсуждение Если соответствующее аудиоустройство еще не запущено, эта функция запускает его.

...