vue+flashkはビデオ合成機能(ドラッグアップ)を実現します。


vue+flashkはビデオ合成を実現します。
効果は以下の通りです
在这里插入图片描述
前の文章をアップロードしました。書いたことがあります。
//www.jb 51.net/articale/206543.httm
ドラフトイベントを監聴してドラッグしたファイルリストを取得するのが原理です。
在这里插入图片描述
在这里插入图片描述
ファイルをアップロード
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)
})
flashk処理ファイル
完全コードは一番下の方にあります。
ロジックは以下の通りです
受信ファイル
合成要求ごとにランダムにフォルダを作成してファイルを一時保存します。
動画リスト
ファイルのパスを返します

@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
ファイルのパスを取得します。
まずflashkを見ます
ロジックは以下の通りです
ファイル名でファイルを取得してファイルに戻ります。

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>
hefsは以下の通りです
在这里插入图片描述
私たちはファイルをアップロードして、falsk処理でファイルのパスをスティッチングしてファイルの住所を取得します。
aタグにdownload属性を追加すると、ダウンロードしたファイルの名前が付けられます。
もしあなたが/qwe/voiに疑問があるなら、下の配置代理説明を見てください。
プロファイルの説明
配置エージェントはドメインをまたぐ問題を解決するために開発環境をvue.co.nfig.jsで設定してもいいです。
生産環境には別途の構成が必要です。
在这里插入图片描述
//qwe実はhttp://127.0.0.1:8087/file
/voiは実はhttp://127.0.0.1:8087/getvoi
私たちflashkの中の対応
在这里插入图片描述
追加説明(uni-apを使うなら)
uni-appを使用すれば、ドキュメントを参照してapiを使用できます。
ファイルをアップロードするhttps://uniapp.dcloud.io/api/request/network-file?id=uploadfile
ファイルをダウンロードhttps://uniapp.dcloud.io/api/request/network-file?id=downloadfile
他の人が直接パッケージしたプラグインを使うと便利です。
完全コード
コピーしたくないなら、ダウンロードしてもいいです。
ダウンロードルート1:https://download.csdn.net/download/qq_42027681/155561897
ダウンロード経路2:https://github.com/dmhsq/vue-flask-videoSynthesis
flashkコード
md 5 randowm.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;
ap_サービスコード

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="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">  </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">  </span></el-button></a>
 <div style="position: relative;top: 100px">        {{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.com fig.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+flashについてビデオ合成機能(ドラッグアップロード)を実現する記事を紹介します。vueに関する動画の合成内容は以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。