难点
这个问题有几个难点
- opencv保存视频能否播放
- web端能否显示视频
自己研究这个问题研究了整整三天,现在对以上难点进行一一解答
opencv保存视频能否播放
我找到的比较多的例子都是如下这样的
fps = self.video_stream.get(cv2.CAP_PROP_FPS)
size = (int(self.video_stream.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(self.video_stream.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# fourcc = cv2.VideoWriter_fourcc(*'avc1')
# fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# fourcc = cv2.VideoWriter_fourcc(*'MP4V')
# fourcc = cv2.VideoWriter_fourcc(*'FMP4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
cv_result_file_name = 'test_result.avi'
videoWriter = cv2.VideoWriter(cv_result_file_name,
fourcc, fps,
size)
但是我的macOS的默认播放器是无法播放的,只能使用别的辅助播放器播放
然后保存成为其他fourcc + “*.avi”
/ "*.mp4"
的组合,就会连播放都播放不了,就更不要想在web端显示了
web端能否显示视频
对于avi格式的视频,web端完全无法显示
对于mp4格式的视频,opencv生成的视频,Chrome浏览器也没有办法展示出来
网上冲浪得知的原因是Chrome浏览器只购买了H264编码格式的版权,所以只使用H264格式的MP4才能播放
所以需要转化成H264编码版本的MP4,这里就涉及了一个新的问题
用什么转化?
网上的答案一般是FFmpeg,但是需要安装x264的FFmpeg编译版本
中途又是很多的巨多的坑,详见我的另一篇文章
如何把视频转化成H264编码web端可播放的MP4格式,安装带H264编码的FFmpeg_Unknown encoder ‘h264’
解决方案
保存视频
fps = self.video_stream.get(cv2.CAP_PROP_FPS)
size = (int(self.video_stream.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(self.video_stream.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# fourcc = cv2.VideoWriter_fourcc(*'avc1')
# fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# fourcc = cv2.VideoWriter_fourcc(*'MP4V')
# fourcc = cv2.VideoWriter_fourcc(*'FMP4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
cv_result_file_name = 'test_result.avi'
videoWriter = cv2.VideoWriter(cv_result_file_name,
fourcc, fps,
size)
转化成H264格式
FFmpeg没有H264格式(Unknown encoder ‘h264’):
如何把视频转化成H264编码web端可播放的MP4格式,安装带H264编码的FFmpeg_Unknown encoder ‘h264’
ffmpeg -y -i test_result.avi -vcodec h264 -strict -2 ffmpeg4.2_test.mp4
也可以是如下python封装函数
def avi_to_web_mp4(self, input_file_path):
'''
ffmpeg -i test_result.avi -vcodec h264 test_result.mp4
@param: [in] input_file_path 带avi或mp4的非H264编码的视频的全路径
@return: [output] output_file_path 生成的H264编码视频的全路径
'''
output_file_path = input_file_path[:-3] + 'mp4'
cmd = 'ffmpeg -y -i {} -vcodec h264 {}'.format(input_file_path, output_file_path)
subprocess.call(cmd, shell=True)
return output_file_path
在html中展示
<video name='demo' controls autoplay width='50%' height='40%'>
<source src="path_to_test_result.mp4" type="video/mp4"></source>
</video>
其他尝试
用avc1格式(报错Could not find encoder for codec id 27: Encoder not found)
chrome由于版权问题只支持h264编码的视频
fps = self.video_stream.get(cv2.CAP_PROP_FPS)
size = (int(self.video_stream.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(self.video_stream.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.VideoWriter_fourcc(*'avc1')
# fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# fourcc = cv2.VideoWriter_fourcc(*'MP4V')
# fourcc = cv2.VideoWriter_fourcc(*'FMP4')
# fourcc = cv2.VideoWriter_fourcc(*'XVID')
cv_result_file_name = 'test_result.mp4'
videoWriter = cv2.VideoWriter(cv_result_file_name,
fourcc, fps,
size)
网上说h264和avc1其实是同一种编码格式,但是使用h264传入时,后缀必须为avi,如果为mp4会报错:
OpenCV: FFMPEG: tag 0x34363268/'h264' is not supported with codec id 27 and format 'mp4 /MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'