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

时间:2014-10-11 06:32:30

标签: python video ffmpeg

我使用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()

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

ffmpeg -i fire.mp4 -b:v 250k -bufsize 250k water.mp4

根据我的理解,它需要fire.mp4并简单地输出一个具有修改比特率的新视频。当我在Windows Media Player中打开它时,此新输出有效。

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

总的来说,我想要完成的是采用视频输入.mp4,在我将其加载到内存中时修改每个帧,然后将该帧写入新文件output.mp4。到目前为止,ffmpeg看起来是最好的工具,因为我无法让OpenCV工作。

因此,如果有人有办法让water.mp4输出文件能够在Windows Media Player中运行而无需运行额外的命令行代码或更好的方式来完成我的整体任务,我将非常感激

1 个答案:

答案 0 :(得分:0)

如果您的问题是如何获取播放的视频,正如您的标题所示,那么我发现删除一些冗余参数工作正常。下面的代码(个人偏好和可读性的其他变化):

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',