출력에서 일부 정보 추출

출력에서 일부 정보 추출

ffmpeg 출력에서 ​​일부 정보를 추출하려고 합니다.

ffmpeg 출력 예:

configuration:  --enable-memalign-hack --enable-mp3lame --enable-gpl --disable-vhook --disable-ffplay --disable-ffserver --enable-a52 --enable-xvid --enable-faac --enable-faad --enable-amr_nb --enable-amr_wb --enable-pthreads --enable-x264 
libavutil version: 49.0.0
libavcodec version: 51.9.0
libavformat version: 50.4.0
built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build 5250)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file.mov':
Duration: 00:01:32.0, start: 0.000000, bitrate: 63489 kb/s
Stream #0.0(eng): Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream #0.1(eng), 29.97 fps(r): Video: Apple ProRes 422, 1280x720
Must supply at least one output file

지속 시간, 프레임 속도, 코덱 및 크기만 포함하는 문자열을 반환하고 싶습니다. 예를 들면 다음과 같습니다.

[00:01:32_29.97_Apple ProRes 422_1280x720]

나는 이것부터 시작하려고 했습니다(다른 팁에서):

ffmpeg -i file.mov 2>&1 | sed -n 's/Duration: \(.*\), start/\1/gp'

기간을 얻으십시오. 그러나 이것은 단지 Durationand 를 "제거"합니다 , start. 즉:

00:01:32.0: 0.000000, bitrate: 63489 kb/s

Apple추신: 또한 그것을 제거 하고 싶습니다 Apple ProRes 422:-)

감사해요!

업데이트: 다음 명령을 사용하여 코덱을 추출할 수 있었습니다.

sed -n "s/.*\Video: \(.*\),.*/\1/p"

하지만 (a) 크기와 프레임 속도를 얻는 방법과 (b) 검색을 한 줄로 결합하는 방법을 모르겠습니다...

답변1

awk: 마법과 같지만 더 좋습니다.

#!/usr/bin/awk -f
/Duration/ {sub(/,/, "", $2); fields["dur"] = $2}
/fps/ { fields["fps"] = $3 }
/Video/ { 
        sub(/.*Video:/, "", $0);
        sub(/\W*Apple\W*/, "", $0);
        split($0, arr, ", ")
        fields["codec"] = arr[1]; 
        fields["res"] = arr[2]; 
}
END {
        printf "[%s_%s_%s_%s]\n", 
                fields["dur"], 
                fields["fps"], 
                fields["codec"],  
                fields["res"]
}

답변2

sed에서 한 줄의 일부를 추출하려면 전체 줄을 일치시키고 역참조를 사용하여 유지하려는 비트를 인쇄하세요. (sed에 \+연산자가 없으면 foo*대신 을 사용하십시오 fo\+.)

$ … | sed -n -e 's/^.*Duration: *\([^,]*\).*$/\1/p' \
             -e 's/^.* \([0-9.]\+\) fps(r).* Video: \([^,]\+\).*, *\([0-9]\+x[0-9]\+\).*$//'
00:01:32.0
29.97 Apple ProRes 422 1280x720

어떤 텍스트가 어떤 그룹에 들어갈지 결정하는 방법이 여러 가지인 경우 이전 그룹의 길이가 최대한 길어집니다. 예를 들어, 두 번째 표현식의 시작 부분에서 는 ^.* \([0-9.]\+\) fps공백 뒤의 숫자와 일치합니다. 표현식이 이면 ^.*\([0-9.]\+\) fps그룹 내의 숫자 하나만 일치하고 이전 숫자는 흡수됩니다 .*. 대신, 두 번째 표현식 끝에는 더 이상 일치하는 항목이 없을 때, 즉 첫 번째 숫자가 아닌 숫자 이후에만 시작하여 \([0-9]\+\).*$그룹 내부에 모든 숫자를 넣습니다 ..*[0-9]\+

가능하지만 sed는 여러 줄을 결합하거나 후처리를 수행하는 데 능숙하지 않습니다. 단순한 텍스트 교체 이상의 기능이 필요한 경우awk로 전환.

답변3

동일한 sed명령에 여러 표현식을 추가할 수 있습니다. 비디오 팝에서 "Apple"을 추출하기 위해 무언가를 추가하면 여전히 두 일치 항목과 대체 항목이 모두 인쇄됩니다.

유일한 문제는 서로 다른 두 줄로 인쇄된다는 점이지만, 언제든지 |xargs echo더 우아하게 인쇄할 수 있습니다.

답변4

sedwith -e옵션을 사용하여 다음과 같이 여러 조건을 결합 할 수 있습니다 .

sed -e <expression1> -e <expression2> ...

관련 정보