Hallo zusammen,
wie hier zu sehen ist, pflege ich meine Familien-Videos (meist kurze Handy-Filme) in Kodi und habe mir dazu ein Skript gebastelt um sie schnell und ordentlich in die Kodi-DB zu bekommen. Drum rum sind aber noch ein paar weitere Skripte entstanden, die vielleicht der eine oder andere von euch auch brauchen kann.
Eines davon ist das, was ich "schneiden und kleben" nenne
- Beispielaufgabe: Ausflug in Tierpark
- Kind füttert Enten => süß => Video 1 wird gemacht
- Kind füttert 10 Minuten später Papageien => süß => Video 2 wird gestartet. Nach ner Minute fliegt das Vieh weg, du denkst es kommt gleich wieder, tut es aber nicht => Video 2 ist 2 Minuten lang, du willst aber nur die erste Minute
- 10 Minten später passiert wieder was ganz tolles und du machst Video 3
- In Kodi will ich aber nicht 3 1-Minuten-Videos haben sondern 1 3-Minuten-Video "Ausflug in den Tierpark". Außerdem habe ich keinen Bock Video 2 von Hand zu schneiden, dann 1 2 und 3 zusammenzufügen und dann auch noch den Zeitstempel manuell zu setzen (damit mein "Einsortieren-Skript den richtigen Tag zuordnet)
Hier kommt mein "Schneiden-und-Kleben-Skript" ins Spiel: es liegt in einem speziellen Ordner, dem auch ein Unterordner \tools\ffmpeg.exe liegt. Da schiebe ich Video 1 2 und 3 rein und starte das Skript. Und dann?
- Es fragt ob ich auch schneiden will => ja
- es erzeugt und öffnet eine Textdatei die ich nur minimal anpassen muss (eine Zahl um genau zu sein):
# Info: 00:00:00 bis 00:00:00 = ganzer Film
00:00:00 bis 00:00:00 => Video_1.mp4
00:00:00 bis 00:00:00 => Video_2.mp4
00:00:00 bis 00:00:00 => Video_3.mp4
ich will nur Video 2 schneiden, also ändere ich es zu
# Info: 00:00:00 bis 00:00:00 = ganzer Film
00:00:00 bis 00:00:00 => Video_1.mp4
00:00:00 bis 00:01:00 => Video_2.mp4
00:00:00 bis 00:00:00 => Video_3.mp4
- speichern, schließen, OK klicken
- Video 2 wird geschnitten
- Video 1, Video 2 geschnitten und Video 3 werden zusammengefügt
- Das kombinierte Video bekommt den Zeitstempel des neuesten Teilvideos (in dem Fall den von Video 3)
- Die originalen Videos werden in den Unterordner \BackupEinzelfilme geschoben (achso, der sollte schon existieren - könnte sonst einen Fehler geben, ich war faul beim programmieren )
- Fertig ist Video des Tages
- ich schiebe es wieder zurück in meinen Home-Video-Ordner und mache es mit oben erwähntem Skript Kodi-lesbar...
Hier noch der Code - achso, es handelt sich diesmal um ein PowerShell-Skript. Also bitte als .ps1 abspeichern und am besten mit PowerShell ISE öffnen und mit F5 starten. Gibt aber mehrere Arten PS-Skripte zu starten, Google hilft.
Es kann übrigens auch einfach dazu benutzt werden ganze Videos zu kombinieren ohne schneiden => dann wird die Textdatei nicht geöffnet.
Oder es kann auch einfach nur 1 Video geschnitten werden, unter Beibehaltung des Dateidatums.
# aktuellen Pfad ermitteln
$AktuellerPfad = split-path $SCRIPT:MyInvocation.MyCommand.Path -parent
$BackupPfad = $AktuellerPfad + "\BackupEinzelfilme"
# definierte Tool-Pfade
$FFPfad = $AktuellerPfad + "\tools\ffmpeg.exe"
# Steuerungs-Abfragen
Write-Host
Write-Host "########################"
Write-Host "### Einstellungen ####"
Write-Host "########################"
Write-Host
$Schnitt = if($Value=(Read-Host "Sollen Filme geschnitten werden? (Enter = ja)")){$Value}else{"ja"}
Write-Host
Write-Host "Schnitt = " $Schnitt
Write-Host
Write-Host "########################"
Write-Host
# Schnittinfo-Datei vorbereiten und Header schreiben
$SchnittinfoDatei = $AktuellerPfad + "\Schnittinfo.txt"
Remove-Item -Path $SchnittinfoDatei -ErrorAction SilentlyContinue
"# Info: 00:00:00 bis 00:00:00 = ganzer Film" | Out-File $SchnittinfoDatei -Encoding UTF8
" " | Out-File $SchnittinfoDatei -Append -Encoding UTF8
# ffmpeg-Input-Datei definieren
$ffmpegInput = $AktuellerPfad + "\ffmpegInput.txt"
Remove-Item -Path $ffmpegInput -ErrorAction SilentlyContinue
# MP4-Dateien suchen und in Schittinfo-Datei schreiben
# + Zeitstempel der letzten Datei auslesen (nimm den neuesten)
$MP4Dateien = Get-ChildItem -Path $AktuellerPfad -Filter "*.mp4"
if ($ZeitstempelAlt) {remove-variable "ZeitstempelAlt"}
if ($Zeitstempel) {remove-Variable "Zeitstempel"}
if ($NeuesteDateiAlt) {remove-variable "NeuesteDateiAlt"}
if ($NeuesteDatei) {remove-Variable "NeuesteDatei"}
ForEach ($Datei in $MP4Dateien) {
"00:00:00 bis 00:00:00 => "+$Datei | Out-File $SchnittinfoDatei -Append -Encoding UTF8
if ($Zeitstempel) {$ZeitstempelAlt = $Zeitstempel}
if ($NeuesteDatei) {$NeuesteDateiAlt = $NeuesteDatei}
$Zeitstempel = $Datei.LastWriteTime
$NeuesteDatei = $Datei
if ($Zeitstempel -lt $ZeitstempelAlt) {
$Zeitstempel = $ZeitstempelAlt
$NeuesteDatei = $NeuesteDateiAlt
}
}
# Schnittinfo anzeigen und auf Aenderung warten
if ($Schnitt -eq "ja") {
start Notepad++ $SchnittinfoDatei
Write-Host
Read-Host -Prompt "Ist die Liste fertig und gespeichert? Dann weiter mit Enter"
}
# Schau nach wie viele Filme es sind
$AnzahlFilme = 0
$ZeilenZaehler = 0
$SchnittinfoInhalt = get-content $SchnittinfoDatei
foreach ($Zeile in $SchnittinfoInhalt) {
$ZeilenZaehler++
If ($ZeilenZaehler -ge 3) {
If ($Zeile.trim()) {$AnzahlFilme = $AnzahlFilme + 1}
}
}
Write-Host $AnzahlFilme "Filme sollen kombiniert werden"
Write-Host
# Zeilenweise einlesen und ffmpeg-Inputdatei schreiben
$Filmnummer = 0
$ZeilenZaehler = 0
foreach ($Zeile in $SchnittinfoInhalt) {
$ZeilenZaehler++
# Inhalt ab Zeile 3 lesen
If ($ZeilenZaehler -ge 3) {
$Filmnummer = $Filmnummer + 1
$Dateiname = $Zeile.Substring(25)
If ($Zeile -like "*00:00:00 bis 00:00:00*") {
write-host Film $Filmnummer : - Ganzer Film -: $Dateiname
Write-Host
"file '"+$AktuellerPfad+"\"+$Dateiname+"'" | out-file $ffmpegInput -Append -Encoding ASCII
} else {
write-host Film $Filmnummer : --- Schnitt ---: $Dateiname
# Zeiten einlesen und umrechnen
$StartStunden = $Zeile.Substring(0,2)
$StartMinuten = $Zeile.Substring(3,2)
$StartSekunden = $Zeile.Substring(6,2)
$EndStunden = $Zeile.Substring(13,2)
$EndMinuten = $Zeile.Substring(16,2)
$EndSekunden = $Zeile.Substring(19,2)
$StartZeit = New-TimeSpan -Hour $StartStunden -Minute $StartMinuten -Second $StartSekunden
$EndZeit = New-TimeSpan -Hour $EndStunden -Minute $EndMinuten -Second $EndSekunden
$ZeitDauer = $EndZeit - $StartZeit
$StartZeitString = $StartStunden + ":" + $StartMinuten + ":" + $StartSekunden
$ZeitDauerString = $ZeitDauer.ToString()
Write-Host Schneide Filme $Filmnummer : Start $StartZeitString : Dauer $ZeitDauerString
Write-Host
# definieren Dateinamen und schneide das Video
$DateinameSchnitt = $Dateiname -replace(".mp4","-Schnitt.mp4")
$DateinameMitPfad = $AktuellerPfad + "\" + $Dateiname
$DateinameSchnittMitPfad = $AktuellerPfad + "\" + $DateinameSchnitt
&$FFPfad -loglevel error -i $DateinameMitPfad -vcodec copy -acodec copy -ss $StartZeitString -t $ZeitDauerString $DateinameSchnittMitPfad
# setze Zeitstempel von geschnittener Datei gleich wie Originaldatei
$DateinameSchnittMitPfadDatei = Get-Item $DateinameSchnittMitPfad
$DateinameMitPfadDatei = Get-Item $DateinameMitPfad
$ZeitstempelSchnitt = $DateinameMitPfadDatei.LastWriteTime
$DateinameSchnittMitPfadDatei.LastWriteTime = $ZeitstempelSchnitt
$DateinameSchnittMitPfadDatei.LastAccessTime = $ZeitstempelSchnitt
$DateinameSchnittMitPfadDatei.CreationTime = $ZeitstempelSchnitt
# verschiebe das Original-Video
$BackupDateinameMitPfad = $BackupPfad + "\" + $Dateiname
Move-Item $DateinameMitPfad $BackupDateinameMitPfad
# schreibe den Schnitt-Dateinamen in die ffmpeg-Input-Datei
"file '"+$AktuellerPfad+"\"+$DateinameSchnitt+"'" | out-file $ffmpegInput -Append -Encoding ASCII
}
}
}
# Check ob mehr nur 1 Film geschnitten werden sollte
if ($AnzahlFilme -le 1) {
write-host "Es ist nur ein Film vorhanden, deswegen ueberspringe ich das Zusammfuegen"
} else {
# Fuege die Videos zusammen
Write-Host "Ich klebe jetzt die Videos zusammen"
Write-Host
$KombiName = $AktuellerPfad+"\"+$NeuesteDatei -replace(".mp4","-Kombi.mp4")
&$FFPfad -loglevel error -f concat -safe 0 -i $ffmpegInput -c copy $KombiName
# setze Zeitstempel
$KombiNameDatei = Get-Item $KombiName
$KombiNameDatei.LastWriteTime = $Zeitstempel
$KombiNameDatei.LastAccessTime = $Zeitstempel
$KombiNameDatei.CreationTime = $Zeitstempel
# Schiebe die Einzelvideos ins Backup
$ZeilenZaehler = 0
$ffmpegInputInhalt = get-content $ffmpegInput
foreach ($Zeile in $ffmpegInputInhalt) {
$ZeilenZaehler++
# Inhalt lesen
$DateinameMitPfad = $Zeile.Substring(6)
$DateinameMitPfad = $DateinameMitPfad.Substring(0,$DateinameMitPfad.Length-1)
$BackupDateinameMitPfad = $DateinameMitPfad.Replace($AktuellerPfad,$BackupPfad)
Move-Item $DateinameMitPfad $BackupDateinameMitPfad
}
}
# aufraeumen
Remove-Item -Path $SchnittinfoDatei -ErrorAction SilentlyContinue
Remove-Item -Path $ffmpegInput -ErrorAction SilentlyContinue
Write-Host "########################"
write-host "####### Fertig #######"
Write-Host "########################"
Alles anzeigen