[libav-api] Extract Audio from Video File

Francois PEDEBOSCQ Yahoo fpedeboscq at yahoo.fr
Sat Aug 31 09:44:19 CEST 2013


Dear All,

I am trying to extract the audio track of a video file and to save it into a file. 
The audio codec of the video I am testing is AC3 but my code should work with any audio codec. WIth the code below, I get an audio file but it's unreadable.
Please find my code here below:

- (void) extractAudioFromVideoFile:(NSString *)filenameString toFile:(NSString *)outfilenameString
{
    NSLog(@"extractAudioFromVideoFile\n");
    const char *inFileName = [filenameString UTF8String];
    const char *outFileName = [outfilenameString UTF8String];
    av_register_all();
    AVFormatContext* inContainer = NULL;
    if(avformat_open_input(&inContainer, inFileName, NULL, NULL) < 0)
        exit(1);
    if(avformat_find_stream_info(inContainer, NULL) < 0)
        exit(1);
    int videoStreamIndex = -1;
    for (unsigned int i = 0; i < inContainer->nb_streams; ++i)
    {
        if (inContainer->streams[i] && inContainer->streams[i]->codec &&
            inContainer->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
        {
            videoStreamIndex = i;
            break;
        }
    }
    if (videoStreamIndex == -1)
        exit(1);
    AVFormatContext* outContainer = NULL;
    if(avformat_alloc_output_context2(&outContainer, NULL, NULL, outFileName) < 0)
        exit(1);
    AVStream const *const inStream = inContainer->streams[videoStreamIndex];
    AVCodec *const decoder = avcodec_find_decoder(inStream->codec->codec_id);
    if(!decoder)
        exit(1);
    if(avcodec_open2(inStream->codec, decoder, NULL) < 0)
        exit(1);
    AVStream *outStream = avformat_new_stream(outContainer, decoder);
    if(!outStream)
        exit(1);
    outStream->codec->coder_type = inStream->codec->coder_type ;
    outStream->codec->sample_fmt = inStream->codec->sample_fmt ;
    outStream->codec->sample_rate =  inStream->codec->sample_rate ;
    outStream->codec->channels = inStream->codec->channels ;
    outStream->codec->bit_rate = inStream->codec->bit_rate ;
     if(avcodec_open2(outStream->codec, decoder, NULL) < 0)
        exit(1);
    FILE *outfile;
    if(avio_open(&outContainer->pb, outFileName, AVIO_FLAG_WRITE) < 0)
        exit(1);
    AVFrame *decodedFrame = avcodec_alloc_frame();
    avformat_write_header(outContainer, NULL);
    AVPacket decodePacket, copyPacket;
    av_init_packet(&decodePacket);
    decodePacket.data = NULL;
    decodePacket.size = 0;
    int curFrameNum = 0;
    int got_frame, len;
    while(av_read_frame(inContainer, &decodePacket)>=0)
    {
        if (decodePacket.stream_index == videoStreamIndex)
        {
            decodedFrame = avcodec_alloc_frame();
            len = avcodec_decode_audio4(inStream->codec, decodedFrame, &got_frame, &decodePacket);
            if(got_frame)
            {
                av_init_packet(&copyPacket);
                copyPacket.pts = decodePacket.pts;
                copyPacket.dts = decodePacket.dts;
                copyPacket.duration = decodePacket.duration;
                NSLog(@"Duration : %i ,PTS : %lld ,DTS : %lld",copyPacket.duration ,copyPacket.pts, copyPacket.dts);
                int data_size = av_samples_get_buffer_size(NULL, inStream->codec->channels,
                                                           decodedFrame->nb_samples,
                                                           inStream->codec->sample_fmt, 1);
                copyPacket.data = decodedFrame->data[0];
                copyPacket.size = data_size;
                av_interleaved_write_frame(outContainer, &copyPacket);
                av_free_packet(&copyPacket);
                curFrameNum +=  1;
            }
        }
    }
    av_free_packet(&decodePacket);
    av_write_trailer(outContainer);
    avio_close(outContainer->pb);
    avcodec_free_frame(&decodedFrame);
    avformat_free_context(outContainer);
    avformat_close_input(&inContainer);
}

Thanks a lot for your support,
François




More information about the libav-api mailing list