Thursday, 1 November 2018

FFMpeg library: how to precisely seek in an audio file

Using the FFMpeg library in my Android app, I try to understand how I can seek in an audio file, at a very precise position.

For example, I want to set the current position in my file to the frame #1234567 (in a file encoded at 44100 Hz), which is equivalent to seek at 27994.717 milliseconds.

To achieve that, here is what I tried:

// 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);

Using a position in microseconds gives me the best result so far.

But for some reason, the positioning is not totally accurate: when I extract the samples from the audio file, it doesn't start exactly at the expected position. There is a slight delay of about 30-40 milliseconds (even if I seek to the position 0, surprisingly...).

Do I use the function the right way, or even the right function?

EDIT

Here is how I can get the position:

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)));

Thanks to that piece of code, I can get the position of the beginning of the current frame (frame = bloc of samples, the size depends on the audio format - 1152 samples for mp3, 128 to 1152 for ogg, ...)

The problem is: the value I get in position is not accurate: it's actually 30 ms late, approximately. For example, when it says 1000000, the actual position is approximately 1030000...

What did I do wrong? Is it a bug in FFMpeg?

Thanks for your help.



from FFMpeg library: how to precisely seek in an audio file

No comments:

Post a Comment