-
-
Save scottire/7fe5e25f1654fb901fb7f024533d5508 to your computer and use it in GitHub Desktop.
from ipywidgets import IntSlider, ToggleButton, Text | |
from IPython.display import display, Audio, Javascript | |
from scipy.io import wavfile | |
import numpy as np | |
from matplotlib import pyplot as plt | |
import ipywidgets | |
t = Text(value='0', | |
description='Elapsed Time:', | |
style = {'description_width': 'initial'}, | |
) | |
fs, data = wavfile.read('./4k6c030p.wav') | |
a = Audio(data, | |
rate=fs, | |
autoplay=True, | |
element_id = 'audio_element', | |
) | |
fig, ax = plt.subplots(constrained_layout=True, figsize=(6, 4)) | |
line = ax.axvline(0) | |
time = np.linspace(0, len(data) / fs, num=len(data)) | |
ax.plot(time, data) | |
s = IntSlider(max=len(data) / fs, | |
description='Elapsed Time:', | |
style = {'description_width': 'initial'}, | |
) | |
def update(change): | |
"""redraw line (update plot)""" | |
line.set_xdata(np.array([change.new, change.new])) | |
fig.canvas.draw() | |
s.observe(update, 'value') | |
display(a,t,s) | |
jscript = f''' | |
var time_check; | |
var stop_checking = false; | |
function updateTime() {{ | |
var audio_element = document.getElementById("audio_element"); | |
var manager = window.IPython.WidgetManager._managers[0]; | |
if (audio_element == null) {{ | |
clearTimeout(time_check); | |
return; | |
}} | |
// Change value only once after pausing | |
if ((!audio_element.paused) || (!stop_checking)) {{ | |
if (audio_element.paused) stop_checking = true; | |
else stop_checking = false; | |
var model_prom = manager.get_model('{t.model_id}'); | |
model_prom.then(function(model) {{ | |
model.set('value', "" + audio_element.currentTime); | |
model.save_changes(); | |
}}); | |
var model_prom = manager.get_model('{s.model_id}'); | |
model_prom.then(function(model) {{ | |
model.set('value', Math.floor(audio_element.currentTime)); | |
model.save_changes(); | |
}}); | |
}}//endif | |
time_check = setTimeout(updateTime, 1000); | |
}} | |
updateTime(); | |
''' | |
Javascript(jscript) |
Hmm... I used Jupyter Notebooks and potentially there’s something different about IPython within Javascript with JupyterLab.
Try calling %matplotlib inline
or %matplotlib widget
before running this.
Thanks! I did that. Then I had to pip install ipympl, and then chase down this issue. Now I see this, which is progress, but the slider still doesn't seem to do what you mention here. And that error is still around. Not sure if Jupyterlab does things differently from notebook. I inspected the HTML and there is an audio_element
div.
That's good that you now have ipywidgets usable in JupyterLab. Unfortunately, it seems it's not possible to get the WidgetManager from within JupyterLab. I did a bit of reading around and it seems there's no equivalent of window.IPython
within JupyterLab, which seems to have been done for security reasons so arbitrary javascript can't be run. It would be great if it was possible to get the currentTime
from the audio element by some other means but I'm not sure about how/if that can be done from within JupyterLab, other than building a new jupyterlab extension.
@delip I was able to find another method to get the playhead alongside playable audio within Jupyter Lab.
See here: https://gist.github.com/scottire/654019e88e6225c15a68006ab4a3ba98
This already visualises the audio, but the on_time_update
callback can be used to update any visualisations playhead using matplotlib like in the above code with line.set_xdata(np.array([time, time])
.
You'll need to follow the instructions to install jp_proxy_widget with JupyterLab.
Followed this verbatim in my jupyterlab notebook and the
Javascript
fails with this error:Javascript Error: Cannot read property 'WidgetManager' of undefined
Any ideas why?