Using Bit Stream Filters
Created by: hunterjm
I am trying to convert an MP4 H264 stream to Annex-B for use in a MPEGTS output container. I am using the MP4 generated video file located in the docs under numpy
for my reproduction example. I am getting an error saying that the stream is invalid, and needs to be in Annex B using -bsf:v h264_mp4toannexb
Error
H.264 bitstream malformed, no startcode found, use the video bitstream filter 'h264_mp4toannexb' to fix it ('-bsf:v h264_mp4toannexb' option with ffmpeg)
Reproduction code:
import io
import numpy as np
import av
duration = 4
fps = 24
total_frames = duration * fps
mp4 = io.BytesIO()
mp4.name = 'test.mp4'
container = av.open(mp4, mode='w')
stream = container.add_stream('libx264', rate=fps)
stream.width = 480
stream.height = 320
stream.pix_fmt = 'yuv420p'
for frame_i in range(total_frames):
img = np.empty((480, 320, 3))
img[:, :, 0] = 0.5 + 0.5 * np.sin(2 * np.pi * (0 / 3 + frame_i / total_frames))
img[:, :, 1] = 0.5 + 0.5 * np.sin(2 * np.pi * (1 / 3 + frame_i / total_frames))
img[:, :, 2] = 0.5 + 0.5 * np.sin(2 * np.pi * (2 / 3 + frame_i / total_frames))
img = np.round(255 * img).astype(np.uint8)
img = np.clip(img, 0, 255)
frame = av.VideoFrame.from_ndarray(img, format='rgb24')
for packet in stream.encode(frame):
container.mux(packet)
# Flush stream
for packet in stream.encode():
container.mux(packet)
# Close the file
container.close()
# Convert to mpegts
input_ = av.open(mp4, 'r')
input_stream = input_.streams.video[0]
output_file = io.BytesIO()
output_file.name = 'test.ts'
output = av.open(output_file, 'w', format='mpegts')
output_stream = output.add_stream('h264', input_stream.rate)
for packet in input_.demux(input_stream):
# We need to skip the "flushing" packets that `demux` generates.
if packet.dts is None:
continue
# We need to assign the packet to the new stream.
packet.stream = output_stream
output.mux(packet)
output.close()