import fractions import logging from typing import cast import av import numpy as np from av import VideoCodecContext, VideoFrame # for e in av.codecs_available: # print(e) logging.basicConfig(level=logging.DEBUG) logging.getLogger('libav').setLevel(logging.DEBUG) MAX_FRAME_RATE = 60 def f0(): # input_ = av.open('asd','w') # in_stream = input_.streams.video[0] # libx264 codec: VideoCodecContext = av.CodecContext.create('libx264', "w") codec.width = 640 codec.height = 480 codec.pix_fmt = 'yuv420p' # 常用格式, 大部分解码器都支持 # codec.width = 100 # codec.height = 100 # codec.bit_rate = 100000 # codec.pix_fmt = "yuv420p" # codec.framerate = fractions.Fraction(MAX_FRAME_RATE, 1) # codec.time_base = fractions.Fraction(1, MAX_FRAME_RATE) # codec.options = { # "profile": "baseline", # "level": "31", # "tune": "zerolatency", # } codec.open() pts = 0 while True: f = VideoFrame.from_ndarray(np.zeros((640, 480, 3), dtype=np.uint8)) pts += 1 f.pts = pts r = codec.encode(f) if r.__len__() > 0: print(r[0].__buffer__(0).__len__()) def f1(): import av # 创建一个输出容器 output = av.open('output.mp4', 'w') # 添加一个视频流 stream = output.add_stream('libx264', rate=24) stream.width = 640 stream.height = 480 stream.pix_fmt = 'yuv420p' # 编码循环 for i in range(100): frame = av.VideoFrame(width=640, height=480, format='rgb24') # ... 对帧进行处理 ... for packet in stream.encode(frame): output.mux(packet) # 完成编码 for packet in stream.encode(): output.mux(packet) # 关闭输出容器 output.close() def f2(): import av from av import VideoFrame from fractions import Fraction # 1. 创建输出容器 output_path = 'output.mp4' output = av.open(output_path, 'w') # 2. 创建视频流(使用 libx264 编码器) stream = output.add_stream('libx264', rate=24) # 帧率 # 3. 设置编解码器上下文参数 stream.width = 640 stream.height = 480 stream.pix_fmt = 'yuv420p' # 常用格式, 大部分解码器都支持 stream.codec_context.time_base = Fraction(1, 24) # 4. 手动打开编解码器上下文 (可选, add_stream 已经完成了这一步) stream.codec_context.open() # 5. 编码循环 for i in range(100): # 生成 100 帧 frame = av.VideoFrame(width=640, height=480, format='rgb24') # 生成测试数据 # 在实际应用中,您需要从图像源获取数据 import numpy as np import colorsys cx = int(640 / 100 * i) cy = int(480 / 100 * i) rgb = (np.array(colorsys.hsv_to_rgb(i / 100.0, 1.0, 1.0)) * 255).astype(np.uint8) data = np.zeros((frame.height, frame.width, 3), dtype=np.uint8) data[cy - 10:cy + 10, cx - 10:cx + 10, :] = rgb frame.planes[0].update(data) for packet in stream.encode(frame): output.mux(packet) # 6. 刷新编码器 for packet in stream.encode(): output.mux(packet) # 7. 关闭容器 output.close() def f3(): import av from av import VideoFrame from fractions import Fraction # 1. 创建输出容器 output_path = 'output.mp4' output = av.open(output_path, 'w') # 2. 获取编码器codec codec = av.Codec('libx264', "w") # 3. 手动创建并配置编解码器上下文 ctx = av.CodecContext.create(codec, mode="w") ctx.width = 640 ctx.height = 480 ctx.pix_fmt = 'yuv420p' # 常用格式, 大部分解码器都支持 ctx.time_base = Fraction(1, 24) # 4. 添加视频流 (使用创建好的编解码器上下文). stream = output.add_stream('libx264', rate=24) # 使用编码器名称 stream.codec_context = ctx # 将之前创建好的 ctx 赋值给 stream stream.width = ctx.width # 宽度 stream.height = ctx.height stream.pix_fmt = ctx.pix_fmt # 5. 手动打开编解码器上下文 (在添加到 stream 后会自动打开) ctx.open() # 6. 编码循环 for i in range(100): # 生成 100 帧 frame = av.VideoFrame(width=640, height=480, format='rgb24') # 生成测试数据 # 在实际应用中,您需要从图像源获取数据 import numpy as np import colorsys cx = int(640 / 100 * i) cy = int(480 / 100 * i) rgb = (np.array(colorsys.hsv_to_rgb(i / 100.0, 1.0, 1.0)) * 255).astype(np.uint8) data = np.zeros((frame.height, frame.width, 3), dtype=np.uint8) data[cy - 10:cy + 10, cx - 10:cx + 10, :] = rgb frame.planes[0].update(data) for packet in stream.encode(frame): output.mux(packet) # 7. 刷新编码器 for packet in stream.encode(None): output.mux(packet) # 8. 关闭容器 output.close() print(f"视频已保存到 {output_path}") if __name__ == '__main__': f0()