从不完整的视频文件中提取元数据

Posted

技术标签:

【中文标题】从不完整的视频文件中提取元数据【英文标题】:Extracting metadata from incomplete video files 【发布时间】:2013-07-03 16:28:36 【问题描述】:

谁能告诉我元数据以常见的视频文件格式存储在哪里?如果它位于文件的开头,或者分散在整个文件中。

我正在使用包含大量视频文件的远程对象存储,我想从这些文件中提取元数据,特别是视频时长和视频尺寸,而不是将整个文件内容流式传输到本地计算机。

我希望此元数据将存储在文件的前 X 个字节中,因此我可以只获取从开头开始的字节范围而不是整个文件,并将此部分文件数据传递给 ffprobe

出于测试目的,我创建了一个 22MB MP4 文件,并使用以下命令仅向 ffprobe 提供前 1MB 数据:

head -c1024K '2013-07-04 12.20.07.mp4' | ffprobe -

打印出来:

avprobe version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2007-2013 the Libav developers
  built on Apr  2 2013 17:02:36 with gcc 4.6.3
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1a6b7a0] stream 0, offset 0x10beab: partial file
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'pipe:':
  Metadata:
    major_brand     : isom
    minor_version   : 0
    compatible_brands: isom3gp4
    creation_time   : 1947-07-04 11:20:07
  Duration: 00:00:09.84, start: 0.000000, bitrate: N/A
    Stream #0.0(eng): Video: h264 (High), yuv420p, 1920x1080, 20028 kb/s, PAR 65536:65536 DAR 16:9, 29.99 fps, 30 tbr, 90k tbn, 180k tbc
    Metadata:
      creation_time   : 1947-07-04 11:20:07
    Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 189 kb/s
    Metadata:
      creation_time   : 1947-07-04 11:20:07

所以我看到前 1MB 足以提取 9.84 秒的视频持续时间和 1920x1080 的视频尺寸,即使 ffprobe 打印了关于检测到部分文件的警告。如果我提供的空间小于 1MB,它会完全失败。

这种方法是否适用于其他常见的视频文件格式以可靠地提取元数据,或者任何常见的格式是否会在整个文件中分散元数据?

我了解容器格式的概念,并且可以使用各种编解码器来表示这些容器内的音频/视频数据。虽然我不熟悉细节。所以我猜这个问题可能适用于容器+编解码器的常见组合?提前致谢。

【问题讨论】:

【参考方案1】:

在深入了解 MP4、3GP 和 AVI 的规格后,可以回答我自己的问题...

AVI

元数据位于 AVI 文件的开头,根据AVI file format specification。

视频时长不会逐字存储在 AVI 文件中,而是按 dwMicroSecPerFrame x dwTotalFrames 计算(以微秒为单位)。

从规范的字里行间解读,似乎许多元数据项可以直接从 AVI 文件中的偏移量读取,而根本无需解析。但规范并未明确提及这些偏移量,因此使用此经验法则可能会有风险。

偏移量 32:dwMicroSecPerFrame,偏移量 48:dwTotalFrames,偏移量 64:dwWidth,偏移量 68:dwHeight。

因此对于 AVI,可以仅使用文件的前 X 个字节提取此元数据。

MP4、3GP (3GPP)、3G2 (3GPP2)

所有这些文件格式均基于称为 ISO/IEC 14496-12(MPEG-4 第 12 部分)的ISO base media file format。

这种格式允许将元数据存储在文件中的任何位置,但实际上它会在开头或结尾,因为原始捕获的音频/视频数据会连续保存在中间。 (不过,“碎片化”的 MP4 文件是个例外,are rare。)

只有在开始时存储元数据的文件才能通过progressive download 播放,但这取决于捕获设备或解码器。

AFAICT 这意味着要从这些文件中提取元数据,只需要文件的前 X 个字节,并且根据该信息可以确定可能还需要最后 X 个字节。但不需要中间的字节。

【讨论】:

以上是关于从不完整的视频文件中提取元数据的主要内容,如果未能解决你的问题,请参考以下文章

如何从 MP4 文件中提取元数据轨道

如何从 C# 中的文件中获取元数据? [复制]

如何使用Python来提取视频中的音频

计算flv视频文件长度?使用纯 php

使用 C# 从 ASP.Net MVC 中的视频文件中获取视频元数据的最佳方法是啥?

用手机APP缓存的视频是多个bin文件,请问怎么合并成完整的视频?