Gesamtvideozeit in einem Verzeichnis

7

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.

Bitte helfen Sie
quelle

Antworten:

10

Zuerst installieren mediainfomit:

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 findBefehl ruft mediainfoalle Dateien rekursiv auf und ermittelt die Videodauer in ms.

Dann awksummiert der Teil diese Werte und gibt die Gesamtzeit im HH:MMFormat zurück.


Update : avprobeist 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-toolszuerst)

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)}'
Sylvain Pineau
quelle
1
Nein. Es funktioniert für kleine Verzeichnisse, gibt aber einige 2 Stunden für große Verzeichnisse. Vor der Installation von gawk wurde folgende Fehlermeldung angezeigt: "strftime: Funktion in awk nicht definiert". @ SylvainPineau kann der Stundenüberlauf sein? (Vermutung)
PleaseHelp
1
@ AtulGangwar Bitte versuchen Sie meine aktualisierte Version
Sylvain Pineau
1
@ SylvainPineau Danke. Ich habe dies als Funktion in meinem ~ / .bashrc hinzugefügt und den Pfad als Argument übergeben :)
PleaseHelp
1
@ SylvainPineau Ich erhalte E: File read errorwährend der Ausführung in einem Verzeichnis (habe andere Dateien als Videodateien). IMHO mediainfoist vergleichsweise langsam als avprobe. Es dauert mehr als doppelt so lange wie die von avprobe.
Souravc
@souravc Ich habe meine Antwort mit aktualisiert, avprobeda sie in der Tat viel schneller als mediainfo ist (ich habe auch den Fehler beim Lesen der ersten Version behoben)
Sylvain Pineau
6

Mit dem folgenden Skript können Sie die Gesamtdauer aller Videodateien in einem Verzeichnis rekursiv ermitteln . Ich habe avprobeim folgenden Skript verwendet, das mit kommtlibav-tools

Installieren libav-toolsals,

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/videodirFü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 -Roder -roder -recursiveoder --recursivenach dem Verzeichnispfad. Zum Beispiel, um die gesamte Videodauer des Verzeichnisses /full/path/to/videodirrekursiv 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

Geben Sie hier die Bildbeschreibung ein

Hinweis: Da ich keine .mkvoder keine .aviDatei in meinem Home-Verzeichnis habe, wurden die letzten beiden Zeilen des Screenshots mit der Dauer 0Hr 0Min 0Sec angezeigt

Souravc
quelle
Funktioniert dies, wenn die Dateien keine Erweiterungen haben (aber immer noch Videodateien sind)?
Bitte helfen Sie
1
Verwenden Sie einfach for i in $mypath/*for i in $mypath/{*.mp4,*.mkv,*.avi}
anstelle
Schönes Skript. Es listet alle Dateien mit Dauer und Gesamtdauer nur im aktuellen Verzeichnis auf, wird jedoch nicht rekursiv. Auch wenn ich es benutze 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 :)
PleaseHelp
Möglicherweise wird eine Option wie "-R" hinzugefügt, um beide Fälle zu behandeln, da auch nur die Suche nach dem aktuellen Verzeichnis nützlich sein kann.
Bitte helfen Sie
1
@AtulGangwar sehen Sie nur den überarbeiteten Code. Ich hoffe, dies wird Ihrem Zweck dienen. :)
Souravc