我有一个来自 GoPro 设备的视频文件,我只是通过这样的 VideoCapture 使用它:

cap = cv2.VideoCapture(path)
        index = 0
        start = time.time()

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
            # do something here
        end = time.time()

这很奇怪,但我可以处理除 GoPro 捕获的任何文件之外的任何文件。 Stream 只是在某个时候关闭,因为 ret 值变为 False 并且 frame 变为 None 。没有异常(exception)或其他任何事情。

谷歌搜索帮助我找到了 this question 。我已经使用 ffmpeg 工具从文件中删除了音频流,然后一切正常。那么为什么会这样呢?请帮忙!

我正在使用 Python 3.6.4 x64、Windows 10(但在 Linux 上相同)和来自 this resource 的 OpenCV 预编译二进制文件。

最佳答案

我也遇到了这个问题,并且能够在不修剪音频的情况下解决它。事实上,我不相信音轨是问题所在。

我在这个问题上看到的所有 ffmpeg 转换命令都有意想不到的副作用,即从视频文件中剥离所有元数据轨道。 GoPro 实际上将大量原始传感器数据直接打包到 MP4 数据中。我认为这更有可能是罪魁祸首,因为它是文件中存在的最不“标准”的数据类型。

我通过使用以下命令剥离音轨来测试这个理论:

ffmpeg -i GH010001.MP4 -map 0 -map -0:a -c copy GH010001_MUTED.MP4

这个新的静音文件表现出相同的问题行为,因此简单地删除音轨是行不通的。

现在如果你不关心元数据轨道,用其他 ffmpeg 调用将它们剥离出来就完全​​没问题了!我实际上想使用那个传感器,所以我不得不找到另一种方法来解决它。

解决方法

下面的代码在概念层面上非常粗糙,但它有效。我们不像通常使用 OpenCV 那样检查空帧,而是简单地计算我们知道应该在那里的帧数,跳过空帧。
auto expectedFrameCount = videoCapture.get(cv::CAP_PROP_FRAME_COUNT);
for(auto frameIndex = 0; frameIndex < expectedFrameCount; frameIndex++) {
  videoCapture >> frame;
  if(frame.empty()) {
    frameIndex--;
    continue;
  }
  // Do useful things with the frame here...
}

忽略文件末尾的通常标志绝对感觉不对,但它起作用了,我能够播放原始视频文件的所有帧,而无需先进行任何 ffmpeg 转换。

关于python - OpenCV VideoCapture 关闭来自 GoPro 的视频,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49060054/

10-12 13:05