我有一个来自 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)或其他任何情况。
Google 帮助我找到了 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/