Siduction Forum > Scripting & Kernelhacking

[DE] Mehrere Videos mit melt zusammenschneiden (Ein-, Aus- u. Überblendeffekte)

(1/3) > >>

pit:
Habe 5 Videos in einem Verzeichnis:
01.mp4, 02.mp4 ... 05.mp4

Ich will die via melt in der Konsole zu einem Video zusammenmontieren.
01.mp4 soll von schwarz eingeblendet u. mit 02 überblendet werden. 02 soll mit 3, 3 mit 4 u. 4 mit 5 überblendet werden. 05.mp4 soll nach schwarz ausgeblendet werden.

Programmaufruf ist:
melt colour:black out=20 01.mp4 -mix 20 -mixer luma 02.mp4 -mix 20 -mixer luma 03.mp4 -mix 20 -mixer luma 04.mp4 -mix 20 -mixer luma 05.mp4 -mix 20 -mixer luma colour:black out=20 -mix 20 -mixer luma

Im Ergebnis dann vom Prinzip her so:
https://imgur.com/KST2gXT

Ich würde das gerne in ein Script oder in einen alias packen.
Challenge: Das soll auch bei einer unbekannten Anzahl von Videos funktionieren.

Ansatz:
Alle Dateinamen in ein array schreiben:

files=($(\ls *.mp4))

Den ersten und letzten Dateinamen (für das Ein-/Ausblenden von/nach schwarz) kann ich referenzieren
Erster: echo ${files[0]}
Letzter: echo  ${files[-1]}

Wie realisiere ich den Mittelteil, also Überblendung von 1 nach 2, 2 nach 2, ... vorletztes zu letztem?

Irgendwas mit Schleifen vermutlich, wobei beim Abrufen der Werte aus dem Array der Index um jeweils 1 hochgezählt werden müsste, bis der letzte Wert erreicht ist.

Fängt also an mit
melt colour:black out=20 ${files[0]} -mix 20 -mixer luma

dann die Schleife die so was erzeugt:
${files[1]} -mix 20 -mixer luma ${files[2]} -mix 20 -mixer luma ${files[2]} -mix 20 -mixer luma usw.

Endet mit colour:black out=20 -mix 20 -mixer luma

Wer kann mir bezüglich der gesuchten Schleife helfen?

edlin:
Quick & Dirty meine schnelle Lösung. Nicht elegant, sollte aber funktionieren. Bei mir habe ich die Dateien v01.mp4 ... v06.mp4 genutzt. Im Prinzip setze ich die Befehlszeile (clip.melt) Stück für Stück zusammen und führe sie dann aus.


--- Code: ---#!/bin/bash

# Alle Dateien entsprechend Suchmuster sortiert in Dump.txt schreiben
# Suchmuster evtl. anpassen

find . | grep mp4 | sort > Dump.txt

# Die erste Zeile wieder entfernen

sed -i 1D Dump.txt

# Den ersten Teil der Befehlszeile in die Datei clip.melt schreiben
# Setzt den fixen Dateinamen v01.mp4 voraus, evtl. anpassen

echo -n "melt colour:black out=20 v01.mp4 -mix 20 -mixer luma " > clip.melt

# Für alle Zeilen in Dump.txt die Befehlsteile an clip.melt anhängen
while read line
do
  echo -n $line >> clip.melt
  echo -n " -mix 20 -mixer luma " >> clip.melt
done < Dump.txt

# Abschluss der Befehlszeile für melt
echo -n "colour:black out=20 -mix 20 -mixer luma" >> clip.melt

# Ausführen und freuen
exec bash ./clip.melt
--- End code ---

Es gibt sicher unzählige Wege das Problem zu lösen, nimms als Anregung.

edlin

pit:
Moin edlin & ganz herzlichen Dank!

Ich probier's heute Abend aus (noch sitze ich vor dem Dienst Notebook) und werde berichten.

Herzlichst
pit

scholle1:
Noch ein Vorschlag:


--- Code: ---#!/bin/sh
#
# Name: multifilm.sh
#
# Voraussetzung:
#  Eindeutige Dateinamen, die die Reihenfolge in der die Dateien
#  zusammengesetzt werden sollen widerspiegelt. Am besten Nummerierung
#  mit führenden Nullen. Die Nummerierung muss nicht durchgehend sein.
#
# Ausführen:
#  Dieses Skript im Ordner mit den .mp4 Dateien ablegen und ausführbar machen.
#  In den Ordner mit den .mp4 Dateien wechseln und das Skript aufrufen.
#

FIRST=$(ls *.mp4 | head -n 1)
LAST=$(ls *.mp4 | tail -n 1)
#echo "First is: $FIRST"       # Nur zum prüfen
#echo "Last is: $LAST"         # Nur zum prüfen

for i in *.mp4; do
  if [ "$i" = "$FIRST" ]       # Sonderbehandlung für die erste Datei
  then
    OUTPUT="melt colour:black out=20 $i -mix 20 -mixer luma";
    continue                   # Zur nächsten Iteration springen
   
  elif [ "$i" = "$LAST" ]      # Sonderbehandlung für die letzte Datei
  then
    OUTPUT="$OUTPUT $i -mix 20 -mixer luma colour:black out=20 -mix 20 -mixer luma";
   
  else
    OUTPUT="$OUTPUT $i -mix 20 -mixer luma ";
  fi
done

exec $OUTPUT       # Befehl ausführen

--- End code ---

Der Befehl führt bei mir zum Fehler

--- Code: ---[libprotobuf ERROR google/protobuf/descriptor_database.cc:120] File already exists in database: opencv-caffe.proto
[libprotobuf FATAL google/protobuf/descriptor.cc:1382] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
terminate called after throwing an instance of 'google::protobuf::FatalException'
  what():  CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
Abgebrochen

--- End code ---

Ich kenne mich mit melt nicht aus.

Da müsstest du noch einmal genauere Informationen posten.

Wichtig für das Skript ist eine posix konforme Bezeichnung der Dateien.
Die Shell sortiert die Dateinamen beim Befehl "ls" und in der "for" Schleife entsprechend.
Am besten mit Ziffern und führenden Nullen (005-film.mp4 oder 034-irgendetwas.mp4).
Buchstaben gehen auch und werden nach den Ziffern eingereiht.
Lücken in der Nummerierung sind unschädlich. Du kannst jeder Zeit einzelne Filme
aus dem Ordner entfernen, ohne dass es Probleme gibt; oder in Nummerierungslücken
hinzufügen.

pit:
Moin scholle1

Sehr cool, dein Script funktioniert auf Anhieb. Ich übergebe jetzt noch die Anzahl der Frames für die Überblendung via Variable $1, habe auch Audio-Überblendung ergänzt (... -mixer mix:-1) und melt schreibt jetzt in eine Datei, statt das Video sofort abzuspielen (letzte Zeile ergänzt um =>  -consumer avformat:$(date +%y%m%d-%H%M%S)-videomix.mp4 vcodec=libx264 b=2M acodec=aac ab=96k). Hier in Gänze:


--- Code: ---#!/bin/sh
#
# Name: multifilm.sh
#
# Voraussetzung:
#  Eindeutige Dateinamen, die die Reihenfolge in der die Dateien
#  zusammengesetzt werden sollen widerspiegelt. Am besten Nummerierung
#  mit führenden Nullen. Die Nummerierung muss nicht durchgehend sein.
#
# Ausführen:
#  Dieses Skript im Ordner mit den .mp4 Dateien ablegen und ausführbar machen.
#  In den Ordner mit den .mp4 Dateien wechseln und das Skript aufrufen.
#

FIRST=$(ls *.mp4 | head -n 1)
LAST=$(ls *.mp4 | tail -n 1)
F=$1    # Anzahl der Frames für Überblendung
#echo "First is: $FIRST"       # Nur zum prüfen
#echo "Last is: $LAST"         # Nur zum prüfen

for i in *.mp4; do
  if [ "$i" = "$FIRST" ]       # Sonderbehandlung für die erste Datei
  then
    OUTPUT="melt colour:black out=$F $i -mix $F -mixer luma -mixer mix:-1";
    continue                   # Zur nächsten Iteration springen
   
  elif [ "$i" = "$LAST" ]      # Sonderbehandlung für die letzte Datei
  then
    OUTPUT="$OUTPUT $i -mix $F -mixer luma colour:black out=$F -mix 20 -mixer luma -mixer mix:-1";
   
  else
    OUTPUT="$OUTPUT $i -mix $F -mixer luma -mixer mix:-1 ";
  fi
done

exec $OUTPUT -profile hdv_720_30p -consumer avformat:$(date +%y%m%d-%H%M%S)-videomix.mp4 vcodec=libx264 b=2M acodec=aac ab=96k      # Befehl ausführen
--- End code ---

Jetzt muss ich nochmal gucken, wie ich melt dazu bewege, die Videos nicht auf eine kleinere Auflösung runterzurechnen. Meine Test-Clips hatten 3840:2160, das Ergebnis 720x576. Nur ein Beispiel, normalerweise haben meine Clips nicht mehr als 1080p. Aber das alles hat mit deinem Script nichts mehr zu tun :-)

// edit
// Die Auflösung der Ausgabedatei steuert der melt Parameter profile
// Habe im Script (letzte Zeile) ergänzt:  -profile hdv_720_30p
// Eine Liste möglicher Auflösungen liefert:
// melt -query "profiles"

Also nochmal VIELEN Dank!

Navigation

[0] Message Index

[#] Next page

Go to full version
Powered by Advanced Topic Prefix Pro
Powered by SMFPacks WYSIWYG Editor