Python + playsound の動作環境を整備して、macからmp3ファイルの音を鳴らしてみた

mac + Pythonな環境で、mp3ファイルの音を鳴らしたいことがありました。

調べてみたところ、いくつかパッケージがあるようでした。

 
今回の場合は単に鳴らせればよかったので、一番手軽に扱えそうな playsound を使うことにしました。
TaylorSMarks/playsound: Pure Python, cross platform, single function module with no dependencies for playing sounds.

 
ただ、Githubリポジトリを見たところ、最新バージョン 1.3.0 のリリースが3年くらい前でした。

そこで試してみたところ、最近のPythonバージョンでは動作しないと分かったので、メモを残します。

 
目次

 

環境

  • mac
  • playsound 1.3.0
  • Python 3.10.13
    • Python 3.11系ではインストールできず
  • 追加で必要なパッケージ

 

用意したPythonスクリプト

playsoundのREADMEを参考に、Pythonスクリプトを書きました。

また、Pythonスクリプトと同じ階層に、 mysound.mp3 というmp3ファイルを置きました。

from playsound import playsound


def main():
  playsound('mysound.mp3')

  print('終了します')


if __name__ == "__main__":
  main()

 

動作するPythonバージョンの確認

上記スクリプトが動くかどうか、新しいバージョンから試していきます。

 

Python 3.12系でインストールできない

Python 3.12系へインストールしようとしたところ、エラーになりました。

% python --version
Python 3.12.1

% pip install playsound
Collecting playsound
  Using cached playsound-1.3.0.tar.gz (7.7 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [28 lines of output]
      Traceback (most recent call last):
        File "/path/to/project/env/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/path/to/project/env/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/path/to/project/env/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
          return hook(config_settings)
                 ^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/9j/rhvj56hj4zl6kbkc0zxswj400000gn/T/pip-build-env-qmcer5n9/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=['wheel'])
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/9j/rhvj56hj4zl6kbkc0zxswj400000gn/T/pip-build-env-qmcer5n9/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 295, in _get_build_requires
          self.run_setup()
        File "/private/var/folders/9j/rhvj56hj4zl6kbkc0zxswj400000gn/T/pip-build-env-qmcer5n9/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 480, in run_setup
          super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script)
        File "/private/var/folders/9j/rhvj56hj4zl6kbkc0zxswj400000gn/T/pip-build-env-qmcer5n9/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 311, in run_setup
          exec(code, locals())
        File "<string>", line 6, in <module>
        File "/path/to/.anyenv/envs/pyenv/versions/3.12.1/lib/python3.12/inspect.py", line 1282, in getsource
          lines, lnum = getsourcelines(object)
                        ^^^^^^^^^^^^^^^^^^^^^^
        File "/path/to/.anyenv/envs/pyenv/versions/3.12.1/lib/python3.12/inspect.py", line 1264, in getsourcelines
          lines, lnum = findsource(object)
                        ^^^^^^^^^^^^^^^^^^
        File "/path/to/.anyenv/envs/pyenv/versions/3.12.1/lib/python3.12/inspect.py", line 1093, in findsource
          raise OSError('could not get source code')
      OSError: could not get source code
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

 

Python 3.11系でもインストールできない

続いて、Python 3.11系に切り替えてインストールしようとしましたが、同じエラーになりました。

% python --version
Python 3.11.7

% pip install playsound
Collecting playsound
  Using cached playsound-1.3.0.tar.gz (7.7 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [28 lines of output]
      Traceback (most recent call last):
        File "/path/to/project/env/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/path/to/project/env/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
        File "/path/to/.anyenv/envs/pyenv/versions/3.11.7/lib/python3.11/inspect.py", line 1081, in findsource
          raise OSError('could not get source code')
      OSError: could not get source code
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

 

Python 3.10系ではインストールできたが、PyObjC が必要

続いて、Python3.10系で試してみたところ、インストールはできました。

% python --version
Python 3.10.13

% pip install playsound
Collecting playsound
  Using cached playsound-1.3.0.tar.gz (7.7 kB)
  Preparing metadata (setup.py) ... done
Installing collected packages: playsound
  DEPRECATION: playsound is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for playsound ... done
Successfully installed playsound-1.3.0

 
ただ、Pythonスクリプトを動かしてみたところ、エラーになりました。

% python main.py
playsound is relying on a python 2 subprocess. Please use `pip3 install PyObjC` if you want playsound to run more efficiently.
Traceback (most recent call last):
  File "/path/to/playsound_pyobj/main.py", line 9, in <module>
    main()
  File "/path/to/playsound_pyobj/main.py", line 5, in main
    playsound('clock_in.mp3')
  File "/path/to/playsound_pyobj/env/lib/python3.10/site-packages/playsound.py", line 244, in <lambda>
    playsound = lambda sound, block = True: _playsoundAnotherPython('/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python', sound, block, macOS = True)
  File "/path/to/playsound_pyobj/env/lib/python3.10/site-packages/playsound.py", line 229, in _playsoundAnotherPython
    t.join()
  File "/path/to/playsound_pyobj/env/lib/python3.10/site-packages/playsound.py", line 218, in join
    raise self.exc
  File "/path/to/playsound_pyobj/env/lib/python3.10/site-packages/playsound.py", line 211, in run
    self.ret = self._target(*self._args, **self._kwargs)
  File "/path/to/playsound_pyobj/env/lib/python3.10/site-packages/playsound.py", line 226, in <lambda>
    t = PropogatingThread(target = lambda: check_call([otherPython, playsoundPath, _handlePathOSX(sound) if macOS else sound]))
  File "/path/to/.anyenv/envs/pyenv/versions/3.10.13/lib/python3.10/subprocess.py", line 364, in check_call
    retcode = call(*popenargs, **kwargs)
  File "/path/to/.anyenv/envs/pyenv/versions/3.10.13/lib/python3.10/subprocess.py", line 345, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/path/to/.anyenv/envs/pyenv/versions/3.10.13/lib/python3.10/subprocess.py", line 971, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/path/to/.anyenv/envs/pyenv/versions/3.10.13/lib/python3.10/subprocess.py", line 1863, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)

 
エラーメッセージの中で、気になった内容は

_playsoundAnotherPython('/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python', sound, block, macOS = True)

playsound is relying on a python 2 subprocess. Please use pip3 install PyObjC if you want playsound to run more efficiently.

でした。

また、Githubのissueにも似たような記載がありました。
https://github.com/TaylorSMarks/playsound/issues/132#issuecomment-1820177142

 
そこで、エラーメッセージに従い、 PyObjC をインストールしてみました。
https://github.com/ronaldoussoren/pyobjc

すると、PyObjCに関するパッケージが大量にインストールされましたが、エラーにはなりませんでした。

% pip install -U PyObjC 
Collecting PyObjC
  Using cached pyobjc-10.1-py3-none-any.whl (4.0 kB)
...
Installing collected packages: pyobjc-core,
...
pyobjc-framework-libxpc-10.1

 
再度、Pythonスクリプトを実行すると、macでmp3の音声が再生できました。