Skip to content

Transcode video file with ffmpeg.

FFmpeg is a powerful open-source library for processing multimedia files like videos and audios. It provides various tools and APIs for tasks like format conversion, resizing, editing, and more. In this article, we will see how to use ffmpeg to transcode a video file from one format to another.

To follow along, you will need:

  • FFmpeg installed on your system
  • A video file to transcode
  • Basic C++ knowledge

At a high level, transcoding a video involves these steps:

  1. Initialize FFmpeg and open the input video file
  2. Get stream information from the input file
  3. Set up the output format context with desired parameters
  4. Read frames from input, decode, process, and encode them
  5. Write the processed frames to the output file

Let’s look at the code to implement these steps.

We begin by including the required FFmpeg headers and registering all the codecs and formats:

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
// other headers
}
av_register_all();

Next, we open the input video file using avformat_open_input() and get the input format context:

AVFormatContext *input_format_ctx = nullptr;
if (avformat_open_input(&input_format_ctx, input_file, nullptr, nullptr) < 0) {
// error handling
}

We find the index of the video stream inside the input file:

int video_stream_idx = -1;
for (int i = 0; i < input_format_ctx->nb_streams; i++) {
if (input_format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_idx = i;
break;
}
}

And get the codec context and parameters for decoding:

AVCodecParameters *codecpar =
input_format_ctx->streams[video_stream_idx]->codecpar;
AVCodec *decoder = avcodec_find_decoder(codecpar->codec_id);
AVCodecContext *codec_ctx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(codec_ctx, codecpar);

We now setup the output format context with the filename, codec and other parameters:

AVFormatContext *output_format_ctx = nullptr;
avformat_alloc_output_context2(&output_format_ctx, nullptr,
nullptr, output_file);
AVStream *out_stream = avformat_new_stream(output_format_ctx,
codec);
avcodec_parameters_copy(out_stream->codecpar, codecpar);

And open the output file for writing:

if (!(output_format_ctx->oformat->flags & AVFMT_NOFILE)) {
if (avio_open(&output_format_ctx->pb, output_file,
AVIO_FLAG_WRITE) < 0) {
// error handling
}
}

Now we can read frames from input, decode them using avcodec_send_packet() and avcodec_receive_frame(), do processing if needed, and finally encode the frames with the output codec and write them to output file.

while (av_read_frame(input_format_ctx, &packet) >= 0) {
avcodec_send_packet(codec_ctx, &packet);
while (avcodec_receive_frame(codec_ctx, frame) == 0) {
// decoding successful
// process frame if needed
avcodec_send_frame(output_codec_ctx, frame);
avcodec_receive_packet(output_codec_ctx, &opacket);
av_interleaved_write_frame(output_format_ctx, &opacket);
}
}

Finally, we free the allocated resources and close the files.

This covers the basic transcoding workflow with FFmpeg. Several additional steps may be needed for robust encoding, like handling subtitles, metadata etc. But this gives an overview of the process.

© 2026 David Li · Home · Blog · RSS ·Classic site · Built with Astro, Starlight and three.js