Popen.write - 在关闭文件上操作 | 使用FFmpeg将图像转换为视频
我正在尝试用我的摄像头拍的图片创建一个视频文件(使用SimpleCV),这些图片会转换成PIL格式,然后用tostring()方法转成原始格式。
我使用Python的subprocess和Popen来通过FFmpeg创建视频。
我可以把一张图片传给FFmpeg,然后把它做成视频,但当我尝试处理多张图片时,就出现了错误:
ValueError: I/O operation on closed file
这是我的代码。
import subprocess as sp
from SimpleCV import *
from Image import Image
FFMPEG_BIN = "ffmpeg.exe"
img = Camera().getImage().toRGB()
command = [FFMPEG_BIN, '-y', # (optional) overwrite output file if it exists
'-f', 'rawvideo', '-vcodec', 'rawvideo', '-s', '%sx%s'%(img.width,img.height), # size of one frame
'-pix_fmt', 'rgb24', '-r', '24', # frames per second
'-i', '-', # The imput comes from a pipe
'-an', # Tells FFMPEG not to expect any audio
'-vcodec', 'libx264rgb',
'my_output_videofile.mp4']
pipe = sp.Popen(command, stdin=sp.PIPE)#, stderr=sp.PIPE)
for n in xrange(10):
img = Camera().getImage().toRGB().getPIL().tostring()
pipe.stdin.write(img)
pipe.terminate()
这很奇怪,因为pipe.terminate()是在代码的最后,应该会立刻关闭文件。
编辑:去掉了stderr。
ffmpeg version N-63208-gbe1fbc0 Copyright (c) 2000-2014 the FFmpeg developers
built on May 17 2014 01:30:26 with gcc 4.8.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib
--enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray
--enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug
--enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus
--enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame
--enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx
--enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid
--enable-decklink --enable-zlib
libavutil 52. 83.100 / 52. 83.100
libavcodec 55. 62.100 / 55. 62.100
libavformat 55. 38.100 / 55. 38.100
libavdevice 55. 13.101 / 55. 13.101
libavfilter 4. 5.100 / 4. 5.100
libswscale 2. 6.100 / 2. 6.100
libswresample 0. 19.100 / 0. 19.100
libpostproc 52. 3.100 / 52. 3.100
Input #0, rawvideo, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: 44236 kb/s
Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 320x240, 44236 kb/s, 24 tbr, 24 tbn, 24 tbc
No pixel format specified, rgb24 for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264rgb @ 0000000000359de0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264rgb @ 0000000000359de0] profile High 4:4:4 Predictive, level 1.3, 4:4:4 8-bit
[libx264rgb @ 0000000000359de0] 264 - core 142 r2431 ac76440 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 -
http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1
psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1
chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0
constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250
keyint_min=24 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69
qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'my_output_videofile.mp4':
Metadata:
encoder : Lavf55.38.100
Stream #0:0: Video: h264 (libx264rgb) ([33][0][0][0] / 0x0021), rgb24, 320x240, q=-1--1, 12288 tbn, 24 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo -> libx264rgb)
frame= 7 fps=0.0 q=0.0 size= 0kB time=00:00:00.00 bitrate=N/A
2 个回答
0
可能是因为 ffmpeg 这个程序在你试图添加所有图片之前就已经停止运行了。如果你去掉 , stderr=sp.PIPE
这个参数,你就能看到 ffmpeg 打印出的错误信息。
1
我觉得自己真傻……
SimpleCV有一个非常简单好用的功能,正好满足我的需求。
如果有人感兴趣的话。
http://simplecv.org/docs/SimpleCV.html#i/SimpleCV.Stream.VideoStream