I am trying to add subtitles to my Plotly Dash video player, i.e. VTT captions overlay, in Python. I cannot find any examples or instruction on this.
from dash import Dash, dcc, html, Input, Output, State
import dash_player
And in a html Div somewhere:
dash_player.DashPlayer(
id='vid1',
controls = True,
url = "http://86.47.173.33:1935/playlist.m3u8",
width='100%',
style={'margin-top':'20px','margin-bottom':'20px'},
playing= True,
muted= True
)
The DashPlayer object has no methods to handle a subtitle track in the documentation. Perhaps this is something that could be handled in CSS?
To find some React player examples.
My strategy in the end was to create a div ('subtitle-container') as a sibling to the DashPlayer in the layout:
dash_player.DashPlayer(
id='vid',
controls = True,
url = None,
style={'margin-top':'20px','margin-bottom':'20px', 'margin-left':'10px'},
playing= False,
muted= False
),
html.Div(
id='subtitle-container',
children=[html.P("subtitle text")],
style={}
),
I implemented my own logic to display the subtitles, in the subtitle-container using the DashPlayer's 'current-time' callback.
@app.callback([Output('subtitle-container','children'),Output('subtitle-container', 'style')],
[Input('vid', 'currentTime')])
def update_subtitles(current_time):
subtitle_text = get_subtitle_for_time(current_time)
# Determine whether subtitles are being displayed
subtitles_displayed = bool(subtitle_text)
# Set the alpha value based on whether subtitles are being displayed
alpha_value = 0 if not subtitles_displayed else 0.5
# Update subtitle container style
subtitle_style={
'position':'absolute',
'bottom':'6%',
'left': '25%',
'width':'50%',
'background-color':f'rgba(30,30,30, {alpha_value})',
'padding':'5px',
'whiteSpace':'pre-wrap',
'color':'white',
'text-align':'center'
}
return subtitle_text, subtitle_style
This callback returns the relevant caption based on the player's current time, to be displayed in the 'subtitle-container'. I also implement logic to determine the style for the subtitle, semi-transparent dark background when caption present, and no background (alpha = 0), when no caption is present.
To gather all the captions initially, I parse an SRT file, to produce a list of caption items. Each caption item is a list of 3 items, start time, end time, and caption text. e.g
[1185.65, 1193.74, "You're the one who was frowning.\nFrisco. San Francisco. Exactly.'].
The timings have been converted from the original SRT timestamps.
Getting the appropriate cue for the player's current time is simply a matter of:
def get_subtitle_for_time(current_time):
for caption in captions:
if current_time <= caption[1]:
if current_time >= caption[0]:
return caption[2]
return ''