vue+flask实现视频合成
效果如下
拖拽上传我们之前一个文章有写过
//www.jb51.net/article/206543.htm
原理就是 监听drop事件 来获取拖拽的文件列表
上传文件
通过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如下
我们上传文件后 通过falsk处理返回文件路径 拼接后获取文件地址
a标签添加download属性可以给下载的文件命名
如果你对/qwe /voi有疑惑 请看下面的配置代理说明
配置代理说明
配置代理是为了解决跨域问题 开发环境可在vue.config.js配置即可使用
生产环境需要额外配置nginx
/qwe实际上就是 http://127.0.0.1:8087/file
/voi实际上就是 http://127.0.0.1:8087/getvoi
对应我们flask中的
额外说明(如果你使用uni-app)
如果你使用uni-app 可参照文档使用api
上传文件api https://uniapp.dcloud.io/api/request/network-file"htmlcode">
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" style="width: 800px;height: 200px;border: 1px solid black;font-size: 40px;line-height: 200px" > {{ dt }} </div> <div v-for="(item, index) in fileList" :key="index" style="width: 800px;height: 200px;border: 1px solid black;font-size: 40px;position: relative;top:10px" > <p style="font-size: 20px;float: left;position: relative;left: 20pxword-wrap:break-word;word-break:normal;" > {{ item.name }} </p> <h5 style="float:right;position: absolute;top: 80px;right: 20px"> {{ item.type }} </h5> <h6 style="position: absolute;top: 80px;float: left;left: 20px"> {{ item.size | sizeType }} </h6> <button style="float: right" @click="del(index)">删除</button> </div> <!-- 此处为展示最后一个上传的文件 --> <!-- <div style="position:relative;top: 100px">--> <!-- <img v-if="isImage" :src="/UploadFiles/2021-04-02/srcs">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视频合成,vue拖拽上传
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】