2014-10-30 37 views
2

我有一個PyQt窗口的小部件改變。我想製作一個視頻。我發現this Answere非常有用,但是在QtGui.QPixmap的save-method中似乎不可能使用子進程PIPE作爲目標。我有這種感覺,我應該使用本地QtProcess進行這種工作,但我不知道如何將PIPE映像打開,並且看不到錯誤,因爲我看不到標準的outpur/error。我想要做的是這樣的:管PyQt窗口小部件圖片到ffmpeg

from PyQt4 import QtGui, QtCore 
import random 

app = QtGui.QApplication([]) 
win = QtGui.QWidget() 
layout = QtGui.QGridLayout() 
win.setLayout(layout) 

#picture frame 
scene = QtGui.QGraphicsScene() 
canvas = QtGui.QGraphicsView(scene) 
layout.addWidget(canvas,0,0) 

# start button 
def run(): 
    # set pen 
    pen = QtGui.QPen(QtCore.Qt.red) 
    size = canvas.size() 

    # start seperate process 
    process = QtCore.QProcess(app) 
    process.start('ffmpeg',['-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r', '24', '-i', '-', '-vcodec', 'mpeg4', '-qscale', '5', 'video.avi']) 
    for i in range(100): 
     x = random.randint(1, size.width()-1) 
     y = random.randint(1, size.height()-1)   
     scene.addLine(x,y,x,y, pen=pen) 
     QtGui.QPixmap.grabWidget(win).save(process, "jpeg") 

but_run = QtGui.QPushButton("Go!") 
but_run.clicked.connect(run) 
layout.addWidget(but_run,1,0) 

win.show() 
app.exec_() 

回答

1

所以我想通了自己。只需添加幾條命令:

process.setProcessChannelMode(process.ForwardedChannels)會將子進程的錯誤和正常輸出重定向到主進程。這可以讓你看到ffmpeg做了什麼或不做什麼。


編輯:這實際上是沒有必要的。
process.setOpenMode(process.WriteOnly)這將打開進程的輸入通道。


我將文件格式更改爲png,因爲它看起來更好。 JPG壓縮不適用於大型單色區域。

process.closeWriteChannel()將關閉輸入通道。這是ffmpeg如何知道沒有更多數據進入。

最後,請致電process.terminate()關閉該過程。

這裏是全功能的代碼:

from PyQt4 import QtGui, QtCore 
import random 

app = QtGui.QApplication([]) 
win = QtGui.QWidget() 
layout = QtGui.QGridLayout() 
win.setLayout(layout) 

#picture frame 
scene = QtGui.QGraphicsScene() 
canvas = QtGui.QGraphicsView(scene) 
layout.addWidget(canvas,0,0) 

# start button 
def run(): 
    # set pen 
    pen = QtGui.QPen(QtCore.Qt.red) 
    size = canvas.size() 

    # start seperate process 
    process = QtCore.QProcess(app) 
    process.setProcessChannelMode(process.ForwardedChannels) 
    #process.setOpenMode(process.WriteOnly) 
    process.start('ffmpeg',['-y', '-vcodec', 'png', '-i', '-', '-vcodec', 'mpeg4', '-qscale', '5', '-r', '24', 'video.avi',"-loglevel", "debug"]) 
    for i in range(100): 
     x = random.randint(1, size.width()-1) 
     y = random.randint(1, size.height()-1)  
     scene.addLine(x,y,x,y, pen=pen) 
     QtGui.QPixmap.grabWidget(win).save(process, "png") 
    process.closeWriteChannel() 
    process.terminate() 
but_run = QtGui.QPushButton("Go!") 
but_run.clicked.connect(run) 
layout.addWidget(but_run,1,0) 

win.show() 
app.exec_()