Подтвердить что ты не робот

Автоматически воспроизводить звук в ноутбуке IPython

Я часто запускаю длинные ячейки в своем ноутбуке IPython. Я хочу, чтобы ноутбук автоматически подавал звуковой сигнал или воспроизводил звук, когда ячейка завершена. Есть ли способ сделать это в ноутбуке iPython, или, может быть, некоторая команда, которую я могу положить в конце ячейки, которая будет автоматически воспроизводить звук?

Я использую Chrome, если это имеет значение.

4b9b3361

Ответ 1

TL; DR

В верхней части вашего ноутбука

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

sound_file должен указывать на файл на вашем компьютере или доступный из Интернета.

Затем, позже, в конце длительной камеры

<code that takes a long time>

Audio(sound_file, autoplay=True)

Этот метод использует тег Audio, встроенный в более новые версии iPython/Jupyter.

Примечание для старых версий

В старых версиях без тега Audio можно использовать следующий метод.

Поместите это в ячейку и запустите, прежде чем захотите воспроизвести свой звук:

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)

В конце ячейки, которую вы хотите сделать по завершении, добавьте шум:

HTML(play_beep)

Как это устроено:

Он читает файл из файловой системы, используя iPython, встроенный в методы open и read. Затем он кодирует это в base64. Затем он создает звуковую метку с beep ID и вводит в нее данные base64. Последний фрагмент настройки создает небольшой тег сценария, который воспроизводит звук.

Этот метод должен работать в любом браузере, который поддерживает аудио-тег HTML5.

Примечание. Если вы не хотите отображать элементы управления звуком в своей записной книжке, просто удалите атрибут controls из переменной с именем sound_tag

Ответ 2

Мое любимое решение (нет необходимости в внешнем модуле):

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

Работает на OS X.

Однако замечание DaveP все еще применяется: это не браузер, воспроизводящий звук, а сервер.

Ответ 3

Вы можете использовать внешний модуль с python. Попробуйте добавить этот вызов s.play() из инструментария Snack Sound Toolkit в конце ячейки.

Инструмент Snack Sound Toolkit может воспроизводить файлы wav, au и mp3.

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

этот вопрос в основном является дубликатом: Воспроизвести звук с помощью Python.

Вышеупомянутый код-snipit был из @csexton в этом вопросе.

Ответ 4

Вот еще одна версия (в основном на стороне Python), которая хорошо работает с 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)

Звуковой сигнал будет издаваться автоматически после каждого выполнения кода, которое занимало более 5 секунд, но последовательные исполнения не учитываются вместе.

Например:

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

Если вы добавите еще одну ячейку

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

Протестировано с JupyterLab 0.32.1 и ноутбуком Jupyter 5.5.0.

Редактировать: чтобы уменьшить помехи показанных аудиоплееров, я использую следующий фрагмент (для Python старше 3.6 вам нужно использовать .format() вместо f-строк):

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>'

и затем используйте InvisibleAudio вместо Audio в post_execute.

Ответ 5

Как насчет того, чтобы набрать код один раз и заставить его работать после выполнения каждой ячейки, если он выполняется дольше указанного времени?

Просто создайте и выполните ячейку со следующим JavaScript (настройка времени ожидания и звука)

%%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();    
        }
    });
})()

После этого вы должны слышать звуковой сигнал после каждого выполнения кода, которое занимало более 5 секунд. Например:

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

Если вы добавите еще одну ячейку

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

Если вы не выполните несколько ячеек одновременно:

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

Протестировано с ноутбуком Jupyter 5.5.0.

Код может потребовать дальнейших улучшений (не стесняйтесь редактировать). Чтобы он работал в Google Colab, нужно загрузить jQuery самостоятельно. Кажется, еще не работает с JupyterLab.

Чтобы выключить, используйте:

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

Вы также можете использовать звуковой сигнал в кодировке Base64 (см. Этот ответ и эту суть):

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=');

Ответ 6

Исходя из ответа @krassowski, вот мое решение. Основное отличие состоит в том, что @krassowski запускается после каждого "длинного" выполнения ячейки (где вы определяете, что означает "длинный"); Я предпочитаю явно говорить, когда я хочу, чтобы звук воспроизводился, поэтому я обернул это в магию (суть здесь и скопирована ниже).

"""
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://stackoverflow.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://stackoverflow.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)

Ответ 7

Похвальный отзыв.

Я искал этот конкретный ответ несколько раз, но не смог найти его здесь.

winsound.Beep(freq, time_in_millisec)

Я использую:

winsound.Beep(300, 200)
winsound.Beep(300, 200)
winsound.Beep(300, 700)