Vue+Flask realisiert Videosynthesefunktion (Drag & Drop-Upload)

Vue+Flask realisiert Videosynthesefunktion (Drag & Drop-Upload)

Der von Vue + Flask erzielte Videosyntheseeffekt ist wie folgt

Bildbeschreibung hier einfügen

Wir haben in einem früheren Artikel über das Hochladen per Drag & Drop geschrieben

//www.jb51.net/article/206543.htm

Das Prinzip besteht darin, auf das Drop-Ereignis zu hören, um die gezogene Dateiliste zu erhalten

Bildbeschreibung hier einfügen
Bildbeschreibung hier einfügen

Dateien hochladen

Dateien über Axios hochladen

this,.fileList ist unsere Dateiliste

let Dateien = diese.Dateiliste;
let formd = neue FormData();
sei i = 1;

//Upload-Liste hinzufügen files.forEach(item => {
	formd.append(i + "", Artikel, Artikelname)
	ich++;
})
formd.append("Typ", i)
let konfiguration = {
	Überschriften: {
		"Inhaltstyp": "multipart/Formulardaten"
	}
}

//Dateianforderung hochladen axios.post("/qwe", formd, config).then(res => {
	konsole.log(res.daten)
})

Flask verarbeitet Dateien

Den vollständigen Code finden Sie unten.

Die Logik ist wie folgt: Dateien empfangen, für jede Syntheseanforderung zufällig einen Ordner generieren, Dateien vorübergehend speichern, Videos zusammenfügen, Dateipfad zurückgeben

@app.route("/Datei",Methoden=['POST'])
def test():

 #Dateien abrufen files = request.files
 #Synthese-Warteschlange videoL = []
 #Zufällige Zeichenfolge dirs = sjs()
 #Ordner os.mkdir(dirs) generieren
 #Speichern Sie die Datei und fügen Sie sie der Synthesewarteschlange für Dateien in files.values() hinzu:
  drucken(Datei)
  dst = Verzeichnisse + "/" + Dateiname + ".mp4"
  Datei.Speichern(Ziel)
  Video = VideoFileClip(Verzeichnisse + "/" + Dateiname + ".mp4")
  videoL.anhängen(video)
 
 #Video zusammenfügen final = Videoclips verketten(videoL)
 #Dateipfad Dateiname = Verzeichnisse + "/" + "{}.mp4".format(sjs())
 #Video generieren final.to_videofile(Dateiname)
 
 #Ordner zerstören def sc():
  shutil.rmtree(Verzeichnisse)
 
 #Zerstöre den Ordner nach 30 Sekunden Timer = threading.Timer(30, sc)
 timer.start()

 # Gibt den Dateipfad zurück return fileName

Spleißen, um den Dateipfad zu erhalten

Schauen wir uns zunächst Flask an

Die Logik ist wie folgt: Holen Sie sich die Datei nach Dateinamen und geben Sie die Datei zurück

app.route("/getvoi",Methoden=['GET'])
def getImg():
 #Dateinamen abrufen ss = request.args['name']
 #Fügen Sie die Datei der zurückgegebenen Antwort hinzu response = make_response(
  sende_datei(ss)

 #Datei löschen def sc():
  os.entfernen(ss)
 
 #Löschen Sie die Datei nach 30 Sekunden Timer = threading.Timer(30, sc)
 timer.start()
 
 Antwort zurückgeben

Frontend-Akquisition

Download über Tag a

<as :href="herfs" rel="external nofollow" rel="external nofollow" :download="fileName">Herunterladen</a>

Herfs sind wie folgt

Bildbeschreibung hier einfügen

Nach dem Hochladen der Datei verarbeiten wir den zurückgegebenen Dateipfad durch FALSK und erhalten dann die Dateiadresse

Durch Hinzufügen des Download-Attributs zum a-Tag kann die heruntergeladene Datei benannt werden

Wenn Sie Fragen zu /qwe /voi haben, lesen Sie bitte die folgenden Anweisungen zur Proxy-Konfiguration

Konfigurationsproxy-Anweisungen

Der Zweck der Konfiguration eines Proxys besteht darin, domänenübergreifende Probleme zu lösen. Die Entwicklungsumgebung kann in vue.config.js konfiguriert und verwendet werden. Die Produktionsumgebung erfordert eine zusätzliche Konfiguration von nginx

Bildbeschreibung hier einfügen

/qwe ist eigentlich http://127.0.0.1:8087/file
/voi ist eigentlich http://127.0.0.1:8087/getvoi
Entsprechend unserer Flasche

Bildbeschreibung hier einfügen

Weitere Hinweise (bei Nutzung der Uni-App)

Wenn Sie uni-app verwenden, lesen Sie bitte die Dokumentation zur Verwendung der API
Datei-Upload-API https://uniapp.dcloud.io/api/request/network-file?id=uploadfile
API-Datei herunterladen https://uniapp.dcloud.io/api/request/network-file?id=downloadfile
Oder es ist bequemer, die von anderen gepackten Plug-Ins direkt zu verwenden.

Vollständiger Code

Wenn Sie sie nicht einzeln kopieren möchten, können Sie sie vom Downloadpfad 1 herunterladen: https://download.csdn.net/download/qq_42027681/15561897
Downloadpfad 2: https://github.com/dmhsq/vue-flask-videoSynthesis

Flaschencode

md5random.py wird zum Generieren von Zufallszeichenfolgen verwendet

zufällig importieren
Hashlib importieren
def sjs():
 a = Zufallszahl.randint(0, 100)
 a = "a" + str(a);
 b = zufällig.randint(100, 10000);
 b = "b" + str(b);
 c = hashlib.md5(a.encode(Kodierung='UTF-8')).hexdigest() + hashlib.md5(b.encode(Kodierung='UTF-8')).hexdigest();
 c = "c" + str(c);
 d = Zufall.randint(10, 100);
 d = "d" + str(d);
 e = hashlib.md5(c.encode(Kodierung='UTF-8')).hexdigest() + hashlib.md5(d.encode(Kodierung='UTF-8')).hexdigest();
 e = hashlib.md5(e.encode(Kodierung='UTF-8')).hexdigest()
 Rückkehr e;

Dienstcode app_service.py

aus Flask importiere Flask, Anfrage, Datei senden, Antwort erstellen
Betriebssystem, JSON, Threading, Shutil importieren
vom moviepy.editor importieren *
von md5random importiere sjs

App = Flask(__name__)

@app.route("/Datei",Methoden=['POST'])
def test():

 #Dateien abrufen files = request.files
 #Synthese-Warteschlange videoL = []
 #Zufällige Zeichenfolge dirs = sjs()
 #Ordner os.mkdir(dirs) generieren
 #Speichern Sie die Datei und fügen Sie sie der Synthesewarteschlange für Dateien in files.values() hinzu:
  drucken(Datei)
  dst = Verzeichnisse + "/" + Dateiname + ".mp4"
  Datei.Speichern(Ziel)
  Video = VideoFileClip(Verzeichnisse + "/" + Dateiname + ".mp4")
  videoL.anhängen(video)

 #Video zusammenfügen final = Videoclips verketten(videoL)
 #Dateipfad Dateiname = Verzeichnisse + "/" + "{}.mp4".format(sjs())
 #Video generieren final.to_videofile(Dateiname)

 #Ordner zerstören def sc():
  shutil.rmtree(Verzeichnisse)

 #Zerstöre den Ordner nach 30 Sekunden Timer = threading.Timer(30, sc)
 timer.start()

 # Gibt den Dateipfad zurück return fileName


@app.route("/getvoi",Methoden=['GET'])
def getImg():
 #Dateinamen abrufen ss = request.args['name']
 #Fügen Sie die Datei der zurückgegebenen Antwort hinzu response = make_response(
  sende_datei(ss)

 #Datei löschen def sc():
  os.entfernen(ss)

 #Löschen Sie die Datei nach 30 Sekunden Timer = threading.Timer(30, sc)
 timer.start()

 Antwort zurückgeben

wenn __name__ == '__main__':
 app.run(Host='0.0.0.0',Port=8087)

Vue-Code

Demo-Dateicode

<Vorlage>
 <div>
 <div
  v-on:dragover="tts"
  v-on:drop="ttrs"
  Stil = "Breite: 800px; Höhe: 200px; Rahmen: 1px tiefschwarz; Schriftgröße: 40px; Zeilenhöhe: 200px"
 >
  {{ dt }}
 </div>
 <div
  v-for="(Element, Index) in Dateiliste"
  :Schlüssel="Index"
  Stil = "Breite: 800px; Höhe: 200px; Rahmen: 1px tief schwarz; Schriftgröße: 40px; Position: relativ; oben: 10px"
 >
  <p
  Stil = "Schriftgröße: 20px; Float: links; Position: relativ; links: 20px Zeilenumbruch: Wortumbruch; Wortumbruch: normal;"
  >
  {{ Artikelname }}
  </p>
  <h5 style="float:right;position: absolute;oben: 80px;rechts: 20px">
  {{ Artikeltyp }}
  </h5>
  <h6 style="position: absolute;oben: 80px;float: links;links: 20px">
  {{ Artikelgröße | Größentyp }}
  </h6>
  <button style="float: right" @click="del(index)">Löschen</button>
 </div>
 <!-- Hier wird die zuletzt hochgeladene Datei angezeigt-->
<!-- <div style="position:relative;top: 100px">-->
<!-- <img v-if="isImage" :src="srcs" style="width: 800px" />-->
<!-- <video v-if="isVideo" steuert :src="srcs" style="width: 800px"></video>-->
<!-- <audio v-if="isAudio" steuert :src="srcs" style="width: 800px"></audio>-->
<!-- </div>-->

 <el-button style="position: relative;top: 50px" type="success" @click="ups()" :disabled="!isCan">Synthese</el-button>
 <el-button style="position: relative;top: 50px" v-loading="wird geladen" 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">Herunterladen</span></el-button></a>
 <div style="position: relative;top: 100px">Gültigkeitsdauer des Dateidownloads {{times}}s</div>
 </div>
</Vorlage>

<Skript>
importiere Axios von „Axios“;

Standard exportieren {
 Name: "trs",
 Daten() {
 zurückkehren {
  dt: "", //Upload-Erinnerung „Ziehen Sie hierhin, um die Datei hochzuladen“ oder „Upload abgeschlossen, Sie können mit dem Hochladen fortfahren“
  fileList: [], // Dateiliste wird geladen: false,
  srcs: "", //Bild/Video/Audio base64
  isImage: false, //Ist es ein Bild? isAudio: false, //Ist es eine Audiodatei? isVideo: false, //Ist es ein Video? isCan: true, //Kann es synthetisiert werden? isCans: true, //Kann es heruntergeladen werden? herfs: "", //Download-Adresse fileName: "", //Dateiname times: 25 //Gültigkeitsdauer des Downloads };
 },
 Filter:
 //Dateigröße formatieren sizeType(val) {
  sei kbs = val / 1024;
  sei mbs = 0;
  sei gbs = 0;
  wenn (kbs >= 1024) {
  mbs = kbs / 1024;
  }
  wenn (mbs >= 1024) {
  GB = MBS / 1024;
  return gbs.toFixed(2) + "GB";
  } sonst wenn (mbs >= 1) {
  return mbs.toFixed(2) + "MB";
  } anders {
  return kbs.toFixed(2) + "KB";
  }
 }
 },
 montiert() {
 lass vm = dies;
 window.addEventListener("dragdrop", this.testfunc, false);

 //Globale Überwachung, wenn auf der Seite eine Erinnerung zum Ziehen von Dateien vorhanden ist. Hierher ziehen. document.addEventListener("dragover", function() {
  konsole.log(111);
  vm.dt = „Ziehen Sie hierher, um Dateien hochzuladen“;
  Konsole.log(vm.dt);
 });
 },
 Methoden: {
 //Es gibt hauptsächlich drei Arten von Anzeigedateien: Bild/Video/Audio readFile(file) {
  lass vm = dies;
  : Der Reader kann nicht mit anderen Dateien verbunden werden.
  reader.readAsDataURL(Datei);
  Leser.onload = Funktion() {
  let Typ = Datei.Typ.substr(0, 5);
  wenn (Typ == "Bild") {
   vm.isImage = true;
   vm.isAudio = falsch;
   vm.isVideo = falsch;
  } sonst wenn (Typ == "Audio") {
   vm.isImage = falsch;
   vm.isAudio = true;
   vm.isVideo = falsch;
  } sonst wenn (Typ == "Video") {
   vm.isImage = falsch;
   vm.isAudio = false;
   vm.isVideo = true;
  } anders {
   alert("Kein Bild/Video/Audio");
  }
  vm.srcs = Leser.Ergebnis;
  // dies.$nextTick(()=>{
  //
  // })
  };
 },
 //Überwache global das Triggerereignis von Drop, um die Anzeige des Drop-Popup-Fensters abzubrechen resource testfunc(event) {
  Warnung("Dragdrop!");

  //Stornieren Sie die Anzeigeressource für das Drop-Popup-Fenster event.stopPropagation();
  event.preventDefault();
 },
 del(index) {
  diese.fileList.splice(index, 1);
  wenn (diese.fileList.length === 0) {
  dies.dt = "";
  }
 },
 //Überwachen Sie das Div-Upload-Feld und zeigen Sie „Ziehen Sie hierhin, um die Datei hochzuladen“ an, wenn eine Datei gezogen wird
 tts(e) {
  konsole.log(e);
  this.dt = "Hierher ziehen, um die Datei hochzuladen";
 },
 //Achten Sie auf das Drop-Ereignis der Div-Upload-Box, um ttrs(e) auszulösen {
  konsole.log(e);
  Konsole.log(e.dataTransfer.files);

  //Dateien abrufen let datas = e.dataTransfer.files;

  //Anzeige des Drop-Popup-Fensters abbrechen Ressource e.stopPropagation();
  e.preventDefault();
  datas.forEach(item => {
  wenn(item.type=="video/mp4"){
   diese.fileList.push(Element);
  }
  });

  //Dateien lesen. Wenn Sie keine Bilder/Videos/Audios anzeigen möchten, können Sie this.readFile(this.fileList[this.fileList.length - 1]); ignorieren.



  this.dt = "Upload abgeschlossen, Sie können mit dem Hochladen fortfahren";
 },

 //Dateien auf den Server hochladen ups(){
  wenn(diese.fileList.length==0){
  this.$message('Die Dateiliste ist leer');
  zurückkehren ;
  }
  dies.laden = wahr;
  dies.isCan = falsch;
  dies.isCans = wahr;
  let Dateien = diese.Dateiliste;
  let formd = neue FormData();
  sei i = 1;

  //Upload-Liste hinzufügen files.forEach(item=>{
  formd.append(i+"",Artikel,Artikelname)
  ich++;
  })
  formd.append("Typ",i)
  let config={
  Überschriften: {"Inhaltstyp":"multipart/form-data"}
  }

  //Dateianforderung hochladen axios.post("/qwe",formd,config).then(res=>{
  konsole.log(res.daten)
  dies.laden = falsch
  //Synthetisierter Download-Pfad this.herfs = "/voi?name="+res.data

  dieser.Dateiname = res.data.split('/')[1]
  //Synthese ist verboten this.isCan = false

  this.isCans = falsch

  //Legen Sie die Gültigkeitsdauer des Downloads fest. Nach Ablauf der Zeit kann der Download nicht abgeschlossen werden, aber die Synthese kann fortgesetzt werden. let timer = setInterval(()=>{
   dieses.Mal--;
  },1000)
  dies.setCans(Timer)
  })
 },
 setzeDosen(Timer){
  setzeTimeout(()=>{
  this.isCans = wahr
  dies.isCan = true
  dieser.Dateiname = ""
  Intervall löschen(Timer)
  dies.mal = 25
  },25000)
 }
 }
};
</Skript>

<Stilbereich></Stil>

vue.config.js

modul.exporte = {
 devServer: {
 // AssetsSubDirectory: "statisch",
 // öffentlicher Assets-Path: '/',
 Proxy: {
  "/qwe": {
  Ziel: "http://127.0.0.1:8087/Datei",
  changeOrigin: wahr,
  PfadNeu schreiben: {
   "^/qwe": ""
  }
  },
  "/voi": {
  Ziel: "http://127.0.0.1:8087/getvoi",
  changeOrigin: wahr,
  PfadNeu schreiben: {
   "^/voi": ""
  }
  }
 }
 }
};

Dies ist das Ende dieses Artikels über die Realisierung der Videosynthesefunktion (Drag & Drop-Upload) mit Vue+Flask. Weitere verwandte Inhalte zur Vue-Videosynthese finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Vue implementiert Drag & Drop oder Klicken zum Hochladen von Bildern
  • Realisieren Sie mobile Bild-Upload-, Komprimierungs-, Drag-and-Drop-Sortierungs- und Drag-and-Drop-Löschfunktionen basierend auf Vue2
  • Vollbild-Drag-Upload-Komponente basierend auf Vue3

<<:  MySQL 5.7.18 Installations-Tutorial und Problemübersicht

>>:  Probleme und Lösungen bei der Installation von MySQL8.0.13 auf einem Win10-System

Artikel empfehlen

JavaScript zur Implementierung eines Sprachwarteschlangensystems

Inhaltsverzeichnis einführen Hauptmerkmale Effekt...

25 Tipps und Tricks zur Div+CSS-Programmierung

1. Das ul-Tag hat in Mozilla standardmäßig einen ...

Analyse der Unterschiede zwischen Iframe und FRAME

1. Verwendung des Iframe-Tags <br />Wenn es ...

Verständnis und Beispielcode des Vue-Standardslots

Inhaltsverzeichnis Was ist ein Slot Grundlegendes...

Implementierung von Nginx-Weiterleitungsübereinstimmungsregeln

1. Regulärer Ausdrucksabgleich ~ für Groß- und Kl...

HTML-Tutorial: Sammlung häufig verwendeter HTML-Tags (6)

Diese eingeführten HTML-Tags entsprechen nicht un...

Detaillierte Erklärung der MySQL Master-Slave-Inkonsistenz und Lösungen

1. MySQL Master-Slave-Asynchronität 1.1 Netzwerkv...

Programme zum Abfragen und Löschen der Portnutzung im Windows-Betriebssystem

Im Windows-Betriebssystem das Programm zum Abfrag...

MySQL fügt schnell 100 Millionen Testdaten ein

Inhaltsverzeichnis 1. Erstellen Sie eine Tabelle ...

Was ist ein MIME-TYP? MIME-Typen-Typensammlung

Was ist ein MIME-TYP? 1. Zunächst müssen wir verst...