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

Django静态文件环境下视频播放列表功能异常求助

问题描述
  • 点击右侧播放列表中的视频,无法切换为主播放视频
  • 视频进度条无法拖动选择播放起始位置,也无法回退播放
  • 尝试直接使用src路径加载视频失败,推测问题与Django静态文件配置相关
相关代码

HTML代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>My Website</title>
    <link rel="icon" href="./favicon.ico" type="image/x-icon">
  </head>
<div class = "container5">
    <div class="main-video-container">
        <video  {% load static %} src ="{% static "Chapter 3.1 Exercise 1-4.mp4" %}" loop controls class="main-video"></video>
        <h3 class="main-vid-title"> Properties of Parallel Lines Exercise 1-4</h3>
    </div>

    <div class="video-list-container" > <!-- This is where we keep adding videos to our list-->
        <div class="list active">
            <video {% load static %} src="{% static "Chapter 3.1 Exercise 1-4.mp4" %}"     class="list-video"></video>
            <h3 class="list-title">Properties of Parallel Lines Exercise 5-7</h3>
        </div>
        <div class="list">
            <video {% load static %} src="{% static "Chapter 3.1 Exercise 5-7.mp4" %}" class="list-video"></video>
            <h3 class="list-title">Properties of Parallel Lines Exercise 5-7</h3>
        </div><div class="list">
            <video  {% load static %} src="{% static "Chapter 3.1 Exercise 5-7.mp4" %}" class="list-video"></video>
            <h3 class="list-title">Properties of Parallel Lines Exercise 5-7</h3>
        </div>
        <div class="list">
            <video {% load static %} src="{% static "Chapter 3.1 Exercise 5-7.mp4" %}" class="list-video"></video>
            <h3 class="list-title">Properties of Parallel Lines Exercise 5-7</h3>
        </div>
        <div class="list">
            <video {% load static %} src="{% static "Chapter 3.1 Exercise 5-7.mp4" %}" class="list-video"></video>
            <h3 class="list-title">Properties of Parallel Lines Exercise 5-7</h3>
        </div>
        <div class="list">
            <video {% load static %} src="{% static "Chapter 3.1 Exercise 5-7.mp4" %}" class="list-video"></video>
            <h3 class="list-title">Properties of Parallel Lines Exercise 5-7</h3>
        </div>
    </div>
</div>
<style>
    *{
        box-sizing: border-box;
     }
    .container5{
        max-width: 1200px;
        margin:100px auto;
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
        gap: 20px;
    }
    .container5 .main-video-container{
        flex: 1 1 700px;
        border-radius: 5px;
        box-shadow: 0 5px 15px rgba(246, 5, 5, 0.557);
        background-color: rgb(255, 119, 0);
        padding:15px
    }
    .container5 .main-video-container .main-video{
        margin-bottom: 7px;
        border-radius: 5px;
        width:100%;
    }
    .container5 .main-video-container .main-vid-title{
        font-size: 20px;
        color: brown;
    }
    .container5 .video-list-container{
        flex:1 1 350px;
        height: 485px;
        overflow-y:scroll ;
        border-radius: 5px;
        box-shadow: 0 5px 15px rgba(246, 5, 5, 0.557);
        background-color: rgb(255, 119, 0);
        padding:15px
    }
    .container5 .video-list-container::-webkit-scrollbar{
      width: 10px;
    }
    .container5 .video-list-container::-webkit-scrollbar-track{
      background-color: #fff;
      border-radius: 5px;
    }
    .container5 .video-list-container::-webkit-scrollbar-thumb{
      background-color: #c71111;
      border-radius: 5px;
    }
    .container5 .video-list-container .list{
      display: flex;
      align-items: center;
      gap:15px;
      padding:10px;
      background-color: #eee;
    }
    .container5 .video-list-container .list{
      display: flex;
      align-items: center;
      gap: 15px;
      padding: 10px;
      background-color: #eee;
      cursor: pointer;
      border-radius: 5px;
      margin-bottom: 10px;
    }
    .container5 .video-list-container .list:last-child{
        margin-bottom: 0;
    }
    .container5 .video-list-container .list.active{
        background-color: #d70f0f;
    }
    .container5 .video-list-container .list.active .list-title{
        color: #1d4736;
    }
    .container5 .video-list-container .list .list-video{
        width:100px;
        border-radius: 5px;
    }
    .container5 .video-list-container .list .list-title{
        font-size: 17px ;
        color: #444;
    }
</style>

</html>

JavaScript代码

let videoList = document.querySelectorAll('.video-list-container.list');
videoList.forEach(vid =>{
    vid.onclick = () =>{
        let src = vid.querySelector('.list-video').src;
        let title = vid.querySelector('.list-title').innerHTML;
        document.querySelector('.main-video-container .main-video').src = src;
        document.querySelector('.main-video-container .main-video').play();
        document.querySelector('.main-video-container .main-vid-title').innerHTML = title;
    };
});
问题分析与解决方案

1. 播放列表无法切换主视频的问题

问题根源

JavaScript选择器错误:document.querySelectorAll('.video-list-container.list') 会匹配同时拥有video-list-container和list类的元素,但实际列表项是video-list-container下的.list子元素,正确选择器应为.video-list-container .list。原选择器找不到目标元素,导致点击事件未绑定成功。此外,原代码未处理列表项的active类切换,点击后无视觉反馈。

修复后的JavaScript代码

// 选择所有列表项
let videoList = document.querySelectorAll('.video-list-container .list');
videoList.forEach(vid => {
    vid.onclick = () => {
        // 移除所有列表项的active类
        videoList.forEach(item => item.classList.remove('active'));
        // 给当前点击项添加active类
        vid.classList.add('active');
        
        // 获取视频地址和标题
        let src = vid.querySelector('.list-video').src;
        let title = vid.querySelector('.list-title').textContent;
        
        // 更新主视频
        const mainVideo = document.querySelector('.main-video-container .main-video');
        mainVideo.src = src;
        mainVideo.play();
        document.querySelector('.main-video-container .main-vid-title').textContent = title;
    };
});

2. 视频进度条无法拖动的问题

问题根源

Django开发服务器(runserver)默认不支持字节范围请求(Byte-Range Requests),而视频进度拖动需要浏览器发送这类请求来获取视频的部分内容。此外,静态文件配置不当也可能导致视频无法正常加载。

解决方案

方案一:开发环境自定义视频服务视图

自定义视图处理视频请求,添加Accept-Ranges响应头:

  1. 在项目的views.py中添加代码:
import os
from django.http import HttpResponse, Http404
from django.conf import settings
from django.views.static import serve

def serve_video(request, path):
    file_path = os.path.join(settings.STATIC_ROOT, path)
    if not os.path.exists(file_path):
        raise Http404("Video not found")
    
    response = serve(request, path, document_root=settings.STATIC_ROOT)
    response['Accept-Ranges'] = 'bytes'
    return response
  1. 在urls.py中添加路由:
from django.urls import path
from . import views

urlpatterns = [
    # 其他路由...
    path('videos/<path:path>', views.serve_video, name='serve_video'),
]
  1. 修改模板中的视频src:
<!-- 替换原static标签,使用自定义路由 -->
<video src="{% url 'serve_video' 'Chapter 3.1 Exercise 1-4.mp4' %}" loop controls class="main-video"></video>

方案二:生产环境使用Whitenoise(推荐)

生产环境部署时,用Whitenoise提供静态文件服务,它默认支持字节范围请求:

  1. 安装Whitenoise:pip install whitenoise
  2. 在settings.py中配置:
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # 添加该行
    # 其他中间件...
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

# 启用压缩和缓存
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

额外检查项

  • 确保视频文件编码为浏览器支持的格式(如MP4使用H.264视频编码和AAC音频编码)
  • 检查Django静态文件配置:STATICFILES_DIRS是否包含视频所在文件夹,STATIC_ROOT在生产环境是否正确收集了静态文件
  • 模板中{% load static %}只需在最顶部加载一次,无需每个video标签重复加载

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:34:51