Re-encode Audio and Video Streams

This topic describes how to use the Transcoder class to re-encode audio and video streams.

The code snippets in this article are from the re_encode AVBlocks sample.

Why Re-encode?

For performance reasons AVBlocks avoids re-encoding when possible, for example when you scale a video clip, the audio will be copied to the output unchanged. Another example is when you want to resample the audio part without changing the video.

However there are some cases when you will want to force re-encoding of audio or video streams, for example, to fix errors introduced by a prior encoding.

To re-encode audio and video streams, configure the Transcoder outputs to be exactly the same as the inputs, and set the Param.ReEncode parameter on the output audio and the output video pins to Use.On, like this:

pin = MediaPin()
pin.params[Param.ReEncode] = Use.On

Complete Python code

def re_encode(input_file: str, output_file: str, force_audio: bool, force_video: bool) -> bool:
    """Re-encode a media file."""
    # Delete output file if it exists
    delete_file(output_file)

    # Create output directory if it doesn't exist
    output_dir = os.path.dirname(output_file)
    if output_dir and not os.path.exists(output_dir):
        os.makedirs(output_dir)

    transcoder = Transcoder()

    # In order to use the production release for testing (without a valid license),
    # the transcoder demo mode must be enabled.
    transcoder.allow_demo_mode = True

    # Get input format using MediaInfo
    media_info = MediaInfo()
    media_info.inputs[0].file = input_file

    if not media_info.open():
        print_error("Open MediaInfo", media_info.error)
        return False

    # Add Inputs
    input_socket = MediaSocket.from_media_info(media_info)
    transcoder.inputs.add(input_socket)

    media_info.close()

    # Add Outputs
    # Create output socket
    output_socket = MediaSocket()
    in_socket = transcoder.inputs[0]

    output_socket.stream_type = in_socket.stream_type
    output_socket.file = output_file

    # Add pins with ReEncode parameter set to Use.On
    for in_pin in in_socket.pins:
        si = in_pin.stream_info.clone()
        pin = MediaPin()
        pin.stream_info = si.clone()

        if si.media_type == MediaType.Video and force_video:
            pin.params[Param.ReEncode] = Use.On

        if si.media_type == MediaType.Audio and force_audio:
            pin.params[Param.ReEncode] = Use.On

        output_socket.pins.add(pin)

    transcoder.outputs.add(output_socket)

    # Open transcoder
    result = transcoder.open()
    print_error("Open Transcoder", transcoder.error)
    if not result:
        return False

    # Run transcoder
    result = transcoder.run()
    print_error("Run Transcoder", transcoder.error)
    if not result:
        return False

    transcoder.close()

    return True

How to Run

See the Python sample for details. The samples are installed as command-line tools when you install the package from the repository root with uv pip install --editable . (see Installation).

Command Line

re-encode [--audio] [--video] --input <mp4_file.mp4> --output <mp4_file.mp4> 

Examples

List options:

re-encode --help
Usage: re-encode [OPTIONS]

  Re-encode a media file with optional forced re-encoding of audio and/or
  video.

Options:
  -i, --input PATH   input file
  -o, --output PATH  output file
  -a, --audio        Force audio re-encoding.
  -v, --video        Force video re-encoding.
  --help             Show this message and exit.

Re-encode the ./assets/mov/big_buck_bunny_trailer.mp4 file. Only the video stream will be re-encoded, the audio stream will be copied as is:

# Linux and macOS
mkdir -p ./output/re_encode

re-encode \
    --video \
    --input ./assets/mov/big_buck_bunny_trailer.mp4 \
    --output ./output/re_encode/big_buck_bunny_trailer.mp4
# Windows
New-Item -ItemType Directory -Force -Path ./output/re_encode

re-encode `
    --video `
    --input ./assets/mov/big_buck_bunny_trailer.mp4 `
    --output ./output/re_encode/big_buck_bunny_trailer.mp4