python のプログラムを Windowsや Macの実行型ファイルに変えてくれるpyinstaller
我々プログラマは Windows PCを使っていても当然のごとくpython などが実行できるように環境を整えております。しかし、まっとうな人間のほとんどは python のお世話になるようなことは無く人生を過ごすことになります。当然PCにpythonが入っている可能性はありませんし、黒い画面(コマンドプロンプト)から、ライブラリが不足していると指摘されて、「あ、そっか。pip で追加しなきゃ」などと考えることは絶対にありません。
このため、我々プログラマが、他の社員さんのためを思ってpythonでプログラムを書いた場合、pythonがインストールされていないPCでも動作する実行型ファイル(exeファイルなど)を作る必要があるわけです。
そういう時に利用されるのがpyinstaller。正直、私にとっては神ライブラリです。
pyinstaller の使い方と黒い画面表示させないオプション --noconsole
pyinstaller の使い方は基本的にとっても簡単。まず、pyinstaller を pipでインストールします。
その後、pythonでプログラムを書き、動くことを確認します。このpython のプログラムを example.py とすると、exeファイルを作るためには、以下のように書くだけです。
pyinstaller example.py --onefile --noconsole
環境変数への登録をしていない場合は、pyinstaller.exe のインストール先を探し出してフルパスを指定して書かないといけないかもしれません。
C:\Users\USERNAME\.pyenv\pyenv-win\versions\3.8.10\Scripts\pyinstaller.exe example.py --onefile --noconsole
ここで、onefileというのは各種ライブラリをまとめて一つのexeファイルにしてくれ、という意味です。
noconsoleというのは、実行時に黒い画面(コマンドプロンプト)を出さないようにするという意味です。この2つのオプションは通常必須と考えて良いでしょう。
ここまでは、色々な人がQiitaなどに記述している通りです。
noconsole が効かない!?
本論はここからです。
私が今回トラブったケースですが、作成したプログラムの一部に ffmpeg というライブラリを利用していました。
ffmpegをimportしていると、pyintaller で noconsole オプションを指定していても、実行時に黒い画面がポップアップされてきます。ポップアップで表示された黒い画面には終始なにも書かれないのですが、ffmpeg が動作している間だけ、短時間ですが黒い画面が出てきているようで、大変不愉快です。
ユーザさんの気持ちになったら「ウィルスにでも感染したか?」と不安になると思いますので大変無粋ですね。これは何とかしたい。
ffmpeg を使っていても黒い画面を表示させない方法
結論だけ言えば、import ffmpeg として、python のコードとして ffmpeg を実行するのではなく、 subprocess コマンドでダウンロードしてきたffmpeg.exe を直接実行する形にするだけで黒い画面は表示されなくなりました。
例としてffmpegを使ってsource.mp4というmp4ファイルを読み込んでフォーマットを変換して tmp.mp4 というファイルに保存する単純なプログラムでご説明します。
以下はpyinstaller でexe化したものを実行すると黒い画面がちらつく記述方法です。
import ffmpeg
ffmpeg_data = ffmpeg.input('./source.mp4')
ffmpeg_data = ffmpeg.output(ffmpeg_data, "tmp.mp4", r = 30, movflags="faststart", loglevel="quiet" , pix_fmt="yuv420p", vf = "scale=trunc(iw/2)*2:trunc(ih/2)*2",)
ffmpeg.run(ffmpeg_data, quiet=True)
上記のようにffmpeg をPython のライブラリとしてimport するとどうしても黒い画面が出てしまいます。quiet=True などとオプションを付けても無駄です。黒い画面はゴキブリのようにしつこく出てきます。
次に黒い画面が全く表示されない記述方法です。
import subprocess
subprocess.run(r'C:\Users\USERNAME\Desktop\ffmpeg-master-latest-win64-gpl-shared\bin\ffmpeg.exe -i ./source.mp4 -r 30 -movflags "faststart" -pix_fmt "yuv420p" -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" temp.mp4',creationflags=subprocess.CREATE_NO_WINDOW)
あまり美しいとは言えませんが、ffmpeg.exe と引数をコマンドラインとして(ここではフルパスで)記述してsubprocess として直接実行してしまうようにします。すると黒い画面は出てきません。
なお上記の例はffmpeg.exe を公式サイトからダウンロードしてきて、zipファイルをデスクトップに解凍して置いた場合の記述です。
ffmpeg.exe のダウンロード方法はこのページに詳しいのでご覧ください。
今日は短いですが以上です。