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

如何通过Flask上传视频并在Bootstrap表格中展示?

Flask + Bootstrap 实现表格内视频上传与时间轴同步

针对你遇到的Flask上传视频后无法在Bootstrap表格中展示、以及时间轴同步的问题,下面是分步解决方案:

一、修正Flask视频上传逻辑

首先确保上传的视频能被Flask正确存储并提供访问路径,这是展示的基础。以下是调整后的核心代码:

from flask import Flask, render_template, request, redirect, url_for, send_from_directory
import os
from werkzeug.utils import secure_filename

app = Flask(__name__)
# 配置上传目录(必须放在static下,否则无法被前端访问)
UPLOAD_FOLDER = 'static/uploads'
ALLOWED_EXTENSIONS = {'mp4', 'webm', 'ogg'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 自动创建上传目录
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

# 校验文件类型
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/')
def index():
    # 获取已上传的视频列表,用于前端渲染
    videos = [f for f in os.listdir(UPLOAD_FOLDER) if allowed_file(f)]
    return render_template('index.html', videos=videos)

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
        return redirect(request.url)
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        return redirect(url_for('index'))
    return redirect(request.url)

# 暴露上传文件的访问路由
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
    app.run(debug=True)

关键注意点:

  • 上传目录必须放在static目录下,否则前端无法直接访问;
  • 用secure_filename处理文件名,避免路径注入风险;
  • 添加uploaded_file路由,专门提供视频文件的访问URL。

二、Bootstrap表格内嵌入视频的HTML实现

在Bootstrap表格中,使用HTML5的<video>标签嵌入视频,配合Bootstrap的响应式类保证适配性。以下是完整的模板代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分析报告页面</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-4">
        <!-- 视频上传表单 -->
        <form method="POST" action="/upload" enctype="multipart/form-data" class="mb-4">
            <div class="input-group">
                <input type="file" class="form-control" name="file" accept="video/*">
                <button class="btn btn-primary" type="submit">上传视频</button>
            </div>
        </form>

        <!-- 分析报告表格 -->
        <h3>视频分析时间轴</h3>
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>视频预览</th>
                    <th>时间点</th>
                    <th>分析指标1</th>
                    <th>分析指标2</th>
                </tr>
            </thead>
            <tbody>
                <!-- 优先展示视频行 -->
                {% for video in videos %}
                <tr>
                    <td>
                        <!-- Bootstrap响应式视频容器,保持16:9比例 -->
                        <div class="ratio ratio-16x9">
                            <video id="main-video" controls class="w-100">
                                <source src="{{ url_for('uploaded_file', filename=video) }}" type="video/mp4">
                                您的浏览器不支持视频播放
                            </video>
                        </div>
                    </td>
                    <td>00:00:00</td>
                    <td>初始值</td>
                    <td>基准值</td>
                </tr>
                {% endfor %}
                <!-- 其他时间轴数据行,用data-timestamp存储对应视频秒数 -->
                <tr data-timestamp="10">
                    <td></td>
                    <td>00:00:10</td>
                    <td>峰值A</td>
                    <td>波动值X</td>
                </tr>
                <tr data-timestamp="20">
                    <td></td>
                    <td>00:00:20</td>
                    <td>峰值B</td>
                    <td>波动值Y</td>
                </tr>
                <tr data-timestamp="30">
                    <td></td>
                    <td>00:00:30</td>
                    <td>均值C</td>
                    <td>稳定值Z</td>
                </tr>
            </tbody>
        </table>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 视频与表格时间轴同步逻辑
        const video = document.getElementById('main-video');
        const timelineRows = document.querySelectorAll('tbody tr[data-timestamp]');

        // 监听视频播放时间变化
        video.addEventListener('timeupdate', () => {
            const currentSec = Math.floor(video.currentTime);
            // 移除所有高亮状态
            timelineRows.forEach(row => row.classList.remove('table-active'));
            // 找到当前时间对应的最新数据行并高亮
            const targetRow = Array.from(timelineRows).findLast(row => 
                parseInt(row.dataset.timestamp) <= currentSec
            );
            if (targetRow) {
                targetRow.classList.add('table-active');
                // 自动滚动到当前行(可选,提升体验)
                targetRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
        });
    </script>
</body>
</html>

核心细节:

  • 用ratio ratio-16x9保证视频在表格单元格内自适应显示;
  • 给数据行添加data-timestamp属性,存储对应视频的秒数,用于同步;
  • 通过timeupdate事件监听视频播放进度,动态高亮对应数据行并滚动。

三、常见问题排查

  1. 视频无法播放:

    • 确认static/uploads目录存在且视频文件已正确上传;
    • 检查视频格式(优先用MP4,兼容性最好);
    • 访问http://localhost:5000/uploads/你的视频文件名,确认能直接打开视频。
  2. 上传失败:

    • 表单必须添加enctype="multipart/form-data",否则无法上传文件;
    • 若上传大视频,需在Flask配置中添加MAX_CONTENT_LENGTH = 64 * 1024 * 1024(限制64MB)。
  3. 时间轴不同步:

    • 确保data-timestamp的值是视频对应的秒数(整数);
    • 若视频帧率高,可给timeupdate事件添加节流,避免频繁触发DOM操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:00:54