Problem using client callback to take picture via client camera

I am trying to build an app to allow user to take picture with their camera. I think in Dash we don’t have the tool so I used client callback with JavaScript codes. The JS codes run well in normal HTML+JS, but not in Dash.

My Dash Codes:

from dash import Dash, html, dcc, Input, Output

app = Dash(name=__name__)

app.layout = html.Div([
    html.H1("test of pictures"),
    html.Div([
        html.Div([
            html.Button("start", id="buttonStart"),
            html.Video(id="video",  style={"width":"500px", "height":"500px", "autoplay":"autoplay", "border":"1px solid red"})
        ], style={"display":"block"}),
        html.Div([
            html.Button("take photo", id="buttonPhoto"),
            html.Canvas(id="canvas",  style={"width":"500px", "height":"500px", "border":"1px solid green"})
        ], style={"display":"block"}),
        html.Div([
            html.Button("Stop", id="buttonStop"),
            html.Img(id="img",  style={"width":"500px", "height":"500px", "autoplay":"autoplay", "border":"1px solid blue"})
        ], style={"display":"block"}),
    ], style={"display":"flex"})

])

app.clientside_callback(
    '''
    function startVideo(){
        var srcVideo = document.getElementById("video");
        var constraints = {
            video:{
                width:500,
                height:500
            },
            audio:false,
        };
        var mediaPromise = navigator.mediaDevices.getUserMedia(constraints);
        mediaPromise.then((stream)=>{
            srcVideo.srcObject = stream;
            srcVideo.play();
        }).catch((err)=>{console.log(err);})
    }
    ''',
    Output("video", "children"),
    Input("buttonStart", "n_clicks"),
    prevent_initial_call = True,
)

app.clientside_callback(
    '''
    function takePhoto(){
        var srcVideo = document.getElementById("video");
        var tempCanvas = document.getElementById("canvas");
        var targImg = document.getElementById("img");
        var ctx = tempCanvas.getContext('2d');
        ctx.drawImage(srcVideo, 0, 0);
        var img =tempCanvas.toDataURL('image/jpeg');
        targImg.src = img;
    }
    ''',
    Output("canvas", "children"),
    Input("buttonPhoto", "n_clicks"),
    prevent_initial_call = True,
)

app.clientside_callback(
    '''
    function stopVideo(){
        var srcVideo = document.getElementById("video");
        var stream = srcVideo.srcObject;
        var tracks = stream.getTracks();
        tracks.forEach((track) => {
            track.stop();
        });
        stream = null;
    }
    ''',
    Output("img", "children"),
    Input("buttonStop", "n_clicks"),
    prevent_initial_call = True,
)

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

The problem is after click button “take photo”, only a small section of video (left-top corner) was taken as the picture displayed, while the same JS codes run well in following HTML file:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>photo test</title>
    <meta charset="utf-8">
</head>

<body>
    <div>
        <button onclick="startVideo()">start</button>
        <button onclick="takePhoto()">photo</button>
        <button onclick="stopVideo()">stop</button>
    </div>
    <div>
        <video id="videoTest" width="200px" height="200px" autoplay="autoplay"></video>
        <canvas id="canvasTest" width="200px" height="200px"></canvas>
        <img id="imgTest" width="200px" height="200px">
    </div>

    <script>
        function startVideo(){
            var srcVideo = document.getElementById("videoTest");
            var constraints = {
                video:{
                    width:200,
                    height:200
                },
                audio:false,
            };
            var mediaPromise = navigator.mediaDevices.getUserMedia(constraints);
            mediaPromise.then((stream)=>{
                srcVideo.srcObject = stream;
                srcVideo.play();
            }).catch((err)=>{console.log(err);})
        }

        function stopVideo(){
            var srcVideo = document.getElementById("videoTest");
            var stream = srcVideo.srcObject;
            var tracks = stream.getTracks();
            tracks.forEach((track) => {
                track.stop();
            });
            stream = null;
        }

        function takePhoto(){
            var srcVideo = document.getElementById("videoTest");
            var tempCanvas = document.getElementById("canvasTest");
            var targImg = document.getElementById("imgTest");
            var ctx = tempCanvas.getContext('2d');
            ctx.drawImage(srcVideo, 0, 0);
            var img =tempCanvas.toDataURL('image/jpeg');
            targImg.src = img;
        }

    </script>
</body>

So I got quite confused and don’t know what is the problem in my Dash codes. If someone got any idea about it please kindly help me. Thanks very much.