IPython.display.Audio 无法正确处理“.ogg”文件类型?

Posted

技术标签:

【中文标题】IPython.display.Audio 无法正确处理“.ogg”文件类型?【英文标题】:IPython.display.Audio cannot correctly handle `.ogg` file type? 【发布时间】:2016-12-28 21:55:42 【问题描述】:

我正在使用 Jupyter 进行一些音频分析工作,并尝试使用 IPython.display.Audio 播放 .ogg 文件。由于 PyCharm 经常无法打开大的 .ipynb 文件,我主要使用网络浏览器在 localhost:8888 查看我的 Notebook 文件。

这张图片是我用 Chrome 得到的。如您所见,FailToDisplay.ogg 取自我的工作,音频播放栏未激活。 File-ACDC__-_Back_In_Black-sample.oggsong sample.mp3都是从网上下载的。 3个文件的完整性都经过验证,即它们都可以用音频播放器正确播放。

我还用 Microsoft Edge 和 Firefox 进行了测试,结果基本相同。 2 .ogg 播放栏都处于非活动状态,而 .mp3 播放栏处于活动状态并且运行良好。所以我猜这个问题不依赖于网络浏览器。

我用 Chrome 开发者工具查看了这 3 个音频播放栏的 html 源代码,它们都是这样的:

<audio controls="controls">
                    <source src="data:None;base64,VERYLONGTEXT" type="None">
                    Your browser does not support the audio element.
                </audio>

mp3 的typeaudio/mpeg,ogg 的typeNone。经过一些谷歌搜索,我想这与 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

不是很奇怪。然后我找到这篇博文How to set MIMETYPES on server : Forums : PythonAnywhere 并测试了我的python MIME 类型设置:

>>> import mimetypes
>>> mimetypes.guess_type("foo.ogg")
(None, None)

现在我不知道在这种情况下下一步该怎么做。这只是 Jupyter 或 IPython 或系统范围的错误吗?我在哪里可以改变这种行为?

我的 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

【问题讨论】:

好的,我自己想出来的。 【参考方案1】:

既然没人给提示,我想我得一个人工作了……

先看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 我了解到 MIME 类型可以从文件中加载或使用mimetypes.add_type() 动态添加。它还说默认情况下mimetypes 将从 Windows 注册表加载。我试图用一个小实用程序FileTypesMan - Alternative to 'File Types' manager of Windows 修改.ogg 的系统范围的MIME 类型设置,但它没有反映在mimetypes 上,所以我想我不得不放弃它。

最后我意识到使用IPython.display.Audio 之前的猴子补丁可能会起作用,而且确实有效:

解决问题可能并不完美,但至少它有效。就这样吧。

【讨论】:

以上是关于IPython.display.Audio 无法正确处理“.ogg”文件类型?的主要内容,如果未能解决你的问题,请参考以下文章

Jupyter (IPython) Notebook 单元格中有多个 Audio 对象

在一个 Jupyter Notebook 单元中播放多种声音

librosa音频处理教程

从 Python 在 Linux 上播放 MP3

在动画期间无法正确定位子图层

windows08:远程桌面正忙无法完成执行任务解决方法