루프에서 ffmpeg를 사용할 때 이상한 오류


23

찾은 결과를 반복하고 일부 FLV 파일의 ffmpeg 인코딩을 수행하는 bash 스크립트가 있습니다. 스크립트가 실행 중일 때 ffmpeg 출력이 혼동되어 아래에 표시된 것과 같이 이상한 모양의 오류가 출력됩니다. 나는 여기서 무슨 일이 일어나고 있는지 전혀 모른다. 누구든지 올바른 방향으로 나를 가리킬 수 있습니까?

ffmpeg 프로세스를 방해하지 않아야 할 때 루프가 여전히 실행중인 것처럼 보입니다.

구체적인 오류는 다음과 같습니다.

frame=   68 fps= 67 q=28.0 00000000000000000000000000001000size=      22kB time=00:00:00.50 bitrate= 363.2kbits/s dup=1 drop=0    
Enter command: <target> <time> <command>[ <argument>]
Parse error, at least 3 arguments were expected, only 1 given in string 'om/pt_br/nx/R3T4N2_HD3D_demoCheckedOut.flv'

ffmpeg 출력의 일부 세부 사항 :

[buffer @ 0xa30e1e0] w:800 h:600 pixfmt:yuv420p tb:1/1000000 sar:0/1 sws_param:flags=2
[libx264 @ 0xa333240] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.1 Cache64
[libx264 @ 0xa333240] profile High, level 3.1
[libx264 @ 0xa333240] 264 - core 122 r2184 5c85e0a - H.264/MPEG-4 AVC codec - Copyleft 2003-2012 - http://www.videolan.org/x264.html - options: cabac=1 ref=5 deblock=1:0:0 analyse=0x3:0x113 me=umh subme=8 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=50 rc=cbr mbtree=1 bitrate=500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 vbv_maxrate=500 vbv_bufsize=1000 nal_hrd=none ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to './mp4s/pt_br/teamcenter/tc8_interactive/videos/8_SRM_EN.mp4':
  Metadata:
    audiodelay      : 0
    canSeekToEnd    : true
    encoder         : Lavf54.3.100
    Stream #0:0: Video: h264 (![0][0][0] / 0x0021), yuv420p, 800x600, q=-1--1, 500 kb/s, 30k tbn, 29.97 tbc
    Stream #0:1: Audio: aac (@[0][0][0] / 0x0040), 44100 Hz, mono, s16, 128 kb/s
Stream mapping:
  Stream #0:1 -> #0:0 (vp6f -> libx264)
  Stream #0:0 -> #0:1 (mp3 -> libfaac)
Press [q] to stop, [?] for help
error parsing debug value0 00000000000000000000000000000000size=      13kB time=00:00:00.-3 bitrate=-3165.5kbits/s dup=1 drop=0    
debug=0
frame=   68 fps= 67 q=28.0 00000000000000000000000000001000size=      22kB time=00:00:00.50 bitrate= 363.2kbits/s dup=1 drop=0    
Enter command: <target> <time> <command>[ <argument>]
Parse error, at least 3 arguments were expected, only 1 given in string 'om/pt_br/nx/R3T4N2_HD3D_demoCheckedOut.flv'

스크립트는 다음과 같습니다

#!/bin/bash
LOGFILE=encodemp4ize.log
echo '' > $LOGFILE
STARTTIME=date
echo "Started at `$STARTTIME`" >> $LOGFILE
rsync -avz flvs/ mp4s/ --exclude '*.flv'
#find flvs/ -name "*.flv" > flv-files
# The loop
find flvs/ -name "*.flv" | while read f
do
FILENAME=`echo $f | sed 's#flvs/##'`
MP4FILENAME=`echo $FILENAME | sed 's#.flv#.mp4#'`
ffmpeg -i "$f" -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -threads 0 -acodec libfaac -ab 128k "./mp4s/$MP4FILENAME"
echo "$f MP4 done" >> $LOGFILE
done

나는 많은 스크립터는 아니지만 명백한 제안-스크립트가 실행중인 줄을 인쇄하도록하십시오. 그들은 당신이 생각하는 것과 다를 수 있습니다.
Faheem Mitha

측면의 문제로 : mp4filename=$(basename "$f" mp4)유용 (볼 수 있습니다 man basenameman dirname추가 정보를 원하시면)
Peter.O

bash -x myscript모든 변수 확장과 함께, 스크립트의 실행을 위해 라인 추적을 얻을 수 있습니다. 아, 그리고 우연히, 당신은 선에 basename바퀴를 재발견했습니다 FILENAME=. :)
Warren Young

1
해결책을 찾았습니다. bash 스크립트는 ffmpeg 프로세스를 방해하는 제품 입력 (즉 'c'키)으로 보입니다. "</ dev / null"을 ffmpeg로 파이핑 : ffmpeg -i "./$f"-vcodec libx264 -vprofile high -preset slow -b : v 500k -maxrate 500k -bufsize 1000k -threads 0 -acodec libfaac -ab 128k "./mp4s/$MP4FILENAME"</ dev / null 문제를 해결합니다. [ linuxquestions.org/questions/programming-9/… [1]을 통해 : linuxquestions.org/questions/programming-9/…
Mark Williams

답변:


56

귀하의 질문은 실제로 Bash FAQ # 89입니다 : 표준 입력을 읽지 </dev/null못하게하기 위해 추가하십시오 ffmpeg.


스크립트에 많은 잠재적 오류가 포함되어 있기 때문에 스크립트를 자유롭게 고칠 수 있습니다. 중요한 몇 가지 사항 :

  • 대부분의 파일 시스템은 보통 사람들이 볼 수있는 모든 종류의 인쇄 할 수없는 문자를 가비지로 포함 할 수 있기 때문에 파일 이름을 다루기가 까다 롭습니다. "파일 이름에 '일반적인'문자 만 포함됨"과 같은 간단한 가정을하면 깨지기 쉬운 쉘 스크립트가 나타납니다."일반적인"파일 이름으로 작업 한 다음 스크립트의 가정을 따르지 않는 특히 불쾌한 파일 이름을 사용하는 날을 깰 수 있습니다. 반면, 파일 이름을 올바르게 처리하면 이상한 파일 이름이 발생할 가능성이 거의 없을 것으로 예상되는 경우 노력할 가치가 없다는 것을 알 수 있습니다 (예 : 자신의 파일에서만 스크립트를 사용하고 자신의 파일에 "간단한"이름을 지정하십시오). 때때로 파일 이름을 파싱하지 않음으로써이 결정을 완전히 피할 수 있습니다. 다행히도 find(1)-exec옵션으로 가능합니다 . 그냥 넣어 {}의 인수에 -exec당신은 구문 분석에 대해 걱정하지 않아도 find출력을.

  • sed확장 및 접두사 제거와 같은 간단한 문자열 작업을 수행하기 위해 또는 다른 외부 프로세스를 사용하는 것은 비효율적입니다. 대신, 쉘의 일부인 매개 변수 확장을 사용하십시오 (외부 프로세스가 없으면 더 빠를 것입니다). 해당 주제에 대한 유용한 기사는 다음과 같습니다.

  • 를 사용 $( )하고 ``더 이상 사용하지 마십시오 : Bash FAQ 82 .

  • 대문자 변수 이름을 사용하지 마십시오. 이 네임 스페이스는 일반적으로 (와 같은 PATH) 특별한 목적을 위해 쉘에 의해 예약되어 있으므로 자신의 변수에 사용하는 것은 좋지 않습니다.

이제 더 이상 고민하지 말고 정리 된 스크립트를 작성하십시오.

#!/bin/sh

logfile=encodemp4ize.log
echo "Started at $(date)." > "$logfile"
rsync -avz --exclude '*.flv' flvs/ mp4s/

find flvs/ -type f -name '*.flv' -exec sh -c '
for flvsfile; do
    file=${flvsfile#flvs/}
    < /dev/null ffmpeg -i "$flvsfile" -vcodec libx264 -vprofile high \
        -preset slow -b:v 500k -maxrate 500k -bufsize 1000k \
        -threads 0 -acodec libfaac -ab 128k \
        "mp4s/${file%flv}"mp4
    printf %s\\n "$flvsfile MP4 done." >> "$logfile"
done
' _ {} +

참고 : 원본에서 특정 기능을 sh사용하지 않았거나 필요하지 않기 때문에 POSIX를 사용했습니다 bash.


3
훌륭한 답변입니다! 수정 된 스크립트를 작성해 주셔서 감사합니다. zsh에 대한 Greg의 Wiki 안내서와 비슷한 것이 궁금하십니까? 감사!
Art

1
@Art 죄송합니다 zsh. 에 대해 잘 모릅니다 . 어쩌면 사이트의 일부 zsh 사람들이 알고있을 것입니다.
jw013

문제는 나중에 ffmpeg가 오류를 생성하여 스크립트를 다운 다운하여 변환 된 파일의 이전 버전을 지 울지 여부를 결정해야한다는 것입니다. Plex Media Server의 경우 mkv를 mp4로 변환하고 있습니다. 큰 mkv 파일로 말더듬을 만들었으므로 모든 mkv를 mp4로 변환하기로 결정했습니다. 또 다른 문제는 그림 기반 형식에 대한 자막 스트림 변환 실패를 확인해야한다는 것입니다.이 경우 다른 절차를 사용하여 자막을 추출합니다. 그렇다면 어떻게 ffmpeg를 실행하고 출력을 얻으며이 문제가 발생하지 않습니까?
dacabdi

15

해결책을 찾았 습니다 . bash 스크립트는 ffmpeg프로세스 를 방해하는 입력 (즉, 'c'키)을 생성하는 것으로 보입니다 .

다음 과 같이 명령 행에 추가 < /dev/null하십시오 ffmpeg.

ffmpeg -i "./$f" -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -threads 0 -acodec libfaac -ab 128k "./mp4s/$MP4FILENAME" < /dev/null

문제를 해결합니다.

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