Skip to content

FFMpeg use as a music parser

Saki edited this page Jan 7, 2015 · 10 revisions

The introduction of FFMpeg is here present in Wikipedia.

This documentation is going to show you how to use FFMpeg to get the property information about a music.

BEFORE YOU READ This document is based on FFMpeg 2.5.2. The API of FFMpeg can be very different on different version. Check your FFMpeg version before you read this document.

Add FFMpeg to your project.

First, add FFMpeg libraries to your projects:

LIBS += -lavformat -lavcodec -lavutil

Include FFMpeg's headers, here we used extern to add FFMpeg header files:

extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
}

Before you used FFMpeg, you should initialize all the muxers, demuxers and protocols of FFMpeg by using av_register_all(). Simply call this function and it will automatically done everything.

Open a file from FFMpeg

First, generate a AVFormatContext pointer to NULL. Use the avformat_open_input function to read the content of a media file to the AVFormatContext.

avformat_open_input(&formatContext,
                    QDir::toNativeSeparators(filePath).toLocal8Bit().data(),
                    NULL,
                    NULL)

If the function return 0, means open failed.

Find the codec of the audio stream

Check if there's any audio stream in the file. Use avformat_find_stream_info() function to check if there's any streams. And in the AVFormatContext, the streams(type AVStream **) record all the information of the media stream.

The AVStream structure records the codec which the current stream used in the codec(type AVCodecContext *) member. And the AVCodecContext structure records the type of the codec via calling codec_type. If the codec_type is AVMEDIA_TYPE_AUDIO, this stream is an audio stream.

The following code shows a simple way to find the first audio stream of a media file. Most audio files contain only one audio stream. So the code should be well worked on these files.

//Check whether we can find the stream info from the context.
if(avformat_find_stream_info(formatContext, NULL)<0)
{
    //We can't find even one stream
    return false;
}
int audioStream=-1;
//Find the audio stream.
for(unsigned int i=0; i<formatContext->nb_streams; i++)
{
    if(formatContext->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
    {
        audioStream=i;
        break;
    }
}

Now you can get the audio stream codec context(formatContext->streams[audioStream]->codec). To decode the stream, we need a decoder. FFMpeg provides various decoder, you can find a decoder via AVCodecID. It's recorded in the AVCodecContext by calling codec_id. Use avcodec_open2 to open the codec context via the audio codec.

//Get the audio codec context.
AVCodecContext *codecContext=formatContext->streams[audioStream]->codec;
//Check is there a codec can we used.
if(codecContext==NULL)
{
    return false;
}
//Find the codec via the codec context.
AVCodec *codec=avcodec_find_decoder(codecContext->codec_id);
//Open the codec context using the codec.
if(avcodec_open2(codecContext, codec, NULL)<0)
{
    return false;
}

Get the properties

  • Duration

You can find the duration in formatContext->duration, but the time is provided in AV_TIME_BASE fractional seconds. To change it to millisecond, use the following code:

formatContext->duration/(AV_TIME_BASE/1000);
  • Sampling Rate

The sampling rate is recorded in AVCodecContext.

codecContext->sample_rate
  • Bit Rate

You should calculate this rate yourself. The meaning of bit rate is how many bits information can be output in one second. So this is very simple:

(double)file_size/duration*8+0.5

Close the file

Close the file after use.

//Close the file.
avformat_close_input(&formatContext);