一半君的总结纸

听话只听一半君

如何才能在Maya里用Phonon – 编译Qt 顺带试验编译PyQt4 for Maya 2014

想在Maya里用Phonon,可是去到maya安装目录下查看,qt-plugins目录下没有phonon_backend文件夹,所以

主要需要准备以下:

当然你必须得有 Microsoft Visual Studio 2010 Service Pack 1

  • 为了得到Phonon插件你必须得装1,2,只有1是强制性要求必须是这个版本,qt编译完成后把phonon-backend拷到qt-plugins目录下即可
    phonon
  • 为了得到高逼格的PyQt4,你还需要2,3,4(其中QScintilla不是必须的),lz用的PyQt和SIP和Maya2014用的都不是严格一致的版本,应该没事吧?(心虚中…)

步骤如下,当然你得在Visual Studio x64 Win64 Command Prompt (2010)里运行他们,lz用了一个console emulator叫做ConEmu的,看最后的推荐…

  1. 编译qt
    maya2014对应的qt是4.8.2,去官网下载解压我不知道用qt自带的zlib和外部的zlib什么区别,我自己compile了zlib先

    cd zlib-1.2.8
    nmake -f win32/Makefile.msc
    

    然后

    cd e:\qt-adsk-4.8.2
    set QTDIR=e:\qt-adsk-4.8.2\bin
    Set DXSDK_DIR="e:\Program Files (x86)\Microsoft DirectX SDK (June 2010)"
    %DXSDK_DIR%\utilities\bin\dx_setenv.cmd
    
    # 当然如果你要那几个数据库插件你就得先有那几个数据库的include和lib文件吧 后来发现默认是用系统的zlib而我没有,所以...
    set INCLUDE=%INCLUDE%;E:\Program Files\PostgreSQL\9.3\include;C:\Program Files\MySQL\MySQL Server 5.6\include;E:\zlib-1.2.8
    set LIB=%LIB%;E:\Program Files\PostgreSQL\9.3\lib;C:\Program Files\MySQL\MySQL Server 5.6\lib;E:\zlib-1.2.8
    
    echo yes | configure -opensource -platform win32-msvc2010 -release -plugin-sql-mysql -plugin-sql-psql -plugin-sql-odbc -mp
    nmake
    
    

    因为上面configure的时候没加-prefix ,用官方的话说,这样出来的将会是一个in-source build, 因此无需nmake install (虽然4.8的安装说明里没写,但是5.0的写了,也许是这样?事实上你如果直接nmake install的话,他会试图拷到自身目录里,当然会失败,其实configure的最后你也看到了,如果你不设prefix,那安装目录就是当前目录)
    qt prefix

    如果你只是想要phonon(上面configure的时候-plugin-sql-mysql -plugin-sql-psql -plugin-sql-odbc都用不着加),此时你把qt-plugins下的phonon-backend目录拷到maya安装目录下的qt-plugins里就完事了(只需要那个dll文件即可),如果想继续乱搞PyQt,可以继续往下操作

  2. 编译sip
    cd sip-4.16.2
    c:\Python27\python.exe configure.py
    nmake
    nmake install
    
  3. 编译pyqt
    cd PyQt-win-gpl-4.11.1
    set QTDIR=e:\qt-adsk-4.8.2
    set PATH=e:\qt-adsk-4.8.2\bin;%PATH%
    echo yes | c:\Python27\python.exe configure.py -w LIBDIR_QT=e:\qt-adsk-4.8.2\lib INCDIR_QT=e:\qt-adsk-4.8.2\include MOC=e:\qt-adsk-4.8.2\bin\moc.exe -w -nodesigner-plugin
    nmake
    nmake install
    
  4. 编译qscintilla
    cd e:\QScintilla-gpl-2.8.3
    cd Qt4Qt5
    set PATH=e:\qt-adsk-4.8.2\bin;%PATH%
    qmake qscintilla.pro
    nmake
    nmake install
    
    # python binding
    cd e:\QScintilla-gpl-2.8.3\Python
    c:\Python27\python.exe configure.py
    nmake
    nmake install
    
    # designer plugin
    cd e:\QScintilla-gpl-2.8.3\designer-Qt4Qt5
    qmake designer.pro
    nmake
    nmake install
    
    

    此外根据官网说明,需要把E:\qt-adsk-4.8.2\lib\qscintilla2.dll 复制到\bin目录下

  5. 如果你只是自己随便用用,现在已经好了就,lz把自己compile出来的qt-plugins放在这里
      • 但是由于上面编译qt的时候没加-prefix,这个in-source build换句话说就是编译出来的东西和源码的文件们是混在一起的,如果你觉得这样不爽,你可以在configure的时候指定个-prefix让他装到另一个目录去。现在qt的工具比如designer是在E:\qt-adsk-4.8.2\bin里面的
      • 如果你想打包编译出来的PyQt发布共享给别人用,你还需要使用Nullsoft scriptable install system,PyQt4源码里自带一个安装脚本,PyQt4-Qt4.nsi,右击选Compile NSIS Script即可,但是这里存在个问题,此script里很多路径是hardcoded的(没办法,他给你这个文件是给脸而已,又不是义务,在此只好手动改下了)

    lz修改过之后的地方如下:

    ...
    
    !define PYQT_PYTHON_MAJOR   "2"
    !define PYQT_PYTHON_MINOR   "7"
    ...
    !define PYQT_QT_VERS        "4.8.2"
    ...
    
    !define QT_SRC_DIR          "E:\qt-adsk-4.8.2"
    !define OPENSSL_SRC_DIR     "C:\OpenSSL-win64"
    !define MYSQL_SRC_DIR       "C:\Program Files\MySQL\MySQL Server 5.6"
    
    ...
        File C:\Python27\pylupdate4.exe
        File C:\Python27\pyrcc4.exe
    ...
        SetOutPath $INSTDIR\Lib\site-packages\PyQt4
        File /r "c:\python27\sip"
    
        SetOutPath $INSTDIR\Lib\site-packages\PyQt4
        File "c:\python27\sip.exe"
    
        SetOutPath $INSTDIR\Lib\site-packages\PyQt4\include
        File "c:\python27\include\sip.h"
    ...
    
    

    此外lz在E:\PyQt-win-gpl-4.11.1下新建了build文件夹,然后把以下文件夹拷了进去(因为.nsi script就是这么写的)
    build_result
    compile完成后,你会得到一个安装包,可以分享给别人了,lz放在这里PyQt4-4.11.1-gpl-Py2.7-Qt4.8.2-x64-maya-2014了,此外lz修改过的.nsi script在这里

ps: 如果某一步configure失败了,而你又改了某些设置,想重新configure的话,可以运行

nmake confclean

推荐使用第三方的console emulator来操作,windows默认的不但复制粘贴麻烦,而且没有tab,开多了以后不好管理,上面的操作中lz用的都是ConEmu


不过lz没这么高逼格,lz只是把Visual Studio x64 Win64 Command Prompt (2010)加了进去,这样开着方便点而已,你只要把原快捷方式里的命令贴进去即可
ConEmu add vs 2010 command prompt
然后你就可以方便的开了
ConEmu add vs 2010 command prompt call

pss: 搞完以后lz在vmware里测试,结果发现现在python最新是2.7.8, lz本机python是2.7.5,看maya 2014的是2.7.3,这应该大概也许没事吧,反正都是2.7 … orz

psss:已测试,发现两个小问题

  • 开designer的时候提示找不到zlib1.dll, 看来需要把他打包加进去
  • 提示找不到msvcr100.dll missing,这是因为需要64Bit: Microsoft Visual C++ 2010 SP1 Redistributable Package (x64),可以去这里下载,看来需要在.nsis script加个提醒或自动下载什么的,抑或直接把他加进去

因此,抄袭.nsi的已有格式,找到Section “Extension modules” SecModules,在下面加一行

...
Section "Extension modules" SecModules
    SectionIn 1 2 RO

    SetOverwrite on

    # We have to take the SIP files from where they should have been installed.
    SetOutPath $INSTDIR\Lib\site-packages
    File "${PYQT_PYTHON_DIR}\Lib\site-packages\sip.pyd"

    SetOutPath $INSTDIR\Lib\site-packages\PyQt4
    File E:\zlib-1.2.8\zlib1.dll
    File .\LICENSE.GPL2
...

对于问题2,lz把需要装的redistribution package加进去了…
lz在.nsi script里添加了

...
!define MSVS_DIR "E:\downloads"
...
Section "Microsoft Visual C++ 2010 SP1 Redistributable Package (x64)" MyApp
    SectionIn 1 2 RO
    SetOutPath "$TEMP"

    ;Check if we have redistributable installed
    Call CheckRedistributableInstalled
    Pop $R0

    ${If} $R0 == "Error"
    File "${MSVS_DIR}\vcredist_x64.exe"
    ExecWait '"$TEMP\vcredist_x64.exe" /passive /norestart'
    ${EndIf}

    ;do other stuff

SectionEnd
...
Function CheckRedistributableInstalled

    Push $R0
    ClearErrors
    ;try to read Version subkey to R0
    ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1D8E6291-B0D5-35EC-8441-6616F567A0F7}" "Version"

    ;was there error or not?
    IfErrors 0 NoErrors
    ;error occured, copy "Error" to R0
    StrCpy $R0 "Error"

    NoErrors:
    Exch $R0
FunctionEnd
...

这下该有了… 不过安装包也大了5MB,上文中的.nsi script 和 编译好的installer链接均已更新
nsis_add_msvs

试用Benjamin Rhoades大神的代码(lz加了个滑条)

from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.phonon import Phonon

import sip
import maya.OpenMayaUI as omu

def maya_main_window():

    ptr = omu.MQtUtil.mainWindow()
    return sip.wrapinstance(long(ptr), QtCore.QObject)

class Window(QtGui.QWidget):
    def __init__(self, parent = maya_main_window()):

        QtGui.QWidget.__init__(self)
        self.media = Phonon.MediaObject(self)
        self.media.stateChanged.connect(self.handleStateChanged)
        self.video = Phonon.VideoWidget(self)
        self.video.setMinimumSize(400, 400)
        self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self)
        Phonon.createPath(self.media, self.audio)
        Phonon.createPath(self.media, self.video)
        self.button = QtGui.QPushButton('Choose File', self)
        self.button.clicked.connect(self.handleButton)
        self.list = QtGui.QListWidget(self)
        self.list.addItems(Phonon.BackendCapabilities.availableMimeTypes())
        self.slider = Phonon.SeekSlider(self.media , self)
        self.play_pause = QtGui.QPushButton('Play / Pause')
        self.play_pause.clicked.connect(self.playClicked)
        slider_layout=QtGui.QHBoxLayout()

        slider_layout.addWidget(self.slider)
        slider_layout.addWidget(self.play_pause)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.video, 1)
        layout.addLayout(slider_layout)
        layout.addWidget(self.button)
        layout.addWidget(self.list)

    def handleButton(self):
        if self.media.state() == Phonon.PlayingState:
            self.media.stop()
        else:
            path = QtGui.QFileDialog.getOpenFileName(self, self.button.text())
            if path:
                self.media.setCurrentSource(Phonon.MediaSource(path))
                self.media.play()

    def playClicked(self):
        if self.media.state() == Phonon.PlayingState:
            self.media.pause()
        else:
            self.media.play()

    def handleStateChanged(self, newstate, oldstate):
        if newstate == Phonon.PlayingState:
            self.button.setText('Stop')
        elif (newstate != Phonon.LoadingState and
              newstate != Phonon.BufferingState):
            self.button.setText('Choose File')
            if newstate == Phonon.ErrorState:
                source = self.media.currentSource().fileName()
                print ('ERROR: could not play:', source.toLocal8Bit().data())
                print ('  %s' % self.media.errorString().toLocal8Bit().data())

if __name__ == '__main__':
    window = Window()
    window.show()

你还需要个 K-Lite Codec Pack lz装了个最大的… K-Lite Mega Codec Pack

然后你就可以在Maya里放“各种”视频了

phonon in action

ps:猜中上面截图中的番号有奖 …

pss: 如果想直接下载本文中编译好的文件:
qt-plugins-qt-4.8.2-phonon-sqldrivers.rar
PyQt4-4.11.1-gpl-Py2.7-Qt4.8.2-x64-maya-2014
更多for其他maya版本的pyqt下载在Maya 2011-2015的PyQt Windows7 Linux Mac OSX 国外大神屌丝编译版大合集

抄袭:
Adventures with PyQt in Maya – Part 1
Shipping Visual Studio redistributable package with NSIS installer
[PyQt] Using Phonon in Maya
This is why Qt (and PyQt) are cool
Windows8.1下编译Maya 2016用的PyQt4 续 – 使用外部Python以及自行编译Qt
使用自动build script编译pyqt for maya 2015 with phonon

Advertisements

13 responses to “如何才能在Maya里用Phonon – 编译Qt 顺带试验编译PyQt4 for Maya 2014

  1. rebecca 六月 23, 2016 @ 12:02 下午

    您好~我想请问一下~~我PyQt安装好了,在Maya中复制您的代码也能正常出现窗口,但是却不能播放影片,点“choose file”也没有反应, K-Lite Codec Pack我也安装好了,但是还是不能正常播放,是为什么呢

    • 一半君 六月 23, 2016 @ 12:17 下午

      你是按文中方法编译出的带phonon插件的pyqt后安装的么?可以去看下plugins目录下有没有phonon的dll. 如果是从riverbank下载的pyqt安装包,里面是没有phonon插件的(所以lz才费这么大力自行编译)

      • rebecca 六月 23, 2016 @ 1:38 下午

        妈呀~我太激动了。。。你竟然回复我了~~
        我不是按照你的方法安装的~我是直接把PyQt安装到Maya2015\Python\文件夹下面,不过确实是从riverbank下载的安装包。
        我在网络上查到把Qt\4.8.2\plugins\里面的phonon_backend文件夹复制到Maya2014\qt-plugins下面
        这个文件夹里面包含有两个分别叫
        “phonon_ds9d4.dll”

        “phonon_ds94.dll”
        是这两个吗?

      • 一半君 六月 23, 2016 @ 1:45 下午

        我觉得是,你试试呗

  2. rebecca 六月 23, 2016 @ 1:47 下午

    我试了。。。仍然木有反应。。。仍然播放不了。。。
    _(:з」∠)_

  3. rebecca 六月 23, 2016 @ 2:22 下午

    哈哈哈哈~~我也不是程序员呀~

  4. 何欣 八月 15, 2016 @ 6:57 下午

    番号是259luxu,楼主记得兑现。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: