디렉토리에서 비디오 파일의 전체 길이를 가져옵니다


30

.ts파일 목록이 있습니다.

out1.ts ... out749.ts   out8159.ts  out8818.ts

이 모든 파일의 총 지속 시간 (실행 시간)을 어떻게 얻을 수 있습니까?


단일 파일의 지속 시간을 어떻게 얻습니까?
Hauke ​​Laging

나도 몰라
k961

@Hauke Laging 내가이 프로그램을 발견 "Mediainfo를"
k961

이들은 미디어 파일이며 비디오 일 가능성이 있습니다.
slm

1
모든 미디어 파일 (예 : MP4, ASF 및 .264 ...)에는 미리 정의 된 표준 헤더 정보가 있으며 해상도, 프레임 속도, 프레임 수 (GOP) 및 파일 길이 및 지속 시간과 같은 해당 파일에서 정보를 얻을 수 있습니다. media ...
Kantam Nagesh

답변:


55

나는 .ts여기에 없지만이 작동합니다 .mp4. ffprobe(의 일부 ffmpeg)를 사용 하여 시간을 초 단위로 가져옵니다. 예 :

ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4 
275.690000

.mp4현재 디렉토리의 모든 파일에 대해 :

find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \;
149.233333
130.146667
275.690000

다음 사용 paste하는 출력을 통과bc초 총 시간을 얻을 :

find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc
555.070000

따라서 .ts파일의 경우 다음을 시도 할 수 있습니다.

find . -maxdepth 1 -iname '*.ts' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc

여기에있는 비디오 파일에서 작동하는 다른 도구는 다음 exiftool과 같습니다.

exiftool -S -n Inception.mp4 | grep ^Duration
Duration: 275.69
exiftool -q -p '$Duration#' Inception.mp4
275.69

.mp4현재 디렉토리에있는 모든 파일의 총 길이 :

exiftool -S -n ./*.mp4 | awk '/^Duration/ {print $2}' | paste -sd+ -| bc
555.070000000000
exiftool -q -p '$Duration#' ./*.mp4 | awk '{sum += $0}; END{print sum}'
555.070000000000

또한 출력을 다른 명령으로 파이프하여 합계를로 변환 할 수도 있습니다 . 여기DD:HH:MM:SS 에서 답변을 참조 하십시오 .

또는에 exiftool내부 ConvertDuration를 사용하십시오 (상대적으로 최신 버전이 필요합니다).

exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
                    }' ./*.mp4| tail -n1
0:09:15

아주 좋은, ffprobe전에 그 트릭을 보지 못했다 .
slm

1
좋은 속임수 pastebc! awk말 보다 훨씬 더 깨끗 합니다.
fduff December

@fduff. bc임의의 정밀도를 수행 하지만 한 가지 단점은 ...| paste -sd+ - | bc일부 bc구현 에서 라인 크기 제한에 도달하거나 (예 : seq 429 | paste -sd+ - | bcOpenSolaris에서 실패 bc) 다른 메모리에서 모든 메모리를 사용할 가능성이 있다는 것입니다.
Stéphane Chazelas

avconv와 같은 방법으로 이것을 할 수 있습니까 (ffprobe 방법)? Kubuntu 14.04에 대한 내 repos에서 ffmpeg를 찾을 수 없으므로 ffprobe가 없습니까? 나는 avprobe를 가지고 있지만 그 주장을 좋아하지 않습니다.
Joe

@Joe - 없음 avprobe(이과 충돌하기 때문에 prolly 아치 REPOS에서이 ffmpeg) 그래서 그것을 ATM을 시도 할 수 있지만,이처럼 실행하면 그것은 당신에게 파일의 지속 시간을 제공 않습니다 avprobe -show_format_entry duration myfile.mp4avprobe -loglevel quiet -show_format_entry duration myfile.mp4? 이 명령 중 하나가 파일 지속 시간이있는 단일 출력 줄을 제공해야한다고 생각합니다. 그래도 확실하지 않습니다.
don_crissti

6

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 계산기로 파이프합니다.


1
좋은! 또한 귀하의 아이디어에 크게 의존하는 내 버전 을 참조하십시오 .
MvG December

짧고 우아한 솔루션
Neo

4

간소화 jmunsch의 대답 @ 및 사용 paste단지에서 배운 I @ 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입니다. 초 뒤의 쉼표는 my를 방해하지 않지만 awk누군가 문제가있는 경우 와 tr -d ,사이의 파이프 라인에를 포함 할 수 있습니다 .ffmpegawk

이제는 slm에서 나온 부분입니다. paste개행을 더하기 기호로 바꾸는 데 사용 하지만 후행 줄 바꿈에는 영향을 미치지 않습니다 ( 이 답변 의 이전 버전tr \\n + 에서와 달리 ). 그것은 식을 제공 할 수있는 합계 식을 제공합니다 .bc

date시간과 같은 형식을 처리하는 데 사용하는 slm의 아이디어에서 영감을 얻은 다음은 소수 부분을 사용하여 결과 초를 일, 시간, 분 및 초로 형식화하는 버전입니다.

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 일로 이어지기 때문에 1 년을 뺀 것입니다. 저는 0에서 시작하는 연도의 카운트를 얻는 방법이 없다고 생각합니다.

마지막은 sed별도의 후행 제로를 제거한다. 이 TZ설정은 UTC 사용을 강요하여 일광 절약 시간이 실제로 큰 비디오 컬렉션을 방해하지 않도록해야 합니다. 1 년 분량의 비디오가 있다면이 방법은 여전히 ​​작동하지 않습니다.


3

.ts확장명에 익숙하지 않지만 파일 형식을 가정 ffmpeg하여 파일의 지속 시간을 식별하는 데 사용할 수 있다고 가정 합니다.

$ ffmpeg -i some.mp4 2>&1 | grep Dura
  Duration: 00:23:17.01, start: 0.000000, bitrate: 504 kb/s

그런 다음 지속 시간 만 선택하여이 출력을 분할 할 수 있습니다.

$ ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
00:23:17.01

이제 파일을 반복하고 이러한 지속 시간 값을 수집하는 방법이 필요합니다.

$ for i in *.mp4; do
    ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"; done
00:23:17.01
00:23:17.01
00:23:17.01

참고 : 여기 내 예를 들어 나는 단지 내 샘플 파일을 복사 some.mp4하고 이름 1.mp4, 2.mp4하고 3.mp4.

시간을 초로 변환

다음 스 니펫은 위에서부터 지속 시간을 가져 와서 초로 변환합니다.

$ for i in *.mp4; do 
    dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
    date -ud "1970/01/01 $dur" +%s; done
1397
1397
1397

$dur파일을 반복하면서 지속 시간을 가져와 변수에 넣습니다 . date그런 다음 이 명령을 사용하여 Unix 신기원 (1970/01/01)을 사인하는 초 수를 계산합니다. 위의 date명령 은 다음과 같이 구분되어보다 쉽게 ​​볼 수 있습니다.

$ date -ud "1970/01/01 00:23:17.01" +%s
1397

참고 :date 이 방식으로 사용 하면 모든 파일의 지속 시간이 24 시간 미만 (예 : 86400 초) 인 경우에만 작동합니다. 더 긴 시간을 처리 할 수있는 것이 필요한 경우이를 대안으로 사용할 수 있습니다.

sed 's/^/((/; s/:/)*60+/g' | bc
$ echo 44:29:36.01 | sed 's/^/((/; s/:/)*60+/g' | bc
160176.01

총계

그런 다음 for루프 의 출력을 가져 와서 각 번호 사이에 부호를 paste포함 하는 명령 으로 실행할 +수 있습니다.

$ for i in *.mp4; do 
    dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
    date -ud "1970/01/01 $dur" +%s; done | paste -s -d+
1397+1397+1397

마지막으로 이것을 명령 줄 계산기로 실행 bc하여 요약합니다.

$ for i in *.mp4; do 
    dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
    date -ud "1970/01/01 $dur" +%s; done | paste -s -d+ | bc
4191

모든 파일의 총 지속 시간 (초). 물론 필요한 경우 다른 형식으로 변환 할 수도 있습니다.


@DamenSalvatore-문제 없음, 희망적으로 작업을 다양한 단계로 나눌 수있는 방법을 보여 주므로 필요에 따라 사용자 정의 할 수 있습니다.
slm

@slm-비디오 길이를 초 단위로 변환하는 다른 방법을 사용 합니다. 즉, 지속 시간이 ≥ 24 시간 / 86400 초인 date경우 질식 할 수 있습니다.ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"26:33:21.68
don_crissti

@ don_crissti-감사합니다. 테스트 할 때 20 시간 이상 시도하지 않았습니다. 다른 방법을 보여주는 메모를 추가하겠습니다.
slm

답변 주셔서 감사합니다! 뿐만 아니라 그것은 영감 않았다 뿐만 아니라 가져온 paste내 관심. 내가 추측이 java -classpath $(find -name \*.jar | paste -sd:)될 것입니다 매우 내가 과거에이 사용했던 해킹을 고려, 나에게 유용합니다.
MvG December

@MvG- paste내가 가장 좋아하는 명령입니다 8-)
slm

1

허용되는 답변을 없애고 고전적인 UNIX 리버스 툴을 사용하십시오.

{ find . -maxdepth 2 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 \
         -show_entries format=duration {} \; ; printf '+\n60\n*\np'; } | dc

783.493000

즉 : 그것을 적용 +하고 p파이핑 dc하면 합계를 얻을 수 있습니다.


2
bc너무 많은 사랑을 얻습니다. 당신은 모든 려구요 +(에 합류 각 라인 사이에 표시를 +하면 그냥 척 할 수 역 폴란드어 반면,) +말과 p그것을 RINT)
AT

0
$ find -iname '*.ts' -print0 |\
xargs -0  mplayer -vo dummy -ao dummy -identify 2>/dev/null |\
perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t += $1) && printf "%02d:%02d:%02d:%02d\n",$t/86400,$t/3600%24,$t/60%60,$t%60'

MPlayer가 설치되어 있는지 확인하십시오 .


그것은 나에게 어떤 출력도주지 않는다
k961

mplayer와 perl이 설치되어 있습니까?
ryanmjacobs

네, mplayer를 설치했고 펄은 이미 설치되었습니다
k961

1
죄송합니다. 왜 작동하지 않는지 모르겠습니다. 그러나 어쨌든 이미 충분한 대답이 이미 있습니다. :)
ryanmjacobs

0

ffmpeg 대신 우분투 선박 libav로 :

#!/bin/sh
for f in *.mp4; do
    avprobe -v quiet -show_format_entry duration "$f"
done | paste -sd+ | bc

MvG 아이디어 에 크게 기반


0

글쎄,이 모든 솔루션에는 약간의 작업이 필요합니다. 내가 한 일은 매우 간단했습니다. 1)

  1. 원하는 폴더로 이동하고 마우스 오른쪽 버튼을 클릭-> 다른 응용 프로그램으로 열기

  2. 그런 다음 VLC 미디어 플레이어를 선택하고

  3. 동영상 중 하나가 재생되기 시작 하지만
  4. ctrl + L을 누르면 비디오의 재생 목록이 표시되고 왼쪽 상단에 총 지속 시간이 표시됩니다

여기 예입니다

1. 목록 항목

2.여기에 이미지 설명을 입력하십시오

삼.여기에 이미지 설명을 입력하십시오

툴바 바로 아래에서 볼 수 있으며, 재생 목록 [10:35:51]이 작성되어 있으므로 폴더에는 총 비디오 시간이 10 시간 35 분 51 초입니다.


0

현재 폴더에 하위 디렉토리가 있으므로 기간을 재귀 적으로 계산해야했습니다.

find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.