Skip to content

How to perform transcoding efficiently #534

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions