tutorial reproduce notebook español python ipython ipython-notebook

python - reproduce - jupyter notebook tutorial pdf



Reproduce automáticamente el sonido en el portátil IPython (6)

A menudo corro celdas de larga duración en mi cuaderno de IPython. Me gustaría que la notebook emita un pitido o reproduzca un sonido automáticamente cuando la celda haya terminado de ejecutarse. ¿Hay alguna forma de hacer esto en el cuaderno iPython, o tal vez algún comando que pueda poner al final de una celda que reproduzca automáticamente un sonido?

Estoy usando Chrome si eso hace alguna diferencia.


TL; DR

En la parte superior de tu cuaderno.

from IPython.display import Audio sound_file = ''./sound/beep.wav''

sound_file debe apuntar a un archivo en su computadora, o accesible desde internet.

Luego, más tarde, al final de la celda de larga duración.

<code that takes a long time> Audio(sound_file, autoplay=True)

Este método utiliza la etiqueta de Audio integrada en las versiones más nuevas de iPython / Jupyter.

Nota para versiones anteriores

Las versiones anteriores sin la etiqueta de audio pueden usar el siguiente método.

Coloca esto en una celda y ejecútalo antes de que quieras reproducir tu sonido:

from IPython.display import HTML from base64 import b64encode path_to_audio = "/path/to/snd/my-sound.mp3" audio_type = "mp3" sound = open(path_to_audio, "rb").read() sound_encoded = b64encode(sound) sound_tag = """ <audio id="beep" controls src="data:audio/{1};base64,{0}"> </audio>""".format(sound_encoded, audio_type) play_beep = """ <script type="text/javascript"> var audio = document.getElementById("beep"); audio.play(); </script> """ HTML(sound_tag)

Al final de la celda que desea hacer un ruido al finalizar, coloque esto:

HTML(play_beep)

Cómo funciona:

Lee un archivo del sistema de archivos utilizando los métodos de read y open integrados de iPython. Luego codifica esto en base64. A continuación, crea una etiqueta de audio con el beep ID e inyecta los datos base64 en ella. La pieza final de la configuración crea una pequeña etiqueta de secuencia de comandos que reproduce el sonido.

Este método debería funcionar en cualquier navegador que admita la etiqueta de audio HTML5.

Nota: si prefiere no mostrar los controles de audio en su computadora portátil, simplemente elimine el atributo de controls de la variable llamada sound_tag


¿Qué hay de escribir el código una vez y hacer que funcione después de la ejecución de cada celda si se ejecuta más tiempo que el dado?

Simplemente crea y ejecuta una celda con JavaScript siguiente (ajuste de tiempo de espera y sonido)

%%javascript (function(){ var startTime; $([Jupyter.events]).on(''execute.CodeCell'', function(event, target) { startTime = performance.now(); }); $([Jupyter.events]).on(''finished_iopub.Kernel'', function(event, target) { var endTime = performance.now(); if(endTime - startTime > 5 * 1000) { var audio = new Audio(''http://www.soundjay.com/button/beep-07.wav''); audio.play(); } }); })()

Después de eso, debería escuchar el "pitido" después de cada ejecución de código que duró más de 5 segundos. Por ejemplo:

# cell 0: from time import sleep # cell 1: sleep(6) # will ring

Si luego agregas otra celda

# cell 3: sleep(3) # it won''t ring

A menos que ejecutes varias celdas a la vez:

# cell 4: sleep(3) # cell 5: sleep(3) # will ring if queued for execution after cell 4

Probado con el cuaderno Jupyter 5.5.0.

El código puede requerir mejoras adicionales (no dudes en editarlo). Para que funcione en Google Colab, uno necesita cargar jQuery por su cuenta. Parece que no funciona con JupyterLab todavía.

Para apagar, utilice:

%%javascript // a slightly better version would unbind only the handlers defined above $([Jupyter.events]).unbind(''execute.CodeCell'') $([Jupyter.events]).unbind(''finished_iopub.Kernel'')

También puede usar el sonido de pitido codificado en base64 (vea esta respuesta y esta idea ):

var audio = new Audio(''data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU='');


Aquí hay otra versión (Python-side principalmente) que funciona bien con JupyterLab:

from time import time from IPython import get_ipython from IPython.display import Audio, display class Beeper: def __init__(self, threshold, **audio_kwargs): self.threshold = threshold self.start_time = None # time in sec, or None self.audio = audio_kwargs def pre_execute(self): if not self.start_time: self.start_time = time() def post_execute(self): end_time = time() if self.start_time and end_time - self.start_time > self.threshold: audio = Audio(**self.audio, autoplay=True) display(audio) self.start_time = None beeper = Beeper(5, url=''http://www.soundjay.com/button/beep-07.wav'') ipython = get_ipython() ipython.events.register(''pre_execute'', beeper.pre_execute) ipython.events.register(''post_execute'', beeper.post_execute)

El pitido se emitirá automáticamente después de cada ejecución de código que duró más de 5 segundos, pero las ejecuciones consecutivas no se cuentan juntas.

Por ejemplo:

# cell 0: from time import sleep # cell 1: sleep(6) # will ring

Si luego agregas otra celda

# cell 3: sleep(3) # it won''t ring

Probado con JupyterLab 0.32.1 y Jupyter notebook 5.5.0.

Editar: para reducir el desorden de los reproductores de audio que se muestran, uso el siguiente fragmento de código (para Python anterior a 3.6 debe usar .format() lugar de cadenas de caracteres):

from IPython.display import Audio, display class InvisibleAudio(Audio): def _repr_html_(self): audio = super()._repr_html_() audio = audio.replace(''<audio'', f''<audio onended="this.parentNode.removeChild(this)"'') return f''<div style="display:none">{audio}</div>''

y luego use InvisibleAudio lugar de Audio en post_execute .


Basado en la respuesta de @krassowski, aquí está mi solución a esto. La principal diferencia es que @ krassowski se ejecuta después de cada ejecución de celda "larga" (donde se define lo que significa "larga"); Prefiero decir explícitamente cuándo quiero que se reproduzca el sonido, así que lo he envuelto en una magia ( here copia y se copia a continuación).

""" Adds a magic to IPython which will play a given sound when a cell finishes running. Requires Python 3.6+. Put this file in, e.g., ~/.ipython/profile_default/startup to load this magic on startup. USAGE: ``` %%notify run_long_function() ``` If you want, you can specify the URL of the audio file to play: ``` %%notify -u "{URL}" run_long_function() ``` To always play your preferred audio file, just change the default below. """ from IPython.display import HTML, Audio, display from IPython.core.magic_arguments import magic_arguments, argument, parse_argstring from IPython.core.magic import cell_magic, Magics, magics_class from IPython import get_ipython class _InvisibleAudio(Audio): """ An invisible (`display: none`) `Audio` element which removes itself when finished playing. Taken from https://.com/a/50648266. """ def _repr_html_(self) -> str: audio = super()._repr_html_() audio = audio.replace( "<audio", ''<audio onended="this.parentNode.removeChild(this)"'' ) return f''<div style="display:none">{audio}</div>'' @magics_class class NotificationMagics(Magics): """ Inspired by https://.com/a/50648266. """ @cell_magic @magic_arguments() @argument( "-u", "--url", help="URL of sound to play", default="https://freewavesamples.com/files/E-Mu-Proteus-FX-CosmoBel-C3.wav", ) def notify(self, line: str, cell: str): args = parse_argstring(self.notify, line) ret = self.shell.ex(cell) audio = _InvisibleAudio(url=args.url, autoplay=True) display(audio) return ret get_ipython().register_magics(NotificationMagics)


Mi solución favorita (sin necesidad de un módulo externo):

import os os.system("printf ''/a''") # or ''/7''

Funciona en OS X.

Sin embargo, la observación de DaveP sigue siendo válida: no es el navegador que reproduce el sonido, sino el servidor.


Podrías usar un módulo externo con python. Intente agregar esta llamada s.play() desde Snack Sound Toolkit al final de la celda.

Snack Sound Toolkit puede reproducir archivos wav, au y mp3.

s = Sound() s.read(''sound.wav'') s.play()

esta pregunta es básicamente un duplicado de: Reproducir un sonido con Python .

El código-snipit anterior fue de @csexton en esa pregunta.