Mam skrypt bash zapętlający wyniki wyszukiwania i wykonujący kodowanie ffmpeg niektórych plików FLV. Podczas działania skryptu wydaje się, że dane wyjściowe ffmpeg zostały przerwane i generują dziwnie wyglądające błędy, takie jak ten poniżej. Nie mam pojęcia, co się tutaj dzieje. Czy ktoś może skierować mnie we właściwym kierunku?
To tak, jakby pętla nadal działała, kiedy nie powinna, i zakłócała proces ffmpeg.
Konkretny błąd to:
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'
Kilka dodatkowych szczegółów z wyjścia 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'
Skrypt jest następujący
#!/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
mp4filename=$(basename "$f" mp4)
może być przydatna (patrzman basename
iman dirname
więcej informacji)bash -x myscript
aby uzyskać liniowe śledzenie wykonania skryptu z rozszerzonymi wszystkimi zmiennymi. Aha, nawiasem mówiąc, na nowo wymyśliłeśbasename
koło naFILENAME=
linii. :)Odpowiedzi:
Twoje pytanie to tak naprawdę Bash FAQ # 89 : wystarczy dodać,
</dev/null
aby uniemożliwićffmpeg
odczytanie jego standardowego wejścia.Pozwoliłem ci naprawić skrypt, ponieważ zawiera on wiele potencjalnych błędów. Kilka ważnych punktów:
Nazwy plików są trudne w obsłudze, ponieważ większość systemów plików pozwala im zawierać wszelkiego rodzaju niedrukowalne znaki, które zwykli ludzie postrzegaliby jako śmieci. Wprowadzanie uproszczeń, takich jak „nazwy plików zawierają tylko„ normalne ”znaki”, powoduje, że pojawiają się delikatne skrypty powłokiaby pracować nad „normalnymi” nazwami plików, a następnie zepsuć dzień, gdy napotkają szczególnie nieprzyjemną nazwę pliku, która nie spełnia założeń skryptu. Z drugiej strony, prawidłowe posługiwanie się nazwami plików może być tak kłopotliwe, że może nie być warte wysiłku, jeśli prawdopodobieństwo napotkania dziwnej nazwy pliku będzie bliskie zeru (tj. Używasz skryptu tylko dla własnych plików i nadajesz swoim plikom „proste” nazwy). Czasami można całkowicie uniknąć tej decyzji, nie analizując w ogóle nazw plików. Na szczęście, jest to możliwe z
find(1)
„s-exec
opcja. Po prostu wstaw{}
argument-exec
i nie musisz się martwić analizowaniemfind
danych wyjściowych.Używanie
sed
lub innych zewnętrznych procesów do wykonywania prostych operacji na łańcuchach, takich jak usuwanie rozszerzeń i prefiksów, jest nieefektywne. Zamiast tego użyj rozszerzeń parametrów, które są częścią powłoki (brak zewnętrznego procesu oznacza, że będzie szybszy). Niektóre pomocne artykuły na ten temat są wymienione poniżej:Używaj
$( )
i nie używaj``
już: Bash FAQ 82 .Unikaj używania nazw zmiennych UPPERCASE. Ta przestrzeń nazw jest ogólnie zarezerwowana przez powłokę do specjalnych celów (np.
PATH
), Więc używanie jej do własnych zmiennych jest złym pomysłem.A teraz, bez zbędnych ceregieli, oto oczyszczony skrypt dla Ciebie:
Uwaga: Użyłem POSIX,
sh
ponieważ niebash
używałeś ani nie potrzebowałeś żadnych specyficznych funkcji w swoim oryginale.źródło
zsh
. Może niektórzy ludzie zsh na stronie będą wiedzieć.Znalazłem rozwiązanie . Wydaje się, że skrypt bash generuje dane wejściowe (mianowicie klawisz „c”), które zakłócają
ffmpeg
proces.Dodanie
< /dev/null
doffmpeg
wiersza poleceń, tak:naprawia problem.
źródło