파일 목록이 있습니다 .ts
.
out1.ts ... out749.ts out8159.ts out8818.ts
이 모든 파일의 총 기간(실행 시간)을 어떻게 얻을 수 있습니까?
답변1
여기에는 없지만 .ts
(만 .mp4
) 모든 비디오 파일에 대해 작동합니다. 시간을 초 단위로 얻으려면 (partial )을
사용하십시오 . 예를 들면 다음과 같습니다.ffprobe
ffmpeg
ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4
275.690000
따라서 모든 비디오 파일에 대해 루프를 사용하여 총 시간을 초 단위로 계산할 수 for
있습니다 awk
.
for f in ./*.mp4
do ffprobe -v quiet -of csv=p=0 -show_entries format=duration "$f"
done | awk '{sum += $1}; END{print sum}'
2735.38
출력을 추가로 처리하여 총계를 로 변환하려면 DD:HH:MM:SS
답변을 참조하세요.여기.
또 다른 방법은 exiftool
내부가 있는 via 입니다 ConvertDuration
.
exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
}' ./*.mp4 | tail -n1
0:45:35
답변2
ffmpeg
총 시간 초과 초를 사용 하고 인쇄합니다.
times=()
for f in *.ts; do
_t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
times+=("$_t")
done
echo "${times[@]}" | sed 's/ /+/g' | bc
설명하다:
for f in *.ts; do
".ts"로 끝나는 각 파일을 반복합니다.
ffmpeg -i "$f" 2>&1
출력을 stderr로 리디렉션
grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
격리 시간
awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
시간을 초로 변환
times+=("$_t")
배열에 초 추가
echo "${times[@]}" | sed 's/ /+/g' | bc
bc
각 인수를 확장하고 공백을 대체하여 일반 Linux 계산기 에 연결합니다.
답변3
유선@jmunsch의 답변, paste
방금 배운 내용을 활용해 보세요.@slm의 답변, 다음과 같은 결과가 나올 수 있습니다.
for i in *.ts; do LC_ALL=C ffmpeg -i "$i" 2>&1 | \
awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done | paste -sd+ | bc
jmunsch와 마찬가지로 ffmpeg
지속 기간을 인쇄하고 누락된 출력 파일에 대한 오류를 무시하고 대신 지속 기간 라인에 대한 오류 출력을 검색했습니다. 나는 ffmpeg
지역화된 출력 메시지에 대해 걱정할 필요가 없도록 로캘의 모든 측면을 표준 C 로캘로 호출하도록 강제합니다.
awk
다음 으로 나는 그의 grep | grep | head | tr | awk
. 이 awk
호출은 포함된(고유한) 행을 찾습니다 Duration:
. 콜론을 구분 기호로 사용하면 레이블은 필드 1, 시간은 필드 2, 분은 필드 3, 초는 필드 4입니다. 초 뒤의 쉼표는 나를 괴롭히지 않는 것 같지만 awk
, 거기에 문제가 있는 사람이 있으면 tr -d ,
와 사이의 파이프에 포함시킬 수 있습니다.ffmpeg
awk
이제 slm의 일부: 저는 개행 문자를 더하기 기호로 바꾸곤 했지만 후행 개행 문자 에는 paste
영향을 주지 않았습니다(예:tr \\n +
이전 버전이 답변). 이는 에 입력할 수 있는 합계 표현식을 제공합니다 bc
.
유사한 시간 형식을 처리하기 위한 slm의 아이디어에서 영감을 받아 date
이를 사용하여 결과 초를 분수 부분을 사용하여 일, 시간, 분 및 초로 형식화하는 버전은 다음과 같습니다.
TZ=UTC+0 date +'%j %T.%N' --date=@$(for i in *.ts; do LC_ALL=C \
ffmpeg -i "$i" 2>&1 | awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done \
| paste -sd+ | bc) | awk '{print $1-1 "d",$2}' | sed 's/[.0]*$//'
내부는 $(…)
예전과 똑같습니다. 이 @
문자를 표시로 사용하여 1970년 1월 1일 이후의 초 수로 사용합니다. 결과 "날짜"는 연도, 시간 및 나노초 형식으로 지정됩니다. 0초를 입력하면 이미 1970년의 첫날이 되기 때문에 날짜에서 1을 뺍니다. 나는 연도의 날짜를 0부터 시작하는 방법이 없다고 생각합니다.
최종 결과에는 sed
불필요한 후행 0이 제거되었습니다. 설정 TZ
은 일광 절약 시간이 방해하지 않도록 UTC를 강제해야 합니다.진짜대규모 비디오 컬렉션. 하지만 1년이 넘은 동영상이 있는 경우에는 이 방법이 작동하지 않습니다.