OpenCV输出视频为MP4无法播放的问题

Posted 赵斌韬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV输出视频为MP4无法播放的问题相关的知识,希望对你有一定的参考价值。

今天写了一段代码,打开一段视频,然后再使用CV::VideoWriter保存处理后视频,结果能够成功保存但是打不开。
保存的代码如下:

pVideoPro->SetOutput("output001.mp4");

函数的内容如下所示

/******************************保存视频****************************/
bool VideoProcessor::SetOutput(const string& filename, int codec, double framerate, bool isColor)

	OutputFile = filename;
	if (framerate == 0.0)
		framerate = GetFrameRate();
	char c[4];
	if (codec == 0)
		codec = GetCodec(c);
	return MyWriter.open(OutputFile, codec, framerate, GetFrameSize(), isColor);

为什么我要保存成mp4呢,因为我打开的那个视频格式就是mp4格式的,运行程序以后,成功保存了视频,但是却打不开。
然后我就查看了GetCodec()函数的返回值,这个函数是要获取原视频的编码格式,具体代码如下:

int VideoProcessor::GetCodec(char codec[4])

	union 
		int value;
		char code[4];
	returned;
	returned.value = static_cast<int>(MyCapture.get(CAP_PROP_FOURCC));
	codec[0] = returned.code[0];
	codec[1] = returned.code[1];
	codec[2] = returned.code[2];
	codec[3] = returned.code[3];
	return returned.value;

经过调试我发现返回值为:
说明我这里的原视频为avc1编码格式的,然后我有将open函数中的codec函数修改为了-1,想要获取可选的编码方式,得到的结果如下
可以看到,第二行就是之前我输入的avc1格式,可以看出来opencv是支持avc1这个编码格式的,但不知道为什么保存的视频就是打不开。
当我把保存文件的名称改为.avi格式以后

pVideoPro->SetOutput("output001.avi");

这时候保存的视频居然能够成功播放了,然后我又将open函数中的codec函数修改为了-1,发现.avi后缀可选的编码方式如下
可以看出来,avc1编码格式也可以保存为.avi的格式的,但不知道为什么.mp4就不行.
最后我在官方中文文档中找到了答案,如下

这里写的内容建立在你已经通过OpenCV读取视频输入和相似度测量教程的假设,你知道如何读取视频文件。要创建视频文件,您只需要创建一个cv :: VideoWriter类的实例。您可以通过构造函数中的参数或稍后通过cv :: VideoWriter :: open函数指定其属性。无论哪种方式,参数是相同的:1.在其扩展名中包含容器类型的输出的名称。目前只支持avi。我们从输入文件构造这个,添加到要使用的通道的名称,并使用容器扩展名完成它。

就是说目前VideoWriter 这个类只支持.avi的后缀并不支持别的后缀

OpenCv - 输出视频未播放

【中文标题】OpenCv - 输出视频未播放【英文标题】:OpenCv - output video is not playing 【发布时间】:2021-06-05 21:47:53 【问题描述】:

我想使用 OpenCv 编写视频并在不同的秒内处理每一帧。

我正在使用 cv2.VideoWriter,但输出文件只显示了我的视频的第一帧并且它没有播放。我想在第一帧上添加文本,它做到了,但视频的其余部分没有继续。 从下面的代码可以看出,它为新处理的视频创建了一个新的输出文件。 它确实会创建 mp4 文件,但只显示带有添加文本的第一帧并且它没有播放。

有什么建议为什么会发生这种情况?

这是我的代码,我使用的是 Spyder 和 windows。

fps = int(round(cap.get(5)))
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_file,fourcc,fps,(frame_width,frame_height))

while(True):
# Capture frame-by-frame
    ret, frame = cap.read()
    if ret:    
       if cv2.waitKey(28) & 0xFF == ord('q'):
            break
       if between(cap, 0, 10000):            
           font = cv2.FONT_HERSHEY_COMPLEX_SMALL
           cv2.putText(frame,'hello',org=(10,600),fontFace=font,fontScale=10,color=(255,0,0),thickness=4)

           pass
         
           
# Our operations on the frame come here
           out.write(frame)

# Display the resulting frame
           cv2.imshow('frame',frame)

【问题讨论】:

【参考方案1】:

正是因为您没有提供between 函数,所以我在您的代码中找不到问题。但是您可以尝试以下 sn-p:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
    print("Unable to read camera feed")
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fps = int(round(cap.get(5)))
out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))

while (True):
    ret, frame = cap.read()

    if ret == True:
        cv2.putText(frame, 'hello',
                    org=(10, 300),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=5,
                    color=(255, 0, 0),
                    thickness=4)
        out.write(frame)
        cv2.imshow('frame', frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap.release()
out.release()
cv2.destroyAllWindows()

【讨论】:

def between(cap, lower: int, upper: int): return lower 这里是 between 函数,如果它有帮助的话。我通过 argparse 调用它,这就是我没有定义输入和输出文件的原因。我的初始视频是 2MB,新处理的视频只有 40KB,而且没有播放。我认为WriteVideo 或fourcc 有问题。欢迎任何想法! 是的,它正在工作!非常感谢!!!我现在也必须尝试使用​​ between 函数。也许这会影响输出

以上是关于OpenCV输出视频为MP4无法播放的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++/OpenCV 从 100fps GoPro .mp4 视频创建 25fps 慢动作视频

用opencv播放mp4,能否播放声音?

解决部分mp4视频在ios上无法播放问题

Android MP4Parser 无法播放视频

用Opencv1.0+VC++6.0怎样打开.mp4格式的视频?

Webpack 3 找到 .mp4 文件,但视频无法播放