2014-10-11 171 views
0

打我使用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,但這也不起作用。

總的來說我想要做到的是拍攝錄像input.mp4,修改每個幀,因爲我在內存中加載它,然後寫一個框架,以一個新的文件output.mp4。到目前爲止,ffmpeg看起來是最好的工具,因爲我無法讓OpenCV工作。

因此,如果任何人有辦法讓water.mp4輸出文件能夠在Windows Media Player中運行,而無需額外的命令行代碼運行或更好的方式來完成我的整體任務,我將非常感激那。

回答

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時得到了什麼錯誤,但是將其添加到參數對我來說工作正常:

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

這工作很好!我使用了從另一個人使用ffmpeg發現的代碼。環顧四周後,我ffmpeg的文檔中看到指定-b選項可能是設置數據速率,所以我就不用在命令行(沒有工作)重做的方式。我也嘗試過使用你提到的變體,'-b:v','64k'在我的commandWriter中沒有用。 爲了記錄在案,我叫我的變量commandWriter因爲我有一個commandReader也是我使用相同的代碼使用ffmpeg的過程。 – kloudab 2014-10-12 01:57:59

+0

非常好!據我所知,''-b:v 64k''選項有效。或者,具體來說,使用該開關製作的視頻顯示的比特率爲22088;根據ffprobe',沒有18783的比特率。我不知道這些比特率是否正確。我在OSX 10.9.4上運行ffmpeg 2.2.3(FWIW)。 – 2014-10-12 08:55:21