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
相关产品推荐
相关产品推荐

