解析多组视频帧的原始二进制文件

Parse raw binary file for multiple sets of video frames

我正在尝试解析 Python 中具有已知 headers 和长度的原始二进制文件。

数据是 6 通道多路复用视频。

文件按照以下规则分隔帧:

图像数据的开头

E0 01 00 00 D2 59 80 C1 27 3F EC BB 31 7B 3F EC 

BB 31 7B 0F 9B 90 5D A8 81 AA 5F A9 C1 D2 4B B9

9D 0A 8D 1B 8F 89 44 FF 4E 86 92 AD 00 90 5B A8

图像数据结束

67 49 0B B5 BC 82 38 AE 5E 46 49 86 6A FF 24 97 

69 8C 6F 17 6D 67 B5 11 C7 E5 FB E3 3F 65 1F 22 

5C F3 7C D0 7C 49 2F CD 26 37 4D 40 FF FF FF FF

源文件有好几GB。将每个通道解析为单独文件的最佳方法是什么?另外,如何一次批量处理多个文件,并根据输入的名称保存文件?

解析多 GB 二进制文件的微小块可能不是 Python 会很快的事情,因为它需要大量的函数调用和对象创建,这意味着大量的 RAM 和CPU 开销。如果您需要更高的性能或对内存管理的控制,最好使用低级语言(C、C++、Go、Rust)。

但是,您可以使用 struct 模块在 Python 中执行此类操作,如下所示:

header = struct.Struct('>BBBH')
data = b'\xE0\x01\x00\x00\xD2\x59\x80...'  # read this from input file
view = memoryview(data)
offset = 0
while offset < len(data):
    channel, _, _, length = header.unpack(view[offset:offset + header.size])
    write_output(channel, view[header.size:header.size + length])
    offset += length

注意事项:

  • 判断长度是大端还是小端(格式字符串中的< vs >
  • 使用 memoryview 是一种避免一些额外的对象复制和创建的方法——希望它能提高效率
  • 您需要让输出文件保持打开状态——我只是将其隐藏在上面的 write_output() 后面
  • 如果输入是多 GB,您可能希望以 1MB 或更合理的大小为单位读取输入文件,而不是一次全部读取
  • 注意字节与字符串(Python 2.x 与 3.x 的不同处理方式)
  • 如果您需要了解有关打开、读取和写入文件的更多信息,请随时post提出更具体的问题

就一次批处理多个文件而言,最好的选择是 multiprocessing 模块。确实需要一段时间才能让你的头脑清醒过来,但之后使用起来就非常简单了。