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

Django中如何将浏览器录制的Blob转为MP4并保存到服务器

解决浏览器录制视频后在Django服务器保存为MP4的问题

一、前端确保录制并传输MP4格式

MediaRecorder默认编码不一定是MP4,先在前端指定兼容的MIME类型,让录制的Blob直接为MP4格式:

  1. 先验证浏览器支持性:
const mimeType = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if (!MediaRecorder.isTypeSupported(mimeType)) {
    console.error('浏览器不支持MP4录制');
    alert('当前浏览器不支持MP4格式录制,请更换Chrome或Edge');
    return;
}
  1. 修改MediaRecorder初始化代码:
    把原来的recorder = new MediaRecorder(stream)替换为:
recorder = new MediaRecorder(stream, { mimeType: mimeType });
  1. 传输时指定文件名和类型:
    构建FormData时明确Blob的类型与文件名,方便后端识别:
const videoBlob = new Blob(blobContainer, { type: mimeType });
var formdata = new FormData();
formdata.append('blobFile', videoBlob, `recording_${Date.now()}.mp4`);

二、Django后端保存MP4文件

情况1:前端已传输MP4格式

若前端确保传的是MP4,直接用Django的FileField保存即可:

  1. 确保模型配置正确:
from django.db import models

class VideoUpload(models.Model):
    name = models.CharField(max_length=100)
    video = models.FileField(upload_to='recordings/')  # 文件会存在MEDIA_ROOT/recordings目录下
    created_at = models.DateTimeField(auto_now_add=True)
  1. 优化视图(替换@csrf_exempt,改用安全的CSRF Token传递):
    先在前端fetch请求中添加CSRF Token:
// 从Cookie中获取Django默认的CSRF Token
function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

// 修改fetch请求
fetch('/upload', {
    method: 'POST',
    headers: {
        'X-CSRFToken': getCookie('csrftoken'),
    },
    body: formdata
}).then(()=>{
    alert('视频已上传');
})

然后更新视图函数:

from django.shortcuts import redirect
from django.http import HttpResponseBadRequest
from .models import VideoUpload

def upload(request):
    if request.method != 'POST':
        return HttpResponseBadRequest('仅支持POST请求')
    if 'blobFile' not in request.FILES:
        return HttpResponseBadRequest('未上传视频文件')
    
    video_file = request.FILES['blobFile']
    # 可选:验证文件类型
    if not video_file.name.endswith('.mp4') or video_file.content_type != 'video/mp4':
        return HttpResponseBadRequest('仅支持MP4格式视频')
    
    video_upload = VideoUpload()
    video_upload.video = video_file
    video_upload.name = request.user.username
    video_upload.save()
    
    # 后续给Whisper用可直接取路径:video_upload.video.path
    return redirect('/')

情况2:后端转码为MP4(兼容不支持MP4录制的浏览器)

若部分浏览器无法录制MP4,用FFmpeg在后端转码:

  1. 安装依赖:
    服务器安装FFmpeg(Ubuntu:sudo apt install ffmpeg),再安装Python库:
pip install ffmpeg-python
  1. 带转码逻辑的视图:
import os
import datetime
from django.conf import settings
from django.shortcuts import redirect
from django.http import HttpResponseBadRequest
from django.core.files import File
from .models import VideoUpload
import ffmpeg

def upload(request):
    if request.method != 'POST':
        return HttpResponseBadRequest('仅支持POST请求')
    if 'blobFile' not in request.FILES:
        return HttpResponseBadRequest('未上传视频文件')
    
    temp_file = request.FILES['blobFile']
    # 临时保存原始文件
    temp_dir = os.path.join(settings.MEDIA_ROOT, 'temp')
    os.makedirs(temp_dir, exist_ok=True)
    temp_path = os.path.join(temp_dir, temp_file.name)
    with open(temp_path, 'wb+') as f:
        for chunk in temp_file.chunks():
            f.write(chunk)
    
    # 转码为MP4
    mp4_filename = f'recording_{datetime.datetime.now().timestamp()}.mp4'
    mp4_path = os.path.join(settings.MEDIA_ROOT, 'recordings', mp4_filename)
    try:
        ffmpeg.input(temp_path).output(mp4_path, vcodec='libx264', acodec='aac').run()
    except Exception as e:
        os.remove(temp_path)
        return HttpResponseBadRequest(f'转码失败:{str(e)}')
    
    # 删除临时文件
    os.remove(temp_path)
    
    # 保存到模型
    video_upload = VideoUpload()
    with open(mp4_path, 'rb') as f:
        video_upload.video.save(mp4_filename, File(f), save=False)
    video_upload.name = request.user.username
    video_upload.save()
    
    return redirect('/')

三、给Whisper转录用的注意点

保存后的MP4文件可通过video_upload.video.path获取绝对路径,直接传给Whisper:

import whisper

model = whisper.load_model("base")
result = model.transcribe(video_upload.video.path)
print(result["text"])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:25:30