For decoding raw packets without streams, some codecs need a few extradata (like Huffman tables). In this commit, I provided two functions, one for extracting these data and the other for setting them when we want to decode without a stream.
An example usage:
import av
container = av.open('somevideo.mp4')
# Find index of the video stream
video_stream_index = 0
for index, stream in enumerate(container.streams):
if isinstance(stream, av.video.stream.VideoStream):
video_stream_index = index
break
buffered_packets = []
count = 0
now = False
for packet in container.demux(streams=video_stream_index):
count += 1
# We only buffer some packets (here from 100 to 500)
if count > 100:
new_packet = av.packet.Packet(input=packet.to_bytes())
# First packet need to be a keyframe
if packet.is_keyframe or now:
buffered_packets.append(new_packet)
now = True
if count > 500:
break
codec_name = container.streams[video_stream_index].codec_context.name
codec_origin = container.streams[video_stream_index].codec_context
codec_new = av.codec.CodecContext.create(codec_name, 'r')
extradata = codec_origin.extradata
if not extradata is None:
codec_new.extradata = extradata
for packet in buffered_packets:
try:
for frame in codec_new.decode(packet):
frame.to_image().save('frame-%04d.jpg' % frame.index)
except av.AVError as e:
print(e)