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.
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.
You can try using ffmpeg to do it in C or C++. Here is the normal flow of steps.
Init ffmpeg using av_register_all();
Open input file using avformat_open_input( &informat, sourcefile, 0, 0)).
Find stream info using avformat_find_stream_info(informat, 0)).
Find the audio stream by iterating through streams and comparing codec_type to AVMEDIA_TYPE_AUDIO.
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).
Now for output file guess the outformat using av_guess_format(NULL, (const char*)outfile, NULL).
Allocate context for outformat.
Find output audio encoder using avcodec_find_encoder(outfmt->audio_codec).
Add new stream audio stream avformat_new_stream(outformat, out_aud_codec).
Fill output codec context with desired sample rate, sample fmt, channel etc.
Open output file using avio_open().
Write the output headers using avformat_write_header(outformat, NULL).
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().
Finally write trailer using av_write_trailer.
You can looking into demuxing.c and muxing.c provided in ffmpeg examples.
Start with the transcode_aac official example. We need remarkably few changes:
add a global variable at file scope:
/* The index of audio stream that will be transcoded */
static int audio_stream_idx = -1;
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;
}
On lines 92 and 107, replace streams[0]
with streams[audio_stream_idx]
.
On line 181, replace hard-coded codec ID AV_CODEC_ID_AAC
with
(*output_format_context)->oformat->audio_codec
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);
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.
mp4
files and I get "Could not find an AAC encoder."
from this line. –
Jamshedpur vcpkg
). Your print statement on step 4 didn't compile, so I replaced it with if (!((output_codec = avcodec_find_encoder((*output_format_context)->oformat->audio_codec)))) {fprintf(stderr, "Could not find audio encoder for %s(%d).\n",(*output_format_context)->oformat->long_name,(*output_format_context)->audio_codec_id);
And the output of the program is "Could not find audio encoder for MP3 (MPEG audio layer 3)(0)." –
Jamshedpur © 2022 - 2024 — McMap. All rights reserved.