Skip to content

How to perform transcoding efficiently #534

@ArtanisCV

Description

@ArtanisCV

Currently, pyav returns frames according to dts. However, when we encode a video, we need to provide frames according to pts. Thus, I have to perform sorting between decoding & encoding like this (otherwise I will get an incorrect output video when there are B-frames in the input):

input_container = av.open('input.mp4')
video_stream = input_container.streams.video[0]

output_container = av.open('output.mp4', mode='w')
stream = output_container.add_stream('libx264', rate=video_stream.average_rate)
stream.width = video_stream.width
stream.height = video_stream.height
stream.pix_fmt = 'yuv420p'

# decode
frames = []
for frame in input_container.decode(video=0):
    frames.append(frame)

# perform sorting
frames = sorted(frames, key=lambda f: f.pts)

# encode
for frame in frames:
    # let libav decide the correct pts and time base (in case of changing fps)
    frame.pts = None
    frame.time_base = None
    packet = stream.encode(frame)
    output_container.mux(packet)

output_container.close()

Is there a more efficient way?

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions