weixin_45526111 2025-04-18 16:59 采纳率: 0%
浏览 14
已结题

视频不能拖动进度条django+mysql+模板

我想做一个公司内部学习平台,能播放视频,记录学员学习情况,用的是django+mysql+模板这种形式,现在的问题是,视频能播放但是不能拖动进度条,再次进入不能记录上次观看位置。代码如下,学习资料app里的视图函数是material_video_detail,记录app里的相关联函数是:save_video_progress和get_video_progress。网页代码如下,有没有朋友能帮忙解答一下
课程视图层:

@login_required
def material_video_detail(request,material_id):
    # 获取资料详情并处理视频播放
    material = get_object_or_404(LearningMaterial, pk=material_id)
    record, created = LearningRecord.objects.get_or_create(
        user=request.user, material=material, defaults={'last_position': 0, 'duration': 0})

    return render(request, 'courses/material_video_detail.html', locals())

记录视图层的2个函数:


@login_required
@require_http_methods(["POST"])
def save_video_progress(request, material_id):
    material = get_object_or_404(LearningMaterial, id=material_id)
    current_time = float(request.POST.get('current_time', 0))
    duration = float(request.POST.get('duration', 0))

    # 创建或更新记录
    record, _ = LearningRecord.objects.update_or_create(
        user=request.user,
        material=material,
        defaults={
            'last_position': current_time,
            # 'progress': round((current_time / duration) * 100) if duration else 0,
            'duration':duration
        }
    )
    record.update_progress(current_time,duration)
    if record.is_completed:
        record.earned_points=material.points
    record.save()
    return JsonResponse({'status': 'success'})


@login_required
def get_video_progress(request, material_id):
    material = get_object_or_404(LearningMaterial, id=material_id)
    record = LearningRecord.objects.filter(
        user=request.user,
        material=material
    ).first()
    print(record.last_position)
    return JsonResponse({
        'last_position': record.last_position if record else 0,
        'progress': record.progress if record else 0
    })

视频播放详细页:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="ratio ratio-16x9">
    <video controls class="w-100" id="videoPlayer">
        <source src="{{ material.file.url }}"
                type="video/mp4">
        您的浏览器不支持视频播放
    </video>
</div>
<!-- material_video_detail.html -->
<script>
document.addEventListener('DOMContentLoaded', () => {
    const video = document.getElementById('videoPlayer');
    const materialId = {{ material.id }};
    let lastSaveTime = 0;
    let hasSetInitialTime = false;

    // 1. 优先从接口获取进度
    fetch(`/records/get_progress/${materialId}/`)
        .then(response => {
            if (!response.ok) throw new Error('Network error');
            return response.json();
        })
        .then(data => {
            if (data.last_position > 0) {
                video.currentTime = data.last_position;
                hasSetInitialTime = true;
            }
        })
        .catch(error => console.error('加载进度失败:', error));

    // 2. 元数据加载后的备用设置
    video.addEventListener('loadedmetadata', () => {
        if (!hasSetInitialTime) {
            const templatePosition = {{ record.last_position|default:0 }};
            video.currentTime = templatePosition;
        }
        // 确保视频可拖动
        video.removeAttribute('controlslist');
    });

    // 3. 保存进度逻辑(保持不变)
    const saveProgress = () => {
        if(video.duration > 0 && video.readyState >= 2) {
            const now = Date.now();
            if(now - lastSaveTime > 5000) {
                const formData = new FormData();
                formData.append('current_time', video.currentTime);
                formData.append('duration', video.duration);

                fetch(`/records/progress/${materialId}/`, {
                    method: 'POST',
                    body: formData,
                    headers: {
                        'X-CSRFToken': '{{ csrf_token }}'
                    }
                })
                .catch(error => console.error('保存失败:', error));

                lastSaveTime = now;
            }
        }
    };

    video.addEventListener('timeupdate', saveProgress);
    video.addEventListener('seeked', saveProgress);
    video.addEventListener('pause', saveProgress);
    window.addEventListener('beforeunload', saveProgress);
});
</script>
</body>
</html>


  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2025-04-18 16:59
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    问题解答

    你遇到的问题是,使用 Django+MySQL+模板创建的学习平台中,视频播放器不能拖动进度条,并且不能记录上次观看位置。

    根据你提供的代码,学习资料ap,可能是使用了 HTML5 的 video 标签来播放视频。为了解决这个问题,我们需要在视频播放器中添加进度条的拖动功能,并记录上次观看位置。

    以下是一些可能的解决方案:

    1. 使用 JavaScript 库来实现进度条的拖动功能,例如 jQuery 的 slider 插件。
    2. 使用 HTML5 的 seek 方法来记录上次观看位置,并在下次播放时恢复到上次观看位置。
    3. 使用 Django 的 session 机制来记录上次观看位置,并在下次播放时恢复到上次观看位置。

    以下是一个简单的示例代码,使用 JavaScript 和 HTML5 的 seek 方法来实现进度条的拖动功能和记录上次观看位置:

    // 获取视频播放器的 DOM 对象
    var video = document.getElementById('video');
    
    // 添加进度条的拖动事件
    video.addEventListener('timeupdate', function() {
      var progressBar = document.getElementById('progress-bar');
      progressBar.value = video.currentTime / video.duration;
    });
    
    // 添加进度条的点击事件
    progressBar.addEventListener('input', function() {
      video.currentTime = progressBar.value * video.duration;
    });
    
    // 记录上次观看位置
    video.addEventListener('ended', function() {
      localStorage.setItem('last-seek', video.currentTime);
    });
    
    // 恢复上次观看位置
    video.addEventListener('play', function() {
      var lastSeek = localStorage.getItem('last-seek');
      if (lastSeek) {
        video.currentTime = lastSeek;
      }
    });
    

    这个示例代码中,我们使用 JavaScript 来获取视频播放器的 DOM 对象,并添加进度条的拖动事件和点击事件。我们还使用 localStorage 机制来记录上次观看位置,并在下次播放时恢复到上次观看位置。

    请注意,这只是一个简单的示例代码,你可能需要根据你的实际需求进行修改和调整。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月27日
  • 创建了问题 4月18日