问题
I was doing some audio analysis stuff with Jupyter and tried to play .ogg
files with IPython.display.Audio
. Since PyCharm often failed to open big .ipynb
files, I mostly used web browser to view my Notebook files at localhost:8888
.
This picture is what I get with Chrome. As you can see, FailToDisplay.ogg is taken from my work, the audio play bar is not activated. File-ACDC_-_Back_In_Black-sample.ogg and song sample.mp3 are all downloaded from Internet. The integrity of 3 files are all validated, i.e., they can all be played correctly with audio players.
I also tested it with Microsoft Edge and Firefox, and the results are mostly the same. 2 .ogg
playbars are all inactive while .mp3
playbar is active and works perfectly. So I guess the problem is not web browser dependent.
I checked the html source code of these 3 audio playbars with Chrome Developer Tool, they are all like:
<audio controls="controls">
<source src="data:None;base64,VERYLONGTEXT" type="None">
Your browser does not support the audio element.
</audio>
The type
for mp3 is audio/mpeg
and type
for ogg is None
. After some google search, I guess this has something to do with MIME type. So I inspected 3 audio files with command mimetype
:
$ mimetype ./*
./AudioDisplayErrorTest.ipynb: text/plain
./FailToDisplay.ogg: audio/x-vorbis+ogg
./File-ACDC_-_Back_In_Black-sample.ogg: video/x-theora+ogg
./song sample.mp3: audio/mpeg
Not very strange. Then I find this blog post How to set MIMETYPES on server : Forums : PythonAnywhere and tested my python MIME type settings:
>>> import mimetypes
>>> mimetypes.guess_type("foo.ogg")
(None, None)
Now I don't know what to do next with this kind of situation. Is this just a bug of Jupyter or IPython or system-wide? Where can I change this behavior?
My Python environment settings are
audioread==2.1.4
ipykernel==4.4.1
ipython==5.1.0
ipython-genutils==0.1.0
ipywidgets==4.1.1
jupyter==1.0.0
jupyter-client==4.3.0
jupyter-console==5.0.0
jupyter-core==4.1.1
librosa==0.4.3
nbconvert==4.2.0
nbformat==4.0.1
notebook==4.2.2
numpy==1.11.1
openpyxl==2.3.2
pydub==0.16.5
回答1:
Since no one gives a hint, I guess I'll have to work alone...
First look into the source code of IPython.display.audio
: ipython/display.py at 48b01aadcbb6a53d2c77fa250c8a4344931c357c · ipython/ipython
def _repr_html_(self):
src = """
<audio controls="controls" {autoplay}>
<source src="{src}" type="{type}" />
Your browser does not support the audio element.
</audio>
"""
return src.format(src=self.src_attr(),type=self.mimetype, autoplay=self.autoplay_attr())
This is the code that generates html source code of audio control block, type
is assigned from self.mimetype
. And self.mimetype
is derived from reload()
:
if self.filename is not None:
self.mimetype = mimetypes.guess_type(self.filename)[0]
elif self.url is not None:
self.mimetype = mimetypes.guess_type(self.url)[0]
else:
self.mimetype = "audio/wav"
It's obvious if mimetypes.guess_type("filename.ogg")[0]
gets None
, then we have type == None
, which results an inactive audio control block.
From 18.7. mimetypes — Map filenames to MIME types — Python 2.7.12 documentation I learned that MIME types can be loaded from file or dynamically added with mimetypes.add_type()
. It also said by default mimetypes
will load from Windows registry. I tried to modify system-wide MIME type settings of .ogg
with one small utility FileTypesMan - Alternative to 'File Types' manager of Windows but it did not reflect on mimetypes
, so I guess I'll have to let it go.
At last I realized that a monkey patch before IPython.display.Audio
was used will possibly work and it really does:
It may not be perfect to solve the problem, but at least it works. So be it for now.
来源:https://stackoverflow.com/questions/39077987/ipython-display-audio-cannot-correctly-handle-ogg-file-type