You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dash应用更新视频文件触发全应用刷新问题求助

Dash应用散点图点击后刷新且视频无法播放问题排查与解决

问题描述

我开发了一款Dash应用,散点图的点击数据包含S3桶中视频文件的存储路径。预期点击图上的点位时会播放对应关联视频,但实际操作时应用会直接刷新。此前将下载的视频存储在静态文件夹时该功能可正常运行,但现在采用此方式存储的视频完全无法播放。相关代码如下:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import boto3
import dynamo_utils
import plotly_express as px
from datetime import datetime

s3 = boto3.client('s3', aws_access_key_id='', aws_secret_access_key='')

df = dynamo_utils.query_site('data')

# Create a copy dataset so original isn't altered
ddf = df.copy()

dff = df.copy()
dff["Event"] = 1
# If a day, then


# Graph data

app = dash.Dash(__name__)

app.layout = html.Div([

dcc.Graph(
    id='scatter-plot',
    figure=px.scatter(dff, x=dff.Human_Time, y=dff.Event, custom_data=["Machine_Id", "Bucket", "File_Path"]),
     clickData={'points': [{'customdata': ""}]}
 # Set initial click data
),

    html.Div(
    children=html.Video(
        controls=True,
        id='video_player',
        src="",
        autoPlay=True,
        style={'width': "70%", 'text-align': 'center'}
    ),
    className="card",
    style={'text-align': 'center'}
),
])

@app.callback(Output('video_player', 'src'),
          [Input('scatter-plot', 'clickData')])
def updateVideo(clk_data):
# This will cause video data to appear if data in graph if clicked
# No need to display data if there is

    video_file = ""
    if clk_data is None:
        video_src = None
    else:
    # Get the current time for saving files
        now = datetime.now()
        current_time = now.strftime("%H_%M_%S")
        print(clk_data)
    # clk_data allows us to get each
    # machineID = clk_data['points'][0]['customdata'][0]
        bucket = clk_data['points'][0]['customdata'][1].split(" ")[0]
        path = clk_data['points'][0]['customdata'][2]
        filePath = path.split(".")[0]

        print(filePath)
        print(bucket)

        try:

             s3.download_file(bucket, filePath + ".mp4", 'app/assets/' + "vid_" + str(current_time) + ".mp4")

        except:
             print("video not downloading")

        video_file = 'app/assets/'+ "vid_" + str(current_time) + ".mp4"


    return video_file,
if __name__ == '__main__':
    app.run_server(debug=True)

问题原因

  • 视频路径格式错误:Dash的静态资源需要用相对URL(如/assets/xxx.mp4)访问,直接返回本地文件路径app/assets/xxx.mp4会导致浏览器无法识别资源,触发页面刷新。
  • 回调返回值格式异常:回调最后返回video_file,(带逗号),会返回一个元组,但Output只接受单个字符串,格式不匹配可能引发隐性异常,导致页面刷新。
  • Debug模式下静态资源未实时加载:Debug模式中,Dash不会自动检测assets文件夹中新添加的文件,刚下载的视频无法被立即识别,导致加载失败。

解决方案

1. 修正视频资源路径

将回调中返回的本地路径改为Dash静态资源的URL格式:

video_file = f'/assets/vid_{current_time}.mp4'

无需添加app/前缀,Dash会自动从assets目录读取资源。

2. 修复回调返回值

去掉返回语句的逗号,确保返回单个字符串:

return video_file

3. 解决Debug模式静态资源加载问题

  • 方案一(推荐生产环境):关闭Debug模式运行应用,此时Dash会读取assets目录下所有文件。
  • 方案二(保留Debug模式):初始化Dash时指定assets目录并强制本地服务,禁用缓存:
    app = dash.Dash(__name__, assets_folder='app/assets', serve_locally=True)
    
    可选:在下载视频后添加短暂延迟,确保文件完全写入后再返回路径:
    import time
    time.sleep(0.5)  # 延迟0.5秒,根据文件大小调整
    

4. 优化S3下载异常排查

添加详细的异常捕获,方便定位下载失败原因:

try:
    s3.download_file(bucket, f"{filePath}.mp4", f'app/assets/vid_{current_time}.mp4')
    print("视频下载成功")
except Exception as e:
    print(f"视频下载失败: {str(e)}")
    video_file = ""

内容的提问来源于stack exchange,提问作者Totes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:55:18