Dash Player Custom Component - Playing and controlling your videos with Dash

Hey all! I just created this Dash wrapper around the well known react-player component. I added all the relevant properties, every single instance methods, as well as supplementary props to control update intervals of the methods.

Feedback are appreciated! Feel free to create an issue or fork/PR if you want to add anything :slight_smile:

Link to the repo: GitHub - plotly/dash-player: Dash Component wrapping React-Player
Link to the usage example app: http://dash-player-usage.herokuapp.com

8 Likes

This looks like what I am looking for, for my PhD work. I have several cameras and an audio recorder recording simultaneously. I want to be able to see the videos at the times where specific sounds are detected. Are you able to start playing videos at specific times ? Can you also play local videos (i.e. not hosted on the web) ? Thanks a bunch for your help/comments.

Is it possible to add custom controls for forward and backward movement in file?

Answer would be highly appreciated!

Solved it.

Use html.Button and update the state of video player within the callback.

Here is my example callback:

@app.callback(Output('video-player', 'seekTo'),
              [Input('button-backward-25s', 'n_clicks'),
              Input('button-backward-15s', 'n_clicks'),
              Input('button-backward-10s', 'n_clicks'),
              Input('button-backward-5s', 'n_clicks'),
              Input('button-backward-3s', 'n_clicks'),
              Input('button-forward-3s', 'n_clicks'),
              Input('button-forward-5s', 'n_clicks'),
              Input('button-forward-10s', 'n_clicks'),
              Input('button-forward-15s', 'n_clicks'),
              Input('button-forward-25s', 'n_clicks'),
              ],
              [State('video-player', 'currentTime')])
def set_seekTo(min_25, min_15, min_10, min_5, min_3, plus_3, plus_5, plus_10, plus_15, plus_25, currentTime):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
    if currentTime is None:
        return currentTime
    elif 'button-backward-25s' in changed_id:
        return (currentTime - 25)
    elif 'button-backward-15s' in changed_id:
        return (currentTime - 15)
    elif 'button-backward-10s' in changed_id:
        return (currentTime - 10)
    elif 'button-backward-5s' in changed_id:
        return (currentTime - 5)
    elif 'button-backward-3s' in changed_id:
        return (currentTime - 3)
    elif 'button-forward-25s' in changed_id:
        return (currentTime + 25)
    elif 'button-forward-15s' in changed_id:
        return (currentTime + 15)
    elif 'button-forward-10s' in changed_id:
        return (currentTime + 10)
    elif 'button-forward-5s' in changed_id:
        return (currentTime + 5)
    elif 'button-forward-3s' in changed_id:
        return (currentTime + 3)

Thanks for this awesome component!

1 Like

I noticed that my browser throws a lot of error messages, whenever I restart the server in python while the page is still loaded in the browser. This even happens for the supplied examples. The video player works nicely, but I don’t know if this somehow impacts performance, so I want to get rid of these error messages.

Reproduction is quite simple:

  1. Start dash app in python
  2. Open dash app in browser
  3. Restart dash app in python
  4. Open browser console (F12)

Example Code from dash-player/DashPlayer.py at master Β· plotly/dash-player Β· GitHub :

import dash_player
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

app.scripts.config.serve_locally = True


app.layout = html.Div(
    [
        dash_player.DashPlayer(
            id="video-player",
            url="http://media.w3.org/2010/05/bunny/movie.mp4",
            controls=True,
        ),
        dcc.Checklist(
            id="radio-bool-props",
            options=[
                {"label": val.capitalize(), "value": val}
                for val in ["playing", "loop", "controls", "muted", "seekTo"]
            ],
            value=["controls"],
        ),
    ]
)


@app.callback(Output("video-player", "playing"), [Input("radio-bool-props", "value")])
def update_prop_playing(value):
    return "playing" in value


@app.callback(Output("video-player", "loop"), [Input("radio-bool-props", "value")])
def update_prop_loop(value):
    return "loop" in value


@app.callback(Output("video-player", "controls"), [Input("radio-bool-props", "value")])
def update_prop_controls(value):
    return "controls" in value


@app.callback(Output("video-player", "muted"), [Input("radio-bool-props", "value")])
def update_prop_muted(value):
    return "muted" in value


@app.callback(Output("video-player", "seekTo"), [Input("radio-bool-props", "value")])
def update_prop_seekTo(value):
    if "seekTo" in value:
        return 5


if __name__ == "__main__":
    app.run_server(debug=True)

Maybe it has to do with any recent updates, as the DashPlayer component is from 2019. Any ideas, @xhlu or someone else?
Thanks a lot!