tom-takeru
@tom-takeru (tom-takeru)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

PyIlnstallerによって単一実行ファイル化したアプリケーションでpydubを利用したい

TkInterを用いてGUIを表示するPythonファイル(myapp.py)をPyInstallerによって単一実行ファイル(myapp.app)にしました。そのmyapp.pyでPydubを利用しようとしましたが、次のように実行したところ、エラーがログに出力されました。

myapp.py内でのPydubのコード

segument = pydub.AudioSegment.from_file(file_path)

エラー

[Error 2]No such file or directory: 'ffprobe': 'ffprobe'

調べると、Pydubではffmpegをsubprocessで利用しているようでした。
ちなみに、myapp.pyをそのまま実行すれば、エラーは出ません

環境

MacOS 10.15.7

Python 3.6
PyInstaller 3.6
FFmpeg 4.3.1
Pydub 0.24.1

試したこと①

myapp.py内でffmpegやffprobeをsubprocessモジュールを用いて実行しているので、PyInstallerでこれらのファイルをmyapp.appにバンドルしています。そのためmyapp.app/Contents/MacOS/内にffmpegやffprobeのバイナリファイルがあります。そこでこれらのファイルパスをPydubに教えることで解消できるのではないかと考えました。

pydubのGitHub
pydubをgitで確認すると、以下のような記述がありました。

pydub/audio_segment.py

class AudioSegment(object):
# --略--
    converter = get_encoder_name()  # either ffmpeg or avconv
# --略--

pydub/utils.py

# --略--
def get_encoder_name():
    """
    Return enconder default application for system, either avconv or ffmpeg
    """
    if which("avconv"):
        return "avconv"
    elif which("ffmpeg"):
        return "ffmpeg"
    else:
        # should raise exception
        warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
        return "ffmpeg"
# --略--

そこでpydub.AudioSegmentクラスのconverterを設定してあげれば良いと考え、先述したコードの前に次のコードを追加しましたが、同じエラーが表示され解決できませんでした。(APP_PATHはmyapp.appのパスの文字列)

pydub.AudioSegment.converter = APP_PATH + '/Contents/MacOS/ffmpeg' # 追加
segument = pydub.AudioSegment.from_file(file_path)

また、pydub/audio_segment.pyのAudioSegmentクラス内に次のようなメソッドがありましたが、使い方がわかりませんでした。

pydub/audio_segment.py

class AudioSegment(object):
#--略--
    # TODO: remove in 1.0 release
    # maintain backwards compatibility for ffmpeg attr (now called converter)
    @classproperty
    def ffmpeg(cls):
        return cls.converter
    @ffmpeg.setter
    def ffmpeg(cls, val):
        cls.converter = val
# --略--

試したこと②

sys.path.appendを用いてpydubにffmpegやffprobeのパスを教えようとしましたが、同じエラーが表示され、解決できませんでした。

sys.path.append(APP_PATH + '/Contents/MacOS/ffmpeg')
sys.path.append(APP_PATH + '/Contents/MacOS/ffprobe')
0

1Answer

試していませんが sys.path.append で解決できそうです。追加するのは実行ファイルのパスではなくそのディレクトリのパスです。 sys.path.append(APP_PATH + '/Contents/MacOS') としてください。

0Like

Comments

Your answer might help someone💌