how to extract audio from video in c using ffmpeg library?

1.6k views Asked by At

I'm try to build an app in c that extract audio from video and save it as mp3 file. I wrote the code below but i got an runtime error : "Invalid audio stream. Exactly one MP3 audio stream is required.". I debugged the code and came to point that line no "avformat_write_header( oc, &opt );" is giving this error. I wrote the same code form video extraction and that worked properly without any error. Does anyone know how to solve it? Help me in it. Thanks in advance.

My code is :

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavformat/avio.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
int codec_id = AV_CODEC_ID_MP3;
AVFormatContext *pFormatCtx = NULL;
int             i;

AVDictionary    *opt = NULL;

if(argc < 2) {
        printf("Please provide a movie file\n");
        return -1;
}

av_register_all();

if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) < 0) return -1; 

if(avformat_find_stream_info(pFormatCtx, NULL) < 0) return -1; 

int audioStream=-1;
AVStream *audio;
for(i=0; i<pFormatCtx->nb_streams; i++) {
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
        audio = pFormatCtx->streams[i];
            audioStream=i;
            break;
        }
}

if(audioStream==-1) return -1;

    AVOutputFormat* fmt = av_guess_format("mp3", NULL, NULL);
    fmt->audio_codec = codec_id;
    AVFormatContext* oc;
    oc  = avformat_alloc_context();
    if (oc) oc->oformat = fmt;

    avio_open2(&oc->pb, "test.mp3", AVIO_FLAG_WRITE,NULL,NULL);

    AVCodec *codec;
    codec = avcodec_find_encoder(fmt->audio_codec);

    if (!codec) {
        fprintf(stderr, "Codec not found\n");
        exit(1);
    }

    AVStream *audio_stream;
    audio_stream = avformat_new_stream(oc, NULL);
    avcodec_copy_context( audio_stream->codec, pFormatCtx->streams[audioStream]->codec);
    audio_stream->codec->bit_rate = audio->codec->bit_rate;
    audio_stream->codec->sample_rate = audio->codec->sample_rate;
    audio_stream->codec->channels = audio->codec->channels;


avformat_write_header( oc, &opt );
av_dump_format( pFormatCtx, 0, pFormatCtx->filename, 0 );
av_dump_format( oc, 0, oc->filename, 1 );


AVPacket pkt;
i = 0;
av_init_packet( &pkt );

while ( av_read_frame( pFormatCtx, &pkt ) >= 0 ) {
        if (pkt.stream_index == audioStream ) {     
        if ( pkt.flags & AV_PKT_FLAG_KEY ) {
                continue;
            }
            pkt.stream_index = audio_stream->id;
            pkt.pts = i++;
            pkt.dts = pkt.pts;

            av_interleaved_write_frame( oc, &pkt );
        }
        av_free_packet( &pkt );
        av_init_packet( &pkt );
}
av_read_pause( pFormatCtx );
av_write_trailer( oc );
avio_close( oc->pb );
avformat_free_context( oc );
avformat_network_deinit();
return 0;
}
0

There are 0 answers