Библиотека FFMpeg: как точно искать в аудиофайле - PullRequest
0 голосов
/ 26 октября 2018

Используя библиотеку FFMpeg в моем приложении для Android, я пытаюсь понять, как искать в аудиофайле с очень точной позицией.

Например, я хочу установить текущую позицию в своем файлек кадру # 1234567 (в файле, закодированном на частоте 44100 Гц), который эквивалентен поиску на 27994,717 миллисекундах.

Чтобы добиться этого, вот что я попробовал:

// this:
av_seek_frame(formatContext, -1, 27994717, 0);

// or this:
av_seek_frame(formatContext, -1, 27994717, AVSEEK_FLAG_ANY);

// or even this:
avformat_seek_file(formatContext, -1, 27994617, 27994717, 27994817, 0);

Использованиепозиция в микросекундах пока дает мне лучший результат.

Но по какой-то причине позиционирование не совсем точное: когда я извлекаю семплы из аудиофайла, он не начинается точно в ожидаемой позиции,Небольшая задержка составляет около 30-40 миллисекунд (даже если я стремлюсь к позиции 0, что удивительно ...).

Правильно ли я использую функцию или даже нужную функцию?

РЕДАКТИРОВАТЬ

Вот как я могу получить позицию:

AVPacket packet;
AVStream *stream = NULL;
AVFormatContext *formatContext = NULL;
AVCodec *dec = NULL;

// initialization:
avformat_open_input(&formatContext, filename, NULL, NULL);
avformat_find_stream_info(formatContext, NULL);
int audio_stream_index = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
stream = formatContext->streams[audio_stream_index];

...

// later, when I extract samples, here is how I get my position, in microseconds:
av_read_frame(formatContext, &packet);
long position = (long) (1000000 * (packet.pts * ((float) stream->time_base.num / stream->time_base.den)));

Благодаря этому коду я могу получить позицию началатекущего кадра (frame = блок сэмплов, размер зависит от аудио формата - 1152 сэмпла для mp3, от 128 до 1152 для ogg, ...)

Проблема: значение, которое я получаю в position, не является точным: на самом деле оно на 30 мс позже, примерно.Например, когда написано 1000000, фактическая позиция составляет примерно 1030000 ...

Что я сделал не так?Это ошибка в FFMpeg?

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 27 октября 2018

Зависит от кодека. Например, aac имеет разрешение 1024 выборки на кадр, независимо от частоты дискретизации, у него также есть выборочные выборки, которые могут быть отброшены. MP3 имеет 576 или 1152 семплов на кадр в зависимости от слоя.

Если вам нужно совершенство, используйте несжатый формат, такой как wav или riff.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...