IPython.display.Audio 无法正确处理 `.ogg` 文件类型?
IPython.display.Audio cannot correctly handle `.ogg` file type?
我正在用 Jupyter 做一些音频分析,并尝试用 IPython.display.Audio
播放 .ogg
文件。由于 PyCharm 经常无法打开大 .ipynb
文件,我主要使用网络浏览器在 localhost:8888
.
查看我的笔记本文件
这张图是我用Chrome得到的。如您所见,FailToDisplay.ogg 是从我的作品中提取的,音频播放栏未激活。 File-ACDC_-_Back_In_Black-sample.ogg和song sample.mp3都是从网上下载的。 3个文件的完整性均已验证,即都可以用音频播放器正确播放。
我也用Microsoft Edge和Firefox测试过,结果大体相同。 2 .ogg
个播放栏都处于非活动状态,而 .mp3
个播放栏处于活动状态并且运行良好。所以我想问题不在于网络浏览器。
我用Chrome Developer Tool查看了这3个音频播放器的html源代码,它们都是这样的:
<audio controls="controls">
<source src="data:None;base64,VERYLONGTEXT" type="None">
Your browser does not support the audio element.
</audio>
mp3 的 type
是 audio/mpeg
,ogg 的 type
是 None
。经过一些 google 搜索,我猜这与 MIME 类型有关。所以我用命令 mimetype
:
检查了 3 个音频文件
$ 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
不是很奇怪。然后我找到这个博客 post How to set MIMETYPES on server : Forums : PythonAnywhere 并测试了我的 python MIME 类型设置:
>>> import mimetypes
>>> mimetypes.guess_type("foo.ogg")
(None, None)
现在遇到这种情况不知道下一步该怎么办。这只是 Jupyter 或 IPython 或 system-wide 的错误吗?我在哪里可以更改此行为?
我的Python环境设置是
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
既然没有人提示,我想我得自己动手了...
首先查看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())
这是生成html音频控制块源代码的代码,type
是从self.mimetype
赋值的。 self.mimetype
派生自 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"
很明显,如果 mimetypes.guess_type("filename.ogg")[0]
得到 None
,那么我们就有 type == None
,这会导致一个不活动的音频控制块。
来自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,但在mimetypes
上没有反映,所以我想我只好放弃了。
最后我意识到使用 IPython.display.Audio
之前的猴子补丁可能会起作用,而且确实有效:
解决问题可能不是很完美,但至少是有效的。就这样吧。
我正在用 Jupyter 做一些音频分析,并尝试用 IPython.display.Audio
播放 .ogg
文件。由于 PyCharm 经常无法打开大 .ipynb
文件,我主要使用网络浏览器在 localhost:8888
.
这张图是我用Chrome得到的。如您所见,FailToDisplay.ogg 是从我的作品中提取的,音频播放栏未激活。 File-ACDC_-_Back_In_Black-sample.ogg和song sample.mp3都是从网上下载的。 3个文件的完整性均已验证,即都可以用音频播放器正确播放。
我也用Microsoft Edge和Firefox测试过,结果大体相同。 2 .ogg
个播放栏都处于非活动状态,而 .mp3
个播放栏处于活动状态并且运行良好。所以我想问题不在于网络浏览器。
我用Chrome Developer Tool查看了这3个音频播放器的html源代码,它们都是这样的:
<audio controls="controls">
<source src="data:None;base64,VERYLONGTEXT" type="None">
Your browser does not support the audio element.
</audio>
mp3 的 type
是 audio/mpeg
,ogg 的 type
是 None
。经过一些 google 搜索,我猜这与 MIME 类型有关。所以我用命令 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
不是很奇怪。然后我找到这个博客 post How to set MIMETYPES on server : Forums : PythonAnywhere 并测试了我的 python MIME 类型设置:
>>> import mimetypes
>>> mimetypes.guess_type("foo.ogg")
(None, None)
现在遇到这种情况不知道下一步该怎么办。这只是 Jupyter 或 IPython 或 system-wide 的错误吗?我在哪里可以更改此行为?
我的Python环境设置是
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
既然没有人提示,我想我得自己动手了...
首先查看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())
这是生成html音频控制块源代码的代码,type
是从self.mimetype
赋值的。 self.mimetype
派生自 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"
很明显,如果 mimetypes.guess_type("filename.ogg")[0]
得到 None
,那么我们就有 type == None
,这会导致一个不活动的音频控制块。
来自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,但在mimetypes
上没有反映,所以我想我只好放弃了。
最后我意识到使用 IPython.display.Audio
之前的猴子补丁可能会起作用,而且确实有效:
解决问题可能不是很完美,但至少是有效的。就这样吧。