У меня есть скрипт bash, который просматривает результаты поиска и выполняет кодирование ffmpeg некоторых файлов FLV. Во время работы скрипта вывод 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
mp4filename=$(basename "$f" mp4)
может быть полезно (см.man basename
Иman dirname
для получения дополнительной информации)bash -x myscript
чтобы получить построчную трассировку выполнения скрипта со всеми переменными. Ох, и, кстати, вы заново изобрелиbasename
колесо наFILENAME=
линии. :)Ответы:
Ваш вопрос на самом деле Bash FAQ # 89 : просто добавьте,
</dev/null
чтобы неffmpeg
читать его стандартный ввод.Я позволил себе исправить ваш сценарий, потому что он содержит много потенциальных ошибок. Несколько важных моментов:
Имена файлов сложны в обращении, потому что большинство файловых систем позволяют им содержать всевозможные непечатаемые символы, которые обычные люди видят как мусор. Создание упрощающих допущений типа «имена файлов содержат только« нормальные »символы» приводит к появлению хрупких сценариев оболочки, которые появляютсяработать с «нормальными» именами файлов, а затем разбивать день, когда они сталкиваются с особенно неприятным именем файла, которое не соответствует предположениям сценария. С другой стороны, правильная обработка имен файлов может быть такой проблемой, что вам может показаться, что это не стоит усилий, если ожидается, что вероятность встретить странное имя файла будет близка к нулю (т.е. вы используете сценарий только для своих собственных файлов и вы даете своим файлам "простые" имена). Иногда можно вообще избежать этого решения, вообще не анализируя имена файлов. К счастью, это возможно с
find(1)
«S-exec
варианта. Просто введите{}
аргумент,-exec
и вам не нужно беспокоиться о разбореfind
вывода.Использование
sed
или других внешних процессов для выполнения простых строковых операций, таких как удаление расширений и префиксов, неэффективно. Вместо этого используйте расширения параметров, которые являются частью оболочки (никакой внешний процесс не означает, что это будет быстрее). Некоторые полезные статьи по этой теме перечислены ниже:Используйте
$( )
и больше не используйте``
: Bash FAQ 82 .Избегайте использования имен переменных UPPERCASE. Это пространство имен обычно резервируется оболочкой для специальных целей (например
PATH
), поэтому использование его для собственных переменных - плохая идея.А теперь, без лишних слов, вот вам очищенный скрипт:
Примечание: я использовал POSIX,
sh
потому что вы не использовали или не нуждались в каких-либоbash
специфических функциях в вашем оригинале.источник
zsh
. Может быть, некоторые из zsh людей на сайте узнают.Я нашел решение . Сценарий bash, кажется, производит ввод (а именно ключ 'c'), который мешает
ffmpeg
процессу.Добавляем
< /dev/null
вffmpeg
командную строку, вот так:устраняет проблему
источник