Gibt es ein Skript (Bash, Python usw.), das die Gesamtdauer aller Videodateien in einem Verzeichnis (rekursiv) ausgibt?
Zum Beispiel bei der Ausführung von Folgendem:
script mypath
es gibt x minutes/hours
.
Gibt es ein Skript (Bash, Python usw.), das die Gesamtdauer aller Videodateien in einem Verzeichnis (rekursiv) ausgibt?
Zum Beispiel bei der Ausführung von Folgendem:
script mypath
es gibt x minutes/hours
.
Antworten:
Zuerst installieren mediainfo
mit:
sudo apt-get install mediainfo
Sie können jetzt den folgenden Oneliner verwenden, um die Gesamtvideozeit eines Verzeichnisses abzurufen:
find . -type f -exec mediainfo --Inform="General;%Duration%" "{}" \; 2>/dev/null | awk '{s+=$1/1000} END {h=s/3600; s=s%3600; printf "%.2d:%.2d\n", int(h), int(s/60)}'
Der find
Befehl ruft mediainfo
alle Dateien rekursiv auf und ermittelt die Videodauer in ms.
Dann awk
summiert der Teil diese Werte und gibt die Gesamtzeit im HH:MM
Format zurück.
Update : avprobe
ist in der Tat schneller als mediainfo
(danke @ souravc )
Für bessere Ergebnisse verwenden Sie stattdessen den folgenden Befehl (Sie müssen sudo apt-get install libav-tools
zuerst)
find . -type f -exec avprobe -v quiet -show_format_entry duration "{}" \; | awk '{s+=$1} END {h=s/3600; s=s%3600; printf "%.2d:%.2d\n", int(h), int(s/60)}'
E: File read error
während der Ausführung in einem Verzeichnis (habe andere Dateien als Videodateien). IMHO mediainfo
ist vergleichsweise langsam als avprobe
. Es dauert mehr als doppelt so lange wie die von avprobe
.
avprobe
da sie in der Tat viel schneller als mediainfo ist (ich habe auch den Fehler beim Lesen der ersten Version behoben)
Mit dem folgenden Skript können Sie die Gesamtdauer aller Videodateien in einem Verzeichnis rekursiv ermitteln . Ich habe avprobe
im folgenden Skript verwendet, das mit kommtlibav-tools
Installieren libav-tools
als,
sudo apt-get install libav-tools
Speichern Sie das Skript als get_video_duration.sh
(sagen wir). Geben Sie ihm die Ausführungsberechtigung von einem Terminal als
chmod u+x get_video_duration.sh
So führen Sie das Skript aus
/full/path/to/videodir
Führen Sie das Argument as aus , um die Gesamtvideodauer des Verzeichnisses zu ermitteln
./get_video_duration.sh /full/path/to/videodir
Oder um die Gesamtvideodauer des aktuellen Verzeichnisses zu kennen, das ohne Argument als ausgeführt wird
./get_video_duration.sh .
Für die Rekursion anhängen -R
oder -r
oder -recursive
oder --recursive
nach dem Verzeichnispfad. Zum Beispiel, um die gesamte Videodauer des Verzeichnisses /full/path/to/videodir
rekursiv zu ermitteln (durchsuchen Sie auch alle darin enthaltenen Ordner /full/path/to/videodir
).
./get_video_duration.sh /full/path/to/videodir -R
Das Skript lautet wie folgt:
#!/bin/bash
mysep="======================================================================================"
mysmallsep="--------------------------------------------------------------------------------------"
if [ -n "$1" ];then
mypath="$1"
else
mypath="$(pwd)"
fi
declare -a my_path_array
get_duration(){
/usr/bin/avprobe "$1" 2>&1 | grep Duration | awk -F[:,] '{print int($2*3600+$3*60+$4)}'
}
print_duration(){
awk -v var="$1" 'BEGIN {print int(var/3600)"Hr "int((var%3600)/60)"Min "int(var%60)"Sec "}'
}
execute_it_now(){
echo -e "Video File\t\tVideo Duration"
echo $mysep
echo "$1"
echo $mysmallsep
j=0
for i in "$1"/{*.mp4,*.mkv,*.avi,*.flv} ## Put the existing video file extension you have
do
if [[ "$(get_duration "$i")" -ne "0" ]];then
echo -e "$(basename "$i")\t$(tput setaf 2)$(print_duration $(get_duration "$i"))$(tput sgr0)"
fi
let j=j+$(get_duration "$i") 2>/dev/null
done
echo $mysep
echo "Total Duration $(tput setaf 1)$(print_duration $j)$(tput sgr0)"
}
execute_these_now(){
for i in "$1"/{*.mp4,*.mkv,*.avi,*.flv} ## Put the existing video file extension you have
do
if [[ "$(get_duration "$i")" -ne "0" ]];then
echo -e "$(basename "$i")\t$(tput setaf 2)$(print_duration $(get_duration "$i"))$(tput sgr0)"
fi
done
}
add_these_now(){
j=0;
for i in "$1"/{*.mp4,*.mkv,*.avi,*.flv} ## Put the existing video file extension you have
do
let j=j+$(get_duration "$i") 2>/dev/null
done
echo $j
}
case "$2" in
-R|-r|-recursive|--recursive)
tmp=$(find $mypath -type d | xargs)
my_path_array=( $tmp )
echo -e "Video File\t\tVideo Duration"
echo $mysep
k=0;
for indx in $(seq ${#my_path_array[@]})
do
echo ${my_path_array[$(($indx-1))]}
echo $mysmallsep
execute_these_now ${my_path_array[$(($indx-1))]}
let k=k+$(add_these_now ${my_path_array[$(($indx-1))]})
done
echo $mysep
echo "Total Duration $(tput setaf 1)$(print_duration $k)$(tput sgr0)"
;;
*)
execute_it_now $mypath
;;
esac
Screenshot der Ausführung des Skripts
Hinweis: Da ich keine .mkv
oder keine .avi
Datei in meinem Home-Verzeichnis habe, wurden die letzten beiden Zeilen des Screenshots mit der Dauer 0Hr 0Min 0Sec angezeigt
for i in $mypath/*
for i in $mypath/{*.mp4,*.mkv,*.avi}
for i in $mypath/*
, listet es andere Dateien mit 0 Dauer auf. Die Anwendung unterscheidet sich also von SylvainPineaus Antwort, ist aber dennoch nützlich :)