1

I'd like to play audio on a remote Jupyter Notebook (like in Google Colab or a Binder-hosted Jupyterlab) but I can't figure out how. What I would like to get working is something like this:

from pydub import AudioSegment
from pydub.playback import play

start = 1000
end = 3000
audio = AudioSegment.from_file("someaudio.flac")
audio_piece = audio[start:end] 
play(audio_piece)

With a playback package like simpleaudio installed, everything works fine on my local machine. But when I try to run this code in Google Colab, for example, I get this error message:

SimpleaudioError: Error opening PCM device. -- CODE: -2 -- MSG: No such file or directory

I tried several other audio packages but I always ran into some trouble. The only thing that works is IPython.display -> Audio. But I can't use this for my project because I don't want a player displayed (and because it doesn't seem to have the option to play segments of an audio file).

Does anyone know a solution for this?

ai4ki
  • 11
  • 2

1 Answers1

0

For MyBinder-served sessions, you have to connect the audio playing ability to IPython abilities imported into the notebook or link the playing of audio to ipywidgets running in the notebook.

Example of playing a wav file in a MyBinder-served notebook

Go to here and press 'launch Binder'.
When the session spins up, paste this into a cell and run that cell:

# PLAY A WAV. BASED ON
# https://ipython.org/ipython-doc/stable/api/generated/IPython.display.html#IPython.display.Audio
from IPython.display import Audio, display
Audio("http://www.nch.com.au/acm/8k16bitpcm.wav")  # From URL
# see https://ipython.org/ipython-doc/stable/api/generated/IPython.display.html#IPython.display.Audio
# for other options such as a file you upload to the remote MyBinder-served session

That will show a controller you can click 'play' to play the file found at the URL as the wav file.

See the source linked in the comments for more information, such as how you could play your own wav file.

To demo this in JupyterLab:
If you are starting fresh, click here to launch directly into JupyterLab. When that sessions spins up, open a new notebook and paste in the code above.

If you are already in a session provided by MyBinder in the classic notebook, click the 'Jupyter' logo in the upper left side above the notebook. The page will refresh and the JupyterLab interface will load and you can open a notebook there and paste in the above code.

The environment specified for those sessions isn't overly complex as you can see here.

Example of playing a tone in a MyBinder-served notebook

Similar to everything above; however, use this as the code block you paste into a cell:

# Generate a sound. BASED ON
# https://ipython.org/ipython-doc/stable/api/generated/IPython.display.html#IPython.display.Audio
import numpy as np
from IPython.display import Audio, display
framerate = 44100
t = np.linspace(0,5,framerate*5)
data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t)
Audio(data,rate=framerate)

Example if an interactive control via ipywidgets of audio-generation in a MyBinder-served notebook.

Click here to launch a session with the JupyterLab interface back by an environment with the necessary modules installed, and then run the following in a cell:

!curl -OL https://raw.githubusercontent.com/mlamoureux/PIMS_YRC/master/Widget_audio.ipynb

That will fetch a notebook that you can run, based on code described here.

Alternatively, you can use the classic interface by launching fresh to one or switching from the JupyterLab inferface back by using from the menubar, 'Help' > 'Launch Classic Notebook'.

(I believe the notebook used in this example is based on here, or vice versa. When I tried that one in the ipywidgets docs from a session that already had ipywidgets installed & not much else, I had to also install matplotlib along with ipywidgets via running %pip install matplotlib, because of the line import matplotlib.pyplot as plt.)


UPDATE: use pydub to edit audio via MyBinder and hear it played

This was added in response to the comments to the general answer. Specifically, pydub use is demonstrated using a different enviornment, since pydub needs ffmpeg.

Go here and click on 'launch binder' to spin up a session where ffmpeg is installed in the backing environment. pydub needs ffmpeg or equivalent.

You can run the following line in a notebook and then open the notebook that it gets to work though that demonstration:

!curl -OL https://gist.githubusercontent.com/fomightez/86482965bbce4bbbb7adb4c98f6cd9e6/raw/d31473699d8a2ec6d31dbf1d9590b8a0ef8972db/pydub_edit_plays_via_mybinder.ipynb```

Or step through the equivalent demonstration code in a notebook in JupyterLan by following these steps.  
First enter in a cell the following:

```python
%pip install pydub

Get an audio file to use for testing by running this:

!curl -OL http://www.nch.com.au/acm/8k16bitpcm.wav

Edit that file and playback the result in the notebook without interacting with it, by running this in a cell:

from pydub import AudioSegment
from pydub.playback import play

start = 1000
end = 3000
audio = AudioSegment.from_file("8k16bitpcm.wav")
audio_piece = audio[start:end] 
audio_piece.export("test_clip.wav", format='wav')
from IPython.display import Audio, display
Audio("test_clip.wav", autoplay=True)
Wayne
  • 6,607
  • 8
  • 36
  • 93
  • Thanks a lot for your answer Wayne! The problem for me with IPython audio playback is that it always displays the player (which of course makes sense as IPython is about interactive computing). Unfortunately, I can't use this for my project. A package like pydub does what I want (if I run the code above in a Jupyter notebook on my local machine) but I can't make it work on a Binder-served notebook (or on Google Colab). I guess it's a dependencies issue or a missing library but I can't figure out which or what. – ai4ki Jun 06 '22 at 13:15
  • You can have it play the audio automatically if that helps? See [the comment here](https://stackoverflow.com/a/30741861/8508004) about the `autoplay=True` parameter. Example from there:`IPython.display.Audio("my_audio_file.mp3", autoplay=True)` – Wayne Jun 06 '22 at 19:59
  • You can use pydub [here](https://github.com/fomightez/ffmpeg-python-binder) after running `%pip install pydub` in a cell; however, it doesn't allow listening to it. You have to download and listen locally. Or maybe then use recommendation above to play it automatically? So maybe you can export what you want using pydub's export method and then listen to it locally or use the method above to play the pydub-modified version? – Wayne Jun 06 '22 at 21:26
  • I added to answer an update pulling together those ideas so pydub output is played. – Wayne Jun 07 '22 at 16:58
  • Again, thanks so much for your support Wayne. I can reproduce your solution. But it doesn't solve my problem since it still displays the IPython player. Think of the code snippet I posted as a function: When I call this function, for example by clicking a ipywidgets button bound to this function, I want the audio to be played directly. Pydub "play()" does this when I run my notebook locally. Yet on Binder it doesn't because it can't find an audio device (even with a package like ffmpeg-python installed). Sorry, if I wasn't clear enough on this earlier. – ai4ki Jun 08 '22 at 08:01
  • Have you actually tried linking `IPython.display.Audio("my_audio_file.mp3", autoplay=True)` to a ipywidget button? Currently, though the player is shown so you can play it again, it plays initially without interaction when the code is run. If pydub can only play with the hardware, then it won't work via Jupyter running on a remote machine. Maybe ask at the Pydub repo about options for running it headless and using `play()`. But it seems like you can use pydub to do what you need and play with a remote compatible way. – Wayne Jun 08 '22 at 15:07
  • Yes, I tried linking `IPython.display Audio(...)` to a button and it doesn't play. Thanks again! – ai4ki Jun 09 '22 at 13:03
  • AN FYI: I came across [this](https://twitter.com/benbovy/status/1534638861678174209). I wondered if how they handle audio play in the notebook may spark some ideas for your needs? – Wayne Jun 09 '22 at 16:28