The video synthesis effect achieved by vue+flask is as follows We have written about drag and drop upload in a previous article//www.jb51.net/article/206543.htm The principle is to listen to the drop event to get the dragged file list Upload filesUpload files via axios this,.fileList is our file list let files = this.fileList; let formd = new FormData(); let i = 1; //Add upload list files.forEach(item => { formd.append(i + "", item, item.name) i++; }) formd.append("type", i) let config = { headers: { "Content-Type": "multipart/form-data" } } //Upload file request axios.post("/qwe", formd, config).then(res => { console.log(res.data) }) Flask processes filesSee the bottom for the complete code The logic is as follows: Receive files, randomly generate a folder for each synthesis request, temporarily save files, stitch videos, return file path @app.route("/file",methods=['POST']) def test(): #Get files files = request.files #Synthesis queue videoL = [] #Random string dirs = sjs() #Generate folder os.mkdir(dirs) #Save the file and add it to the synthesis queue for file in files.values(): print(file) dst = dirs + "/" + file.name + ".mp4" file.save(dst) video = VideoFileClip(dirs + "/" + file.name + ".mp4") videoL.append(video) #Splice video final = concatenate_videoclips(videoL) #File path fileName = dirs + "/" + "{}.mp4".format(sjs()) #Generate video final.to_videofile(fileName) #Destroy folder def sc(): shutil.rmtree(dirs) #Destroy the folder after 30 seconds timer = threading.Timer(30, sc) timer.start() # Return the file path return fileName Splicing to get the file pathFirst, let's look at flaskThe logic is as follows: Get the file by file name and return the file app.route("/getvoi",methods=['GET']) def getImg(): #Get the file name ss = request.args['name'] #Add the file to the returned response response = make_response( send_file(ss) #delete file def sc(): os.remove(ss) #Delete the file after 30 seconds timer = threading.Timer(30, sc) timer.start() return response Front-end acquisitionDownload via tag a <as :href="herfs" rel="external nofollow" rel="external nofollow" :download="fileName">Download</a> herfs are as follows After uploading the file, we process the returned file path through falsk and then obtain the file address Adding the download attribute to the a tag can name the downloaded file If you have any questions about /qwe /voi, please see the following proxy configuration instructions Configuration Proxy InstructionsThe purpose of configuring a proxy is to solve cross-domain issues. The development environment can be configured in vue.config.js and can be used. The production environment requires additional configuration of nginx /qwe is actually http://127.0.0.1:8087/file Additional Notes (if you use uni-app) If you use uni-app, please refer to the documentation to use the api Complete code If you don't want to copy them one by one, you can download them from Download path 1: https://download.csdn.net/download/qq_42027681/15561897 flask codemd5random.py is used to generate random stringsimport 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 service codefrom 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(): #Get files files = request.files #Synthesis queue videoL = [] #Random string dirs = sjs() #Generate folder os.mkdir(dirs) #Save the file and add it to the synthesis queue for file in files.values(): print(file) dst = dirs + "/" + file.name + ".mp4" file.save(dst) video = VideoFileClip(dirs + "/" + file.name + ".mp4") videoL.append(video) #Splice video final = concatenate_videoclips(videoL) #File path fileName = dirs + "/" + "{}.mp4".format(sjs()) #Generate video final.to_videofile(fileName) #Destroy folder def sc(): shutil.rmtree(dirs) #Destroy the folder after 30 seconds timer = threading.Timer(30, sc) timer.start() # Return the file path return fileName @app.route("/getvoi",methods=['GET']) def getImg(): #Get the file name ss = request.args['name'] #Add the file to the returned response response = make_response( send_file(ss) #delete file def sc(): os.remove(ss) #Delete the file after 30 seconds timer = threading.Timer(30, sc) timer.start() return response if __name__ == '__main__': app.run(host='0.0.0.0',port=8087) vue codeDemo file code <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)">Delete</button> </div> <!-- Here is the last uploaded file to be displayed--> <!-- <div style="position:relative;top: 100px">--> <!-- <img v-if="isImage" :src="srcs" style="width: 800px" />--> <!-- <video v-if="isVideo" controls :src="srcs" style="width: 800px"></video>--> <!-- <audio v-if="isAudio" controls :src="srcs" style="width: 800px"></audio>--> <!-- </div>--> <el-button style="position: relative;top: 50px" type="success" @click="ups()" :disabled="!isCan">Synthesis</el-button> <el-button style="position: relative;top: 50px" v-loading="loading" type="success" >. . . </el-button> <a style="position: relative;top: 50px;left: 15px;" type="success" :href="herfs" rel="external nofollow" rel="external nofollow" :download="fileName"><el-button :disabled="isCans"><span style="color: black">Download</span></el-button></a> <div style="position: relative;top: 100px">File download validity time {{times}}s</div> </div> </template> <script> import axios from "axios"; export default { name: "trs", data() { return { dt: "", //Upload reminder "Drag here to upload the file" or "Upload completed, you can continue uploading" fileList: [], // file list loading: false, srcs: "", //Picture/video/audio base64 isImage: false, //Is it an image? isAudio: false, //Is it an audio? isVideo: false, //Is it a video? isCan: true, //Can it be synthesized? isCans: true, //Can it be downloaded? herfs: "", //Download address fileName: "", //File name times: 25 //Download validity period }; }, filters: //Format file size 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); //Global monitoring when there is a file drag reminder in the page drag here document.addEventListener("dragover", function() { console.log(111); vm.dt = "Drag here to upload files"; console.log(vm.dt); }); }, methods: { //Display files are mainly of three types: picture/video/audio 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("Not a picture/video/audio"); } vm.srcs = reader.result; // this.$nextTick(()=>{ // // }) }; }, //Globally monitor the trigger event of drop to cancel the drop pop-up window display resource testfunc(event) { alert("dragdrop!"); //Cancel the drop pop-up window display resource event.stopPropagation(); event.preventDefault(); }, del(index) { this.fileList.splice(index, 1); if (this.fileList.length === 0) { this.dt = ""; } }, //Monitor the div upload box and display "Drag here to upload the file" when a file is dragged tts(e) { console.log(e); this.dt = "Drag here to upload the file"; }, //Listen for the div upload box drop event to trigger ttrs(e) { console.log(e); console.log(e.dataTransfer.files); //Get files let datas = e.dataTransfer.files; //Cancel the drop pop-up window display resource e.stopPropagation(); e.preventDefault(); datas.forEach(item => { if(item.type=="video/mp4"){ this.fileList.push(item); } }); //Read files. If you don't want to display pictures/videos/audios, you can ignore this.readFile(this.fileList[this.fileList.length - 1]); this.dt = "Upload completed, you can continue uploading"; }, //Upload files to the server ups(){ if(this.fileList.length==0){ this.$message('The file list is empty'); return ; } this.loading = true; this.isCan = false; this.isCans = true; let files = this.fileList; let formd = new FormData(); let i = 1; //Add upload list files.forEach(item=>{ formd.append(i+"",item,item.name) i++; }) formd.append("type",i) let config={ headers:{"Content-Type":"multipart/form-data"} } //Upload file request axios.post("/qwe",formd,config).then(res=>{ console.log(res.data) this.loading = false //Synthesized download path this.herfs = "/voi?name="+res.data this.fileName = res.data.split('/')[1] //Synthesis is prohibited this.isCan = false this.isCans = false //Set the download validity period. After the time is up, the download cannot be completed but the synthesis can continue. 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": "" } } } } }; This is the end of this article about vue+flask to realize video synthesis function (drag and drop upload). For more related vue video synthesis content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: MySQL 5.7.18 installation tutorial and problem summary
>>: Problems and solutions when installing MySQL8.0.13 on Win10 system
Cleanly uninstall MySQL. Personally tested, this ...
The form elements with visibility=hidden and displ...
Create a new server.js yarn init -y yarn add expr...
Today's web designs tend to display very larg...
Table of contents 3 ways to deploy projects with ...
JS implements a hover drop-down menu. This is a s...
The method of obtaining the position of the point...
Table of contents 1. Introduce cases 2. View the ...
Introduction The default source of Ubuntu is not ...
Declaring variables Setting Global Variables set ...
LEMP (Linux + Nginx + MySQL + PHP) is basically a...
The image can be easily pushed directly to the Do...
Today I sent a small tool for Ubuntu to a custome...
Today a client wants to run an advertisement, and ...
Table of contents Code: Replenish: Summarize Requ...