温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在vue中使用flask实现一个视频合成功能

发布时间:2021-03-05 14:51:35 来源:亿速云 阅读:312 作者:Leah 栏目:开发技术

这篇文章给大家介绍怎么在vue中使用flask实现一个视频合成功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

vue是什么软件

Vue是一套用于构建用户界面的渐进式JavaScript框架,Vue与其它大型框架的区别是,使用Vue可以自底向上逐层应用,其核心库只关注视图层,方便与第三方库和项目整合,且使用Vue可以采用单文件组件和Vue生态系统支持的库开发复杂的单页应用。

原理:监听drop事件 来获取拖拽的文件列表

怎么在vue中使用flask实现一个视频合成功能
怎么在vue中使用flask实现一个视频合成功能

上传文件

通过axios 上传文件

this,.fileList就是我们的文件列表

let files = this.fileList; let formd = new FormData(); let i = 1; //添加上传列表 files.forEach(item => {	formd.append(i + "", item, item.name)	i++; }) formd.append("type", i) let config = {	headers: {	"Content-Type": "multipart/form-data"	} } //上传文件请求 axios.post("/qwe", formd, config).then(res => {	console.log(res.data) })

flask处理文件

完整代码见最底部

逻辑如下
接收文件
为每次合成请求随机生成一个文件夹 临时保存文件
拼接视频
返回文件路径

@app.route("/file",methods=['POST']) def test():  #获取文件  files = request.files  #合成队列  videoL = []  #随机字符串  dirs = sjs()  #生成文件夹  os.mkdir(dirs)  #保存文件并添加至合成队列  for file in files.values():   print(file)   dst = dirs + "/" + file.name + ".mp4"   file.save(dst)   video = VideoFileClip(dirs + "/" + file.name + ".mp4")   videoL.append(video)    #拼接视频  final = concatenate_videoclips(videoL)  #文件路径  fileName = dirs + "/" +"{}.mp4".format(sjs())  #生成视频  final.to_videofile(fileName)    #销毁文件夹  def sc():   shutil.rmtree(dirs)    #30秒后销毁文件夹  timer = threading.Timer(30, sc)  timer.start()  # 返回文件路径  return fileName

拼接获取文件路径

首先我们看flask

逻辑如下
通过文件名 获取文件 返回文件

app.route("/getvoi",methods=['GET']) def getImg():  #获取文件名  ss = request.args['name']  #文件加至返回响应  response = make_response(   send_file(ss))  #删除文件  def sc():   os.remove(ss)    #30秒后删除文件  timer = threading.Timer(30, sc)  timer.start()    return response

前端获取

通过a标签下载

<a s :href="herfs" rel="external nofollow" rel="external nofollow" :download="fileName">下载</a>

herfs如下

怎么在vue中使用flask实现一个视频合成功能

我们上传文件后 通过falsk处理返回文件路径 拼接后获取文件地址

a标签添加download属性可以给下载的文件命名

如果你对/qwe /voi有疑惑 请看下面的配置代理说明

配置代理说明

配置代理是为了解决跨域问题 开发环境可在vue.config.js配置即可使用
生产环境需要额外配置nginx

怎么在vue中使用flask实现一个视频合成功能

/qwe实际上就是 http://127.0.0.1:8087/file
/voi实际上就是 http://127.0.0.1:8087/getvoi
对应我们flask中的

怎么在vue中使用flask实现一个视频合成功能

额外说明(如果你使用uni-app)

如果你使用uni-app 可参照文档使用api
上传文件api https://uniapp.dcloud.io/api/request/network-file?id=uploadfile
下载文件api https://uniapp.dcloud.io/api/request/network-file?id=downloadfile
或者直接使用别人封装好的 插件毕竟比较方便

完整代码

如果你不想一个一个复制可以去下载
下载途径1: https://download.csdn.net/download/qq_42027681/15561897
下载途径2:https://github.com/dmhsq/vue-flask-videoSynthesis

flask代码

md5random.py 用于随机字符串生成
import random import hashlib def sjs():  a = random.randint(0, 100)  a = "a" + str(a);  b = random.randint(100, 10000);  b = "b" + str(b);  c = hashlib.md5(a.encode(encoding='UTF-8')).hexdigest() + hashlib.md5(b.encode(encoding='UTF-8')).hexdigest();  c = "c" + str(c);  d = random.randint(10, 100);  d = "d" + str(d);  e = hashlib.md5(c.encode(encoding='UTF-8')).hexdigest() + hashlib.md5(d.encode(encoding='UTF-8')).hexdigest();  e = hashlib.md5(e.encode(encoding='UTF-8')).hexdigest()  return e;
app_service.py 服务代码
from flask import Flask,request,send_file,make_response import os,json,threading,shutil from moviepy.editor import * from md5random import sjs app = Flask(__name__) @app.route("/file",methods=['POST']) def test():  #获取文件  files = request.files  #合成队列  videoL = []  #随机字符串  dirs = sjs()  #生成文件夹  os.mkdir(dirs)  #保存文件并添加至合成队列  for file in files.values():   print(file)   dst = dirs + "/" + file.name + ".mp4"   file.save(dst)   video = VideoFileClip(dirs + "/" + file.name + ".mp4")   videoL.append(video)  #拼接视频  final = concatenate_videoclips(videoL)  #文件路径  fileName = dirs + "/" +"{}.mp4".format(sjs())  #生成视频  final.to_videofile(fileName)  #销毁文件夹  def sc():   shutil.rmtree(dirs)  #30秒后销毁文件夹  timer = threading.Timer(30, sc)  timer.start()  # 返回文件路径  return fileName @app.route("/getvoi",methods=['GET']) def getImg():  #获取文件名  ss = request.args['name']  #文件加至返回响应  response = make_response(   send_file(ss))  #删除文件  def sc():   os.remove(ss)  #30秒后删除文件  timer = threading.Timer(30, sc)  timer.start()  return response if __name__ == '__main__':  app.run(host='0.0.0.0',port=8087)

vue代码

演示文件代码

<template>  <div>  <div   v-on:dragover="tts"   v-on:drop="ttrs"     >   {{ dt }}  </div>  <div   v-for="(item, index) in fileList"   :key="index"     >   <p      >   {{ item.name }}   </p>   <h6 >   {{ item.type }}   </h6>   <h7 >   {{ item.size | sizeType }}   </h7>   <button  @click="del(index)">删除</button>  </div>  <!-- 此处为展示最后一个上传的文件 --> <!-- <div >--> <!--  <img v-if="isImage" :src="srcs"  />--> <!--  <video v-if="isVideo" controls :src="srcs" ></video>--> <!--  <audio v-if="isAudio" controls :src="srcs" ></audio>--> <!-- </div>-->  <el-button  type="success" @click="ups()" :disabled="!isCan">合成</el-button>  <el-button  v-loading="loading" type="success" >。。。</el-button>  <a  type="success" :href="herfs" rel="external nofollow" rel="external nofollow" :download="fileName"><el-button :disabled="isCans"><span >下载</span></el-button></a>  <div >文件下载有效时间{{times}}s</div>  </div> </template> <script> import axios from "axios"; export default {  name: "trs",  data() {  return {   dt: "",//上传提醒 "拖动到此处上传文件“或者"上传完成,可继续上传"   fileList: [],//文件列表   loading:false,   srcs: "",//图片/视频/音频 base64   isImage: false,//是否是图片   isAudio: false,//是否是音频   isVideo: false,//是否是视频   isCan: true,//是否能合成   isCans:true,//是否能下载   herfs: "",//下载地址   fileName: "",//文件名   times: 25//下载有效时间  };  },  filters: {  //格式化文件大小  sizeType(val) {   let kbs = val / 1024;   let mbs = 0;   let gbs = 0;   if (kbs >= 1024) {   mbs = kbs / 1024;   }   if (mbs >= 1024) {   gbs = mbs / 1024;   return gbs.toFixed(2) + "GB";   } else if (mbs >= 1) {   return mbs.toFixed(2) + "MB";   } else {   return kbs.toFixed(2) + "KB";   }  }  },  mounted() {  let vm = this;  window.addEventListener("dragdrop", this.testfunc, false);  //全局监听 当页面内有文件拖动 提醒拖动到此处  document.addEventListener("dragover", function() {   console.log(111);   vm.dt = "拖动到此处上传文件";   console.log(vm.dt);  });  },  methods: {  //展示文件 主要为三个类型 图片/视频/音频  readFile(file) {   let vm = this;   let reader = new FileReader();   reader.readAsDataURL(file);   reader.onload = function() {   let type = file.type.substr(0, 5);   if (type == "image") {    vm.isImage = true;    vm.isAudio = false;    vm.isVideo = false;   } else if (type == "audio") {    vm.isImage = false;    vm.isAudio = true;    vm.isVideo = false;   } else if (type == "video") {    vm.isImage = false;    vm.isAudio = false;    vm.isVideo = true;   } else {    alert("不是图片/视频/音频");   }   vm.srcs = reader.result;   // this.$nextTick(()=>{   //   // })   };  },  //全局监听drop的触发事件 取消drop弹窗显示资源  testfunc(event) {   alert("dragdrop!");   //取消drop弹窗显示资源   event.stopPropagation();   event.preventDefault();  },  del(index) {   this.fileList.splice(index, 1);   if (this.fileList.length === 0) {   this.dt = "";   }  },  //监听div上传框 当有文件拖动时 显示"拖动到此处上传文件"  tts(e) {   console.log(e);   this.dt = "拖动到此处上传文件";  },  //监听div上传框 drop事件触发  ttrs(e) {   console.log(e);   console.log(e.dataTransfer.files);   //获取文件   let datas = e.dataTransfer.files;   //取消drop弹窗显示资源   e.stopPropagation();   e.preventDefault();   datas.forEach(item => {   if(item.type=="video/mp4"){    this.fileList.push(item);   }   });   //读取文件 如果不想展示图片/视频/音频可忽略   this.readFile(this.fileList[this.fileList.length - 1]);   this.dt = "上传完成,可继续上传";  },  //上传文件到服务器  ups(){   if(this.fileList.length==0){   this.$message('文件列表为空');   return ;   }   this.loading = true;   this.isCan = false;   this.isCans = true;   let files = this.fileList;   let formd = new FormData();   let i = 1;   //添加上传列表   files.forEach(item=>{   formd.append(i+"",item,item.name)   i++;   })   formd.append("type",i)   let config={   headers:{"Content-Type":"multipart/form-data"}   }   //上传文件请求   axios.post("/qwe",formd,config).then(res=>{   console.log(res.data)   this.loading = false   //合成下载路径   this.herfs = "/voi?name="+res.data   this.fileName = res.data.split('/')[1]   //禁止合成   this.isCan = false   this.isCans = false   //设置下载有效时间 时间到后无法下载但可以继续合成   let timer = setInterval(()=>{    this.times--;   },1000)   this.setCans(timer)   })  },  setCans(timer){   setTimeout(()=>{   this.isCans = true   this.isCan = true   this.fileName =""   clearInterval(timer)   this.times = 25   },25000)  }  } }; </script> <style scoped></style>

vue.config.js

module.exports = {  devServer: {  // assetsSubDirectory: 'static',  // assetsPublicPath: '/',  proxy: {   "/qwe": {   target: "http://127.0.0.1:8087/file",   changeOrigin: true,   pathRewrite: {    "^/qwe": ""   }   },   "/voi": {   target: "http://127.0.0.1:8087/getvoi",   changeOrigin: true,   pathRewrite: {    "^/voi": ""   }   }  }  } };

关于怎么在vue中使用flask实现一个视频合成功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI