I am following a tutorial on PyDub. The very first exercise is to play a WAV file. Here is my adapted code. I’m not too worried about the warning at this point, as I am trying to resolve the [Errno 13]
resulting from the final command play(wav_file)
:
>>> import os
>>> os.chdir('C:/cygwin64/home/User.Name/Some.Path')
>>> from pydub import AudioSegment
>>> from pydub.playback import play
>>> wav_file = AudioSegment.from_file(file = "SomeFile.wav", format = "wav")
C:UsersUser.Nameanaconda3envspy39libsite-packagespydubutils.py:170: RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work
warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
>>> play(wav_file)
C:UsersUser.Nameanaconda3envspy39libsite-packagespydubutils.py:184: RuntimeWarning: Couldn't find ffplay or avplay - defaulting to ffplay, but may not work
warn("Couldn't find ffplay or avplay - defaulting to ffplay, but may not work", RuntimeWarning)
Traceback (most recent call last):
Cell In[5], line 1
play(wav_file)
File ~anaconda3envspy39libsite-packagespydubplayback.py:71 in play
_play_with_ffplay(audio_segment)
File ~anaconda3envspy39libsite-packagespydubplayback.py:15 in _play_with_ffplay
seg.export(f.name, "wav")
File ~anaconda3envspy39libsite-packagespydubaudio_segment.py:867 in export
out_f, _ = _fd_or_path_or_tempfile(out_f, 'wb+')
File ~anaconda3envspy39libsite-packagespydubutils.py:60 in _fd_or_path_or_tempfile
fd = open(fd, mode=mode)
PermissionError: [Errno 13] Permission denied: 'C:\Users\User.Name\AppData\Local\Temp\tmpryjpscsv.wav'
Much googling reveals the likely error to be that on Windows, you cannot repeatedly open a file without closing it. The vary last frame in the stack trace is line 60 of utils.py
:
/c/Users/User.Name/anaconda3/envs/py39/lib/site-packages/pydub/utils.py
-----------------------------------------------------------------------
53 def _fd_or_path_or_tempfile(fd, mode='w+b', tempfile=True):
54 close_fd = False
55 if fd is None and tempfile:
56 fd = TemporaryFile(mode=mode)
57 close_fd = True
58
59 if isinstance(fd, basestring):
60 fd = open(fd, mode=mode)
61 close_fd = True
62
63 try:
64 if isinstance(fd, os.PathLike):
65 fd = open(fd, mode=mode)
66 close_fd = True
67 except AttributeError:
68 # module os has no attribute PathLike, so we're on python < 3.6.
69 # The protocol we're trying to support doesn't exist, so just pass.
70 pass
71
72 return fd, close_fd
I noticed that whenever fd
is assigned an open file, the close_fd
flag is set to True
. I can use this to avoid multiple reopenings. Lines 60 and 65 represent potential sites of [Errno 13]
. Would it be robust to AND the immediately preceding if
conditions as follows?
59 if not close_fd and isinstance(fd, basestring):
64 if not close_fd and isinstance(fd, os.PathLike):
The 2nd of the two conditional openings refers to os.PathLike
. While I can find webpages on that, I can’t find a simple explanation. So I’m not sure what the enclosing try
block is meant to do. I hope that understanding it is not necessary if the logic at the microscopic level is robust enough for general situations, i.e., if not close_fd and ...
.