我有一个来自 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/