FFmpeg code to extract audio and video data

Today, we begin to roll up the code. First, we use the FFmpeg API to extract the audio data of an MP4 file. IDE It should be the first time to do C/C...
IDE
Extract audio AAC data
Extract video data

Today, we begin to roll up the code. First, we use the FFmpeg API to extract the audio data of an MP4 file.

IDE

It should be the first time to do C/C + + development on Mac, and choose to use CLion development after tangle. CLion It's the IDE specially used for developing C/C + + under JetBrains. It's used to Android studio and IntelliJ IDEA, so CLion is still easy to use.

After creating a new C project, you need to import the FFmpeg library to run normally. We modify the CMakeLists.txt file of the project.

Extract audio AAC data

In fact, the main thing we need to do is to operate a file, open a file, take out part of its data from it, and then put this data into another file for saving.

Defining parameters
#include <stdio.h> #include <libavutil/log.h> #include <libavformat/avformat.h> //context AVFormatContext *fmt_ctx = NULL; AVFormatContext *ofmt_ctx = NULL; //Support various output file formats, MP4, FLV, 3GP, etc AVOutputFormat *output_fmt = NULL; //Input stream AVStream *in_stream = NULL; //Output stream AVStream *out_stream = NULL; //Store compressed data AVPacket packet; //Stream to copy int audio_stream_index = -1;

1. Open the input file and extract the parameters

//Open the input file, and all the information about the input file will be saved in FMT? CTX err_code = avformat_open_input(&fmt_ctx, src_fileName, NULL, NULL); if (err_code < 0) { av_log(NULL, AV_LOG_ERROR, "cant open file:%s\n", av_err2str(err_code)); return -1; } if(fmt_ctx->nb_streams<2){ //The number of streams is less than 2, which means that the audio and video streams of this file cannot be guaranteed, and the input file has errors av_log(NULL, AV_LOG_ERROR, "Input file error, less than 2 streams\n"); exit(1); } //Get the audio stream in the file in_stream = fmt_ctx->streams[1]; //parameter information AVCodecParameters *in_codecpar = in_stream->codecpar; //Find the best audio stream audio_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); if(audio_stream_index < 0){ av_log(NULL, AV_LOG_DEBUG, "Failed to find the best audio stream, please check the input file!\n"); return AVERROR(EINVAL); }

2. Prepare output file and output stream

// Output context ofmt_ctx = avformat_alloc_context(); //Generate the most appropriate output container based on the target filename output_fmt = av_guess_format(NULL,dst_fileName,NULL); if(!output_fmt){ av_log(NULL, AV_LOG_DEBUG, "Failed to generate output container according to target!\n"); exit(1); } ofmt_ctx->oformat = output_fmt; //New output stream out_stream = avformat_new_stream(ofmt_ctx, NULL); if(!out_stream){ av_log(NULL, AV_LOG_DEBUG, "Failed to create output stream!\n"); exit(1); }

3. Data copy

3.1 parameter information
// Copy the parameter information to the output stream, we just extract the audio stream, not do the audio processing, so here is just copy if((err_code = avcodec_parameters_copy(out_stream->codecpar, in_codecpar)) < 0 ){ av_strerror(err_code, errors, ERROR_STR_SIZE); av_log(NULL, AV_LOG_ERROR,"Copy code parameter failed!, %d(%s)\n", err_code, errors); }
3.2 initialize AVIOContext
//Initialize AVIOContext, which completes the file operation if((err_code = avio_open(&ofmt_ctx->pb, dst_fileName, AVIO_FLAG_WRITE)) < 0) { av_strerror(err_code, errors, 1024); av_log(NULL, AV_LOG_DEBUG, "Could not open file %s, %d(%s)\n", dst_fileName, err_code, errors); exit(1); }
3.3 start copying
//Initialize AVPacket, and the data we read from the file will be temporarily stored in it av_init_packet(&packet); packet.data = NULL; packet.size = 0; // Write header information if (avformat_write_header(ofmt_ctx, NULL) < 0) { av_log(NULL, AV_LOG_DEBUG, "Error occurred when opening output file"); exit(1); } //Every frame of data read out while(av_read_frame(fmt_ctx, &packet) >=0 ){ if(packet.stream_index == audio_stream_index){ //Time base calculation, audio pts and dts are consistent packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); packet.dts = packet.pts; packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base); packet.pos = -1; packet.stream_index = 0; //Write package to output media file av_interleaved_write_frame(ofmt_ctx, &packet); //Reduce reference count and avoid memory leakage av_packet_unref(&packet); } } //Write tail information av_write_trailer(ofmt_ctx); //Finally, don't forget to free up memory avformat_close_input(&fmt_ctx); avio_close(ofmt_ctx->pb);

implement

./MyC /Users/david/Desktop/1080p.mov /Users/david/Desktop/test.aac

Extract video data

The process of extracting video information and saving it in a file, even the code, is basically the same as the audio extracted above.

//Get the audio stream or video stream in the file. All streams are in the streams array in_stream = fmt_ctx->streams[1]; //Find the best video stream video_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); packet.dts = av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

Basically, it's the change of some parameters. If all the processes and codes remain the same, the video data in an audio and video file can be extracted. The format of mp4, H264, etc. is so simple...

3 December 2019, 17:42 | Views: 5637

Add new comment

For adding a comment, please log in
or create account

0 comments