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
This article example shares the specific code of ...
The utf8mb4 encoding is a superset of the utf8 en...
Table of contents 1.Json string 1.1Json Syntax 1....
Table label composition The table in HTML is comp...
As a required course for front-end developers, CS...
Docker takes up a lot of space. Whenever we run c...
This article example shares the specific code for...
Google's goal with Flutter has always been to...
Table of contents Vue CLI builds a Vue project Vu...
Copy code The code is as follows: <span style=...
The database enables slow query logs Modify the c...
Table of contents What is an index? Leftmost pref...
Result: The main part is to implement the code lo...
The fastest way to experience the latest version ...
In this article, I will explain the relevant cont...