Loading

django视频文件传输成功样例

from django.http import HttpResponse, JsonResponse, StreamingHttpResponse,FileResponse
from utils.to_video import image_to_video as convert_to_video
import tempfile
import os
import subprocess

def image_to_video(request):
    if request.method == "POST":
        # 获取图片
        input_image = request.FILES.get("input_image")
        # 未接到图片
        if not input_image:
            return JsonResponse({
                "status": False,
                "message": "图片接收失败",
            })

        try:
            # 使用临时文件处理
            # with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as tmp_img, \
            #     tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as tmp_video:
            # with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as tmp_video:
                # # 保存上传的图片到临时文件
                # for chunk in input_image.chunks():
                #     tmp_img.write(chunk)
                # # 将最后一次缓存内容全部写入文件
                # tmp_img.flush()

                # 转换为视频
                video_path = "media/video/test2.mp4"
                convert_to_video(input_image.temporary_file_path(), video_path)
                # convert_to_video(r"D:\d_pycharm_program\dvi_video\media\image\test.jpg", "media/video/test.mp4")
                
                # 在返回响应之前播放视频(能播)
                # try:
                #     os.startfile(r"D:\d_pycharm_program\dvi_video\media\video\test.mp4")
                # except Exception as e:
                #     print(f"播放视频失败: {str(e)}")

                # 确保文件存在
                if not os.path.exists(video_path):
                    raise Exception("视频文件生成失败")

                # 设置响应
                response = FileResponse(
                    open(video_path, 'rb'),
                    # content_type='video/mp4',
                    # as_attachment=True,
                    # filename="test.mp4"
                )

                # 设置CORS头
                response['Content-Type'] = "application/octet-stream"
                response['Content-Disposition'] = 'attachment; filename="{}"'.format(os.path.basename("media/video/test.mp4"))

                return response
                
        except Exception as e:
            return JsonResponse({
                "status": False,
                "message": f"处理失败: {str(e)}"
            })

    return JsonResponse({
        "status": False, 
        "message": "只支持POST请求"
    })

前端

submitBtn.onclick = async (e) => {
    // 禁用提交按钮
    submitBtn.disabled = true

    // 创建 FormData 对象来处理文件上传
    const formData = new FormData()
    formData.append('input_image', imageInput.files[0])

    // 发送请求
    fetch('http://127.0.0.1:8000/image_to_video/', {
        method: 'POST',
        body: formData
    }).then(response => {
        if (response.ok) {
            // 获取文件名,添加错误处理
            console.log(1)
            const contentDisposition = response.headers.get('Content-Disposition');
            console.log(contentDisposition)
            let filename = 'output.mp4';  // 默认文件名
            
            if (contentDisposition) {
                try {
                    filename = contentDisposition.split('filename=')[1].replace(/"/g, '');
                } catch (e) {
                    console.warn('无法解析文件名,使用默认文件名');
                }
            }

            // 下载视频
            response.blob().then(blob => {
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);
            });
        } else {
            throw new Error('转换失败');
        }
    }).catch(error => {
        console.error('错误:', error);
        alert('视频转换失败');
    }).finally(() => {
        submitBtn.disabled = false
    })
}

参考博客:https://blog.csdn.net/inthat/article/details/130470032
非常感谢该播主

response = FileResponse(
                    open(video_path, 'rb'),
                    # content_type='video/mp4',
                    # as_attachment=True,
                    # filename="test.mp4"
                )

                # 设置CORS头
                response['Content-Type'] = "application/octet-stream"
                response['Content-Disposition'] = 'attachment; filename="{}"'.format(os.path.basename("media/video/test.mp4"))

主要是这几句,核心

posted @ 2025-03-18 16:57  一只大学生  阅读(45)  评论(0)    收藏  举报