Python 使用ffmpeg创建的视频无法在视频播放器中播放

Python 使用ffmpeg创建的视频无法在视频播放器中播放,python,video,ffmpeg,Python,Video,Ffmpeg,我正在使用Python创建一个使用ffmpeg的视频。下面的代码是我正在使用的 import subprocess as sp import Image FFMPEG_BIN = "ffmpeg" commandWriter = [ FFMPEG_BIN, '-y', '-f', 'image2pipe', '-vcodec','mjpeg', '-s', '480x360', #

我正在使用Python创建一个使用ffmpeg的视频。下面的代码是我正在使用的

import subprocess as sp
import Image
FFMPEG_BIN = "ffmpeg"

commandWriter = [ FFMPEG_BIN,
              '-y',
              '-f', 'image2pipe',
              '-vcodec','mjpeg',
              '-s', '480x360', # size of one frame
              '-pix_fmt', 'rgb24',
              '-r', '29', # frames per second
              '-i', '-',
              '-an', # Tells FFMPEG not to expect any audio
              '-vcodec', 'mpeg4',
              '-qscale', '5',
              '-r', '29',
              '-b', '250',
              './fire.mp4' ]

pipeWriter = sp.Popen(commandWriter, stdin=sp.PIPE)

fps, duration = 24, 10
for i in range(fps*duration):
   im = Image.new("RGB",(480,360),(i%250,1,1))
   im.save(pipeWriter.stdin, "JPEG")
pipeWriter.stdin.close()
pipeWriter.wait()

pipeWriter.terminate()
运行上述代码后,我得到了数据速率为214kbps的输出视频。此视频无法在Windows Media Player中播放。起初我不知道如何播放视频,所以我把它和我下载的另一个视频进行了比较。我注意到唯一真正的区别在于比特率/数据率。我从命令行运行了这个命令

ffmpeg -i fire.mp4 -b:v 250k -bufsize 250k water.mp4
据我所知,它需要fire.mp4并以修改后的比特率输出新视频。当我在Windows Media Player中打开此新输出时,它将正常工作

我要问的问题是,如何直接从Python实现这一点?我已经尝试将a-b选项添加到commandWriter,如图所示,但这不起作用。我还在pipeWriter中添加了一个bufsize=10**8,但这也不起作用

总的来说,我试图完成的是获取一个video input.mp4,在内存中加载时修改每个帧,然后将该帧写入一个新的文件output.mp4。到目前为止,ffmpeg看起来是最好的工具,因为我根本无法让OpenCV工作


因此,如果有人能够在Windows Media Player中运行water.mp4输出文件,而无需运行额外的命令行代码或以更好的方式完成我的总体任务,我将不胜感激。

如果您的问题是如何获得播放的视频,如标题所示,然后我发现删除一些冗余参数效果很好。代码如下:为了个人喜好和可读性,此处的其他更改:

import subprocess
from PIL import Image

FFMPEG_BIN = "ffmpeg"    
movie_duration_seconds = 2
movie_fps = 24

ffmpeg_command = [ FFMPEG_BIN,
              '-y',
              '-f', 'image2pipe',
              '-vcodec','mjpeg',
              '-s', '480x360', # size of one frame
              '-i', 'pipe:0', # take input from stdin
              '-an', # Tells FFMPEG not to expect any audio
              '-r', str(movie_fps),
              #'-pix_fmt', 'yuvj420p',  # works fine without this
              #'-vcodec', 'mpeg4',  # not sure why this is needed
              #'-qscale', '5',  # works fine without this
              #'-b', '250',  # not sure why this is needed
              './fire.mp4' ]

ffmpeg_process = subprocess.Popen(ffmpeg_command, stdin=subprocess.PIPE)

for i in range(movie_fps * movie_duration_seconds):
   # each image is a shade of red calculated as a function of time
   im = Image.new("RGB",(480,360),(i%255,1,1))
   im.save(ffmpeg_process.stdin, "JPEG")
   ffmpeg_process.stdin.flush()
ffmpeg_process.stdin.close()
#ffmpeg_process.wait()
#ffmpeg_process.terminate()
ffmpeg_process.communicate()  # not sure if is better than wait but
                              # terminate seems not required in any case.
然而,我认为问题实际上是关于指定比特率。我不确定修改python时会出现什么错误,但将其添加到args对我来说效果很好:

          '-b:v', '64k',

这真是太棒了!我使用了从另一个使用ffmpeg的人那里找到的代码。环顾四周后,我在ffmpeg文档中看到,指定a-b选项可能是设置数据速率的一种方法,这样我就不必从命令行重新执行它,因为命令行不起作用。我还试着在我的commandWriter中使用你提到的变体,'-b:v',64k',但它不起作用。作为记录,我将我的变量命名为commandWriter,因为我还有一个commandReader,我在使用ffmpeg过程的相同代码中使用它。太棒了!据我所知,-b:v64k选项是有效的。或者,具体地说,使用该开关制作的视频显示的比特率为22088;根据ffprobe的数据,那些没有的比特率为18783。我不知道这些比特率是否正确。我正在OSX 10.9.4 FWIW上运行ffmpeg 2.2.3版。