JavaScript与Django集成:实现前端录制视频文件到后端存储的教程

聖光之護
发布: 2025-08-30 23:13:01
原创
789人浏览过

JavaScript与Django集成:实现前端录制视频文件到后端存储的教程

本教程详细指导如何在JavaScript前端录制视频后,通过Fetch API将其上传至Django后端进行文件系统存储和数据库关联。文章涵盖了前端视频数据处理、CSRF令牌管理以及Django视图层接收文件并保存的完整流程,旨在帮助开发者实现视频录制与持久化存储的无缝集成。

在现代web应用中,用户生成内容的场景日益增多,其中视频录制与上传是常见需求。本教程将深入探讨如何将前端javascript录制的视频文件,通过异步请求(fetch api)安全有效地传输至django后端,实现文件的持久化存储于文件系统,并将其关联信息记录到数据库中。与传统表单提交方式不同,我们采用更灵活的api驱动方法,优化用户体验并提升开发效率。

1. 前端视频录制与数据封装

首先,我们依赖JavaScript的MediaDevices API(getUserMedia)进行视频流获取,并使用MediaRecorder API进行录制。录制完成后,视频数据以Blob(二进制大对象)的形式存储在recordedBlobs数组中。为了将此Blob发送到服务器,我们需要将其封装为FormData对象。

1.1 录制流程回顾

前端HTML结构包含video元素用于显示摄像头预览和录制回放,以及控制按钮(开始、录制、播放、下载)。JavaScript代码负责:

卡拉OK视频制作
卡拉OK视频制作

卡拉OK视频制作,在几分钟内制作出你的卡拉OK视频

卡拉OK视频制作 178
查看详情 卡拉OK视频制作
  • 通过navigator.mediaDevices.getUserMedia获取摄像头和麦克风权限及流。
  • 实例化MediaRecorder对象,并监听ondataavailable事件收集视频数据块。
  • 在stopRecording时,recordedBlobs数组包含了完整的视频数据。

1.2 封装视频数据为FormData

当用户点击“下载”按钮时,除了传统的客户端下载逻辑外,我们还需要触发上传至后端的动作。核心在于将recordedBlobs合并成一个Blob,然后将其转换为File对象并添加到FormData中。

// ... (保留原有的JavaScript录制逻辑,例如mediaRecorder、recordedBlobs等)

const errorMsgElement = document.querySelector('span#errorMsg');
const recordedVideo = document.querySelector('video#recorded');
const recordButton = document.querySelector('button#record');
const playButton = document.querySelector('button#play');
const downloadButton = document.querySelector('button#download');

// 获取CSRF Token的辅助函数
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

// 上传函数:负责将FormData发送到Django后端
async function upload(formData) {
  try {
    // 这里的URL '/video-app' 需与Django的urls.py配置保持一致
    const response = await fetch("/video-app", {
      method: "POST",
      headers: {
        "X-CSRFToken": getCookie('csrftoken'), // 附带CSRF Token,确保Django安全认证
      },
      body: formData, // 发送FormData对象,Fetch API会自动设置Content-Type为multipart/form-data
    });
    const result = await response.json(); // 解析后端返回的JSON响应
    console.log("上传响应:", result);
    // 根据后端返回的result处理,例如显示成功或失败消息
    if (result.error_code === 0) {
        alert('视频上传成功!');
    } else {
        alert('视频上传失败: ' + result.message);
    }
  } catch (error) {
    console.error("上传错误:", error);
    alert('视频上传过程中发生错误!');
  }
}

// 修改下载按钮的点击事件,增加上传逻辑
downloadButton.addEventListener('click', () => {
  // 将录制的Blob数据合并为一个完整的MP4视频Blob
  const blob = new Blob(recordedBlobs, {type: 'video/mp4'});

  // 1. 上传到服务器
  const formData = new FormData();
  // 将Blob转换为File对象,命名为'my-interview.mp4',并作为'video'字段添加到FormData
  formData.append("video", new File([blob], 'my-interview.mp4'));
  upload(formData); // 调用上传函数

  // 2. 客户端下载(如果不需要客户端下载,可以移除以下代码)
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = 'w3-coder-recorder-test.mp4'; // 客户端下载的文件名
  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }, 100);
});

// ... (保留原有的start/stop Recording, play, handleSuccess, init等函数)
// 确保MediaRecorder的ondataavailable和onstop事件处理逻辑正确
function handleDataAvailable(event) {
  console.log('handleDataAvailable', event);
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
  }
}

function startRecording() {
  recordedBlobs = [];
  let options = {mimeType: 'video/webm;codecs=vp9,opus'};
  try {
    mediaRecorder = new MediaRecorder(window.stream, options);
  } catch (e) {
    console.error('Exception while creating MediaRecorder:', e);
    errorMsgElement.innerHTML = `Exception while creating MediaRecorder: ${JSON.stringify(e)}`;
    return;
  }
  recordButton.textContent = 'Stop Recording';
  playButton.disabled = true;
  downloadButton.disabled = true;
  mediaRecorder.onstop = (event) => {
    console.log('Recorder stopped: ', event);
    console.log('Recorded Blobs: ', recordedBlobs);
  };
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.start();
}

function stopRecording() {
  mediaRecorder.stop();
  recordButton.textContent = 'Record'; // 停止后将按钮文本改回“Record”
  playButton.disabled = false;
  downloadButton.disabled = false;
}
登录后复制

以上就是JavaScript与Django集成:实现前端录制视频文件到后端存储的教程的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号