如何用JavaScript将视频Blob通过Django表单传递给Django视图
核心问题
如何使用JavaScript将视频数据Blob通过Django表单传递至Django视图?
背景
我正在开发摄像头视频录制功能,目前已成功实现通过JavaScript获取用户摄像头和麦克风流、录制并转换为Blob,还可将Blob转为文件。但我不想让用户接触视频文件,只需将视频数据发送至后端,且出于安全限制无法通过代码为<input type='file'>元素赋值,因此希望直接发送二进制数据。
已尝试方案及结果
- 尝试在Django表单中使用FileField,但受限于Web安全规则无法生效,让用户自行下载再上传不符合项目要求。
- 尝试使用JSONField通过JSON格式提交二进制数据,但无法将Blob正确转为JSON格式,JSON中视频Blob字段值为空字符串、
undefined或"data:"。
代码示例
JavaScript
// MediaRecorder用这个函数把数据传给"recordedChunks" const handleDataAvailable = function(event) { if (event.data.size > 0) { recordedChunks.push(event.data); } else { // … } }
问题出在停止录制、生成Blob并传递至input元素的步骤,以下是不同尝试的函数及base64data的输出结果:
console.log(base64data); = undefined
const stopCapture = function() { mediaRecorder.stop(); const blob = new Blob(recordedChunks, {type: "video/webm",}); // 将Blob转为base64再转成JSON格式随表单提交 const reader = new FileReader(); reader.onload = function () { const base64data = reader.result.split(',')[1]; console.log(base64data); const jsonData = JSON.stringify({ videoBlob: base64data }); // 把base64编码的Blob设置为input元素的值 jsonInput.value = jsonData; }; reader.readAsDataURL(blob); }
console.log(base64data); = data:
将const base64data = reader.result.split(',')[1];改为const base64data = reader.result;。
console.log(base64data); = 空字符串
//...Blob创建完成后 // 将Blob转为base64再转成JSON格式随表单提交 const reader = new FileReader(); reader.onload = function () { const arrayBuffer = reader.result; // 将ArrayBuffer转为base64 const base64data = arrayBufferToBase64(arrayBuffer); // 创建包含base64编码Blob数据的JSON字符串 const jsonData = JSON.stringify({ videoBlob: base64data }); // 把JSON字符串设置为隐藏input的值 blobInput.value = jsonData; }; reader.readAsArrayBuffer(blob); } // ArrayBuffer转base64的函数 function arrayBufferToBase64(arrayBuffer) { const uint8Array = new Uint8Array(arrayBuffer); const binaryString = uint8Array.reduce((acc, byte) => acc + String.fromCharCode(byte), ''); return btoa(binaryString); }
其他思路
- 或许不使用Django表单,直接通过JavaScript的
formData()和fetch()提交至Django独立视图,但希望保留Django表单的内置安全性。 - 或许在转换为Blob前就将数据发送至Django后端独立视图?
Django表单及视图代码
附上相关代码,以便获取整体流程的建议,最终目标是将用户录制的视频发送至第三方存储服务。
forms.py
from django import forms class VidFileUploadForm(forms.Form): vidBlob = forms.JSONField(widget=forms.HiddenInput) name = forms.CharField(required=True) descrip = forms.CharField(required=True)
views.py
from django.urls import reverse_lazy from django.views.generic import FormMixin, TemplateView, ProcessFormView class VidDemoTwoView(FormMixin, TemplateView, ProcessFormView): """实验性视频录制视图类""" template_name = 'evaluations/vid_demo2.html' form_class = VidFileUploadForm success_url = reverse_lazy('view-vid-demo') def form_valid(self, form): vidBlob = form.cleaned_data['vidBlob'] name = form.cleaned_data['name'] description = form.cleaned_data['descrip'] # 将视频Blob转为视频文件并上传至第三方存储服务的逻辑 return super().form_valid(form)
内容的提问来源于stack exchange,提问作者DevinG
相关产品推荐
相关产品推荐

