From a3e9769e31c9c813ee4068f9de40bc8116fef82a Mon Sep 17 00:00:00 2001 From: HappyWorldGames Date: Sat, 20 May 2023 05:16:06 +0300 Subject: [PATCH] Added an audible notification after text generation in web. (#1277) --------- Co-authored-by: oobabooga <112222186+oobabooga@users.noreply.github.com> --- .gitignore | 1 + docs/Audio-Notification.md | 12 ++++++++++++ docs/README.md | 1 + server.py | 32 +++++++++++++++++++++++--------- 4 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 docs/Audio-Notification.md diff --git a/.gitignore b/.gitignore index dac4ce87..ba4939dc 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ venv/ *.log settings.json +notification.mp3 img_bot* img_me* prompts/[0-9]* diff --git a/docs/Audio-Notification.md b/docs/Audio-Notification.md new file mode 100644 index 00000000..5f928b32 --- /dev/null +++ b/docs/Audio-Notification.md @@ -0,0 +1,12 @@ +# Audio notification + +If your computer takes a long time to generate each response for the model that you are using, you can enable an audio notification for when the response is completed. This feature was kindly contributed by HappyWorldGames in [#1277](https://github.com/oobabooga/text-generation-webui/pull/1277). + +### Installation + +Simply place a file called "notification.mp3" in the same folder as `server.py`. Here you can find some examples (source: https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/1126): + +* https://pixabay.com/sound-effects/search/ding/?duration=0-30 +* https://pixabay.com/sound-effects/search/notification/?duration=0-30 + +This file will be automatically detected the next time you start the web UI. diff --git a/docs/README.md b/docs/README.md index 65dadd7c..b31026f4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,3 +17,4 @@ * [Windows installation guide](Windows-installation-guide.md) * [WSL installation guide](WSL-installation-guide.md) * [Docker Compose](Docker.md) +* [Audio notification](Audio-Notification.md) diff --git a/server.py b/server.py index c8cb0d38..2b8b36cd 100644 --- a/server.py +++ b/server.py @@ -540,6 +540,11 @@ def create_interface(): js += apply_extensions('js') with gr.Blocks(css=css, analytics_enabled=False, title=title, theme=ui.theme) as shared.gradio['interface']: + if Path("notification.mp3").exists(): + shared.gradio['audio_notification'] = gr.Audio(interactive=False, value="notification.mp3", elem_id="audio_notification", visible=False) + audio_notification_js = "document.querySelector('#audio_notification audio')?.play();" + else: + audio_notification_js = "" # Create chat mode interface if shared.is_chat(): @@ -761,32 +766,37 @@ def create_interface(): ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( lambda x: (x, ''), shared.gradio['textbox'], [shared.gradio['Chat input'], shared.gradio['textbox']], show_progress=False).then( chat.generate_chat_reply_wrapper, shared.input_params, shared.gradio['display'], show_progress=False).then( - chat.save_history, shared.gradio['mode'], None, show_progress=False) + chat.save_history, shared.gradio['mode'], None, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") ) gen_events.append(shared.gradio['textbox'].submit( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( lambda x: (x, ''), shared.gradio['textbox'], [shared.gradio['Chat input'], shared.gradio['textbox']], show_progress=False).then( chat.generate_chat_reply_wrapper, shared.input_params, shared.gradio['display'], show_progress=False).then( - chat.save_history, shared.gradio['mode'], None, show_progress=False) + chat.save_history, shared.gradio['mode'], None, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") ) gen_events.append(shared.gradio['Regenerate'].click( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( partial(chat.generate_chat_reply_wrapper, regenerate=True), shared.input_params, shared.gradio['display'], show_progress=False).then( - chat.save_history, shared.gradio['mode'], None, show_progress=False) + chat.save_history, shared.gradio['mode'], None, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") ) gen_events.append(shared.gradio['Continue'].click( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( partial(chat.generate_chat_reply_wrapper, _continue=True), shared.input_params, shared.gradio['display'], show_progress=False).then( - chat.save_history, shared.gradio['mode'], None, show_progress=False) + chat.save_history, shared.gradio['mode'], None, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") ) gen_events.append(shared.gradio['Impersonate'].click( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( lambda x: x, shared.gradio['textbox'], shared.gradio['Chat input'], show_progress=False).then( - chat.impersonate_wrapper, shared.input_params, shared.gradio['textbox'], show_progress=False) + chat.impersonate_wrapper, shared.input_params, shared.gradio['textbox'], show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") ) shared.gradio['Replace last reply'].click( @@ -860,14 +870,16 @@ def create_interface(): gen_events.append(shared.gradio['Generate'].click( lambda x: x, shared.gradio['textbox'], shared.gradio['last_input']).then( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( - generate_reply_wrapper, shared.input_params, output_params, show_progress=False) # .then( + generate_reply_wrapper, shared.input_params, output_params, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") # None, None, None, _js="() => {element = document.getElementsByTagName('textarea')[0]; element.scrollTop = element.scrollHeight}") ) gen_events.append(shared.gradio['textbox'].submit( lambda x: x, shared.gradio['textbox'], shared.gradio['last_input']).then( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( - generate_reply_wrapper, shared.input_params, output_params, show_progress=False) # .then( + generate_reply_wrapper, shared.input_params, output_params, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") # None, None, None, _js="() => {element = document.getElementsByTagName('textarea')[0]; element.scrollTop = element.scrollHeight}") ) @@ -876,13 +888,15 @@ def create_interface(): gen_events.append(shared.gradio['Regenerate'].click( lambda x: x, shared.gradio['last_input'], shared.gradio['textbox'], show_progress=False).then( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( - generate_reply_wrapper, shared.input_params, output_params, show_progress=False) # .then( + generate_reply_wrapper, shared.input_params, output_params, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") # None, None, None, _js="() => {element = document.getElementsByTagName('textarea')[0]; element.scrollTop = element.scrollHeight}") ) else: gen_events.append(shared.gradio['Continue'].click( ui.gather_interface_values, [shared.gradio[k] for k in shared.input_elements], shared.gradio['interface_state']).then( - generate_reply_wrapper, [shared.gradio['output_textbox']] + shared.input_params[1:], output_params, show_progress=False) # .then( + generate_reply_wrapper, [shared.gradio['output_textbox']] + shared.input_params[1:], output_params, show_progress=False).then( + None, None, None, _js=f"() => {{{audio_notification_js}}}") # None, None, None, _js="() => {element = document.getElementsByTagName('textarea')[1]; element.scrollTop = element.scrollHeight}") )