I have a sample script here which play sound only once after it is loaded.
import dash
import dash_html_components as html
import base64
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
# Encode the local sound file.
sound_filename = 'path_to_your_file.mp3' # replace with your own .mp3 file
encoded_sound = base64.b64encode(open(sound_filename, 'rb').read())
app.layout = html.Div(children=[
html.H1(children='Demo for Audio with Dash'),
html.Div(children='''
Click the button to play your local .mp3 sounds.
'''),
html.Button(id="button1", children="Click me for sound"),
html.Div(id="placeholder", style={"display": "none"})])
@app.callback(Output("placeholder", "children"),
[Input("button1", "n_clicks")],
)
def play(n_clicks):
if n_clicks is None:
n_clicks = 0
if n_clicks != 0:
return html.Audio(src='data:audio/mpeg;base64,{}'.format(encoded_sound.decode()),
controls=False,
autoPlay=True,
)
if __name__ == '__main__':
app.run_server(debug=True)
what I want is to play sound each time the button is clicked. Let me know if this is possible. Thank you!
I was solving the same issue and to my knowledge, unfortunately there is no straightforward solution available. Custom dash component would be a solution, but that was too complicated for my use case.
I ended up with javascript callbacks:
from dash import html, Input, Output, Dash
import base64
app = Dash(__name__)
# Encode the local sound file.
sound_filename = 'audio_file.mp3' # replace with your own .mp3 file
encoded_sound = base64.b64encode(open(sound_filename, 'rb').read())
app.layout = html.Div(children=[
html.H1(children='Demo for Audio with Dash'),
html.Div(children='''
Click the button to play your local .mp3 sounds.
'''),
html.Button(id="button1", children="Click me for sound"),
html.Audio(id='audio-player', src='data:audio/mpeg;base64,{}'.format(encoded_sound.decode()),
controls=True,
autoPlay=False,
),
html.Div(id="placeholder", style={"display": "none"})])
app.clientside_callback(
"""
function(n) {
var audio = document.querySelector('#audio-player');
if (!audio){
return -1;
}
audio.play();
return '';
}
""", Output('placeholder', 'children'), [Input('button1', 'n_clicks')],
prevent_initial_call=True
)
if __name__ == '__main__':
app.run_server(debug=True)
It should be possible to also interconnect some events from some slider component to have seekable audio element…
Note that with javascript callbacks you need to hard-refresh browser cache whenever you modify javascript code because it won’t update automatically as in python callbacks.