Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract audio to mp3 from mp4 using C++ (not executing ffmpeg with args)

How can I programmatically convert (extract the audio channel) from the mp4 video file format?
I just can't find anything on the web, for using C++.

Passing command line args to LAME or MPLAYER or FFMPEG is not an option.

like image 895
user63898 Avatar asked Apr 21 '13 13:04

user63898


People also ask

Can FFmpeg convert mp4 to mp3?

FFmpeg allows you to convert any media file from one format to another. We have a simple bash script that can be used to convert mp4/mkv/WebM media files to mp3 on Linux. The script can convert mp4, mkv and WebM video formats to mp3 audio format in few seconds.

How do I convert video to audio by FFmpeg?

The -i option in the above command is simple: it is the path to the input file. The second option -f mp3 tells ffmpeg that the ouput is in mp3 format. The third option i.e -ab 192000 tells ffmpeg that we want the output to be encoded at 192Kbps and -vn tells ffmpeg that we dont want video.

Can FFmpeg convert video to audio?

FFmpeg Installation FFmpeg is an open-source audio and video converter that supports most industry-standard codecs and can convert from one file format to another quickly and easily. It also lets you capture video and audio from a live source and process it.


2 Answers

You can try using ffmpeg to do it in C or C++. Here is the normal flow of steps.

  1. Init ffmpeg using av_register_all();

  2. Open input file using avformat_open_input( &informat, sourcefile, 0, 0)).

  3. Find stream info using avformat_find_stream_info(informat, 0)).

  4. Find the audio stream by iterating through streams and comparing codec_type to AVMEDIA_TYPE_AUDIO.

  5. Once you have input audio stream you can find audio decoder and open the decoder. Use avcodec_find_decoder(in_aud_strm->codec->codec_id) and avcodec_open2(in_aud_codec_ctx, in_aud_codec, NULL).

  6. Now for output file guess the outformat using av_guess_format(NULL, (const char*)outfile, NULL).

  7. Allocate context for outformat.

  8. Find output audio encoder using avcodec_find_encoder(outfmt->audio_codec).

  9. Add new stream audio stream avformat_new_stream(outformat, out_aud_codec).

  10. Fill output codec context with desired sample rate, sample fmt, channel etc.

  11. Open output file using avio_open().

  12. Write the output headers using avformat_write_header(outformat, NULL).

  13. Now in while loop start reading packet, decode only audio packet encode them and write them in opened output file. You can use av_read_frame(informat, &pkt) , avcodec_decode_audio4(in_aud_codec_ctx, pframeT, &got_vid_pkt, &pkt), avcodec_encode_audio2() and av_write_frame().

  14. Finally write trailer using av_write_trailer.

You can looking into demuxing.c and muxing.c provided in ffmpeg examples.

like image 99
praks411 Avatar answered Oct 07 '22 23:10

praks411


Start with the transcode_aac official example. We need remarkably few changes:

  1. add a global variable at file scope:

    /* The index of audio stream that will be transcoded */
    static int audio_stream_idx = -1;
    
  2. in open_input_file(), replace lines 83-88 with

    for (audio_stream_idx = 0; audio_stream_idx < (*input_format_context)->nb_streams; audio_stream_idx++) {
    if ((*input_format_context)->streams[audio_stream_idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
        break;
    }
    
    if (audio_stream_idx >= (*input_format_context)->nb_streams) {
        fprintf(stderr, "Could not find an audio stream\n");
        avformat_close_input(input_format_context);
        return AVERROR_EXIT;
    }
    
  3. On lines 92 and 107, replace streams[0] with streams[audio_stream_idx].

  4. On line 181, replace hard-coded codec ID AV_CODEC_ID_AAC with

    (*output_format_context)->oformat->audio_codec
    
  5. On line 182, replace the error message:

    fprintf(stderr, "Could not find audio encoder for %s(%d).\n", (*output_format_context)->oformat->long_name, (*output_format_context)->oformat->audio_codec);
    
  6. In decode_audio_frame() we skip non-audio frames: on line 389, write

    if (error != AVERROR_EOF && input_packet.stream_index != audio_stream_idx) goto cleanup;
    

PS Note that this solution does not handle optimally the case when the audio stream does not require transcoding. Most mp4 files will have AAC or AC3 audio tracks, so make sure you build your ffmpeg with the relevant decoders and with an MP3 encoder (e.g. shine).

PPS here is the file, adapted to Adnroid.

like image 30
Alex Cohn Avatar answered Oct 08 '22 01:10

Alex Cohn