【问题标题】:How to write mp4 video file with H264 codec?如何使用 H264 编解码器编写 mp4 视频文件?
【发布时间】:2017-10-11 22:32:32
【问题描述】:

在 OSX 上,我可以从我的网络摄像头录制并使用以下简单脚本编写视频文件:

import cv2
camera = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object to save the video
fourcc = cv2.VideoWriter_fourcc(*'XVID')
video_writer = cv2.VideoWriter('output.avi', fourcc, 25.0, (640, 480))

while True:
    try:
        (grabbed, frame) = camera.read()  # grab the current frame
        frame = cv2.resize(frame, (640, 480))  # resize the frame
        video_writer.write(frame)  # Write the video to the file system

    except KeyboardInterrupt:
        camera.release()
        break

生成的 avi 文件非常大。我想要一个较小的文件,最好是 mp4。所以我将文件名更改为output.mp4,将fourcc编解码器更改为H264。这写了一个有效的视频文件,但给了我以下错误:

$ python write_video_file.py 
OpenCV: FFMPEG: tag 0x34363248/'H264' is not supported with codec id 28 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x00000021/'!???'

因为我认为我在 ffmpeg 中缺少 H264 编解码器,所以我决定卸载 ffmpeg 和 opencv 并重新安装它们以支持 H264。为此,我使用了以下命令:

# First ffmpeg
brew install ffmpeg --with-fdk-aac --with-libvidstab --with-openh264 \
      --with-openjpeg  --with-openssl --with-tools --with-webp --with-x265 --with-zeromq
# then opencv3
brew tap homebrew/science
brew install opencv3 --with-contrib --with-ffmpeg --with-tbb

之后我再次运行脚本,使用以下组合:

  • output.mp4H264
  • output.mp4X264

不幸的是,我仍然收到 OpenCV 警告/错误。该文件是可读的,但我收到这些错误仍然让我很恼火。有谁知道如何让 OpenCV 使用 H264 编解码器编写 mp4 视频文件?

欢迎所有提示!

【问题讨论】:

  • 您尝试重启了吗?
  • @StavrosAvramidis - 不,重新启动没有帮助
  • 确保你有 ffdshow(x32 和 x64)
  • @StavrosAvramidis - ffdshow 不是用于解码/显示文件,而不是编码/写入文件吗?
  • 是的,但你永远不知道

标签: python opencv video ffmpeg codec


【解决方案1】:

我花了很长时间试图在 ma​​cOS 上查找视频编解码器列表,并找出哪些编解码器适用于哪些容器,然后 QuickTime 是否可以实际读取生成的文件.

我可以将我的发现总结如下:

.mov container and fourcc('m','p','4','v') work and QuickTime can read it
.mov container and fourcc('a','v','c','1') work and QuickTime can read it
.avi container and fourcc('F','M','P','4') works but QuickTime cannot read it without conversion

如您所愿,我确实设法在 mp4 容器中编写了 h264 视频,只是没有使用 OpenCV 的 VideoWriter 模块。相反,我将代码(我的恰好是 C++)更改为仅输出原始 bgr24 格式数据——这就是 OpenCV 喜欢存储像素的方式:

所以存储在名为FrameMat 中的一帧视频的输出变为:

cout.write(reinterpret_cast<const char *>(Frame.data),width*height*3);

然后将程序的输出通过管道传输到ffmpeg,如下所示:

./yourProgram | ffmpeg -y -f rawvideo -pixel_format bgr24 -video_size 1024x768 -i - -c:v h264 -pix_fmt yuv420p video.mp4

是的,我知道我做了一些假设:

  • 数据为 CV8_UC3,
  • 尺寸在 OpenCVffmpeg 中匹配,并且
  • OpenCV 数据中没有填充或疯狂的步伐,

但基本技术是有效的,您可以根据其他尺寸和情况进行调整。

【讨论】:

    猜你喜欢
    • 2011-11-07
    • 2019-01-17
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    相关资源
    最近更新 更多