是否有一个脚本(bash,python等)可以输出目录中所有视频文件的总持续时间(递归)?
例如执行以下操作:
script mypath
它给x minutes/hours
。
答案1
首次安装mediainfo
:
sudo apt-get install mediainfo
您现在可以使用以下一行代码来获取目录的总视频时间:
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)}'
该find
命令将mediainfo
递归调用每个文件并以毫秒为单位获取视频时长。
然后该awk
部分将对这些值求和并以格式返回总时间HH:MM
。
更新:avprobe
确实比mediainfo
(感谢@索拉夫)
为了获得更好的结果,请使用下面的命令(您需要sudo apt-get install libav-tools
先)
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)}'
答案2
你可以使用以下脚本来了解递归获取目录中所有视频文件的总时长。 我用过avprobe
在以下脚本中libav-tools
安装libav-tools
为,
sudo apt-get install libav-tools
保存脚本比如说get_video_duration.sh
。从终端授予其执行权限
chmod u+x get_video_duration.sh
如何运行脚本
要了解目录的总视频时长/full/path/to/videodir
,请使用参数运行
./get_video_duration.sh /full/path/to/videodir
或者要知道当前目录运行的视频总时长,无需任何参数,
./get_video_duration.sh .
对于递归在目录路径后附加-R
或-r
或-recursive
或--recursive
。例如,以递归方式了解目录的总视频时长/full/path/to/videodir
(还可以搜索目录内的所有文件夹/full/path/to/videodir
)
./get_video_duration.sh /full/path/to/videodir -R
脚本如下:
#!/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
脚本执行的屏幕截图
笔记:由于我的主目录中没有任何.mkv
文件,因此.avi
屏幕截图中最后两行的持续时间为 0 小时 0 分钟 0 秒