我有一个 bash 脚本循环查找的结果并执行一些 FLV 文件的 ffmpeg 编码。虽然脚本正在运行 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'
Run Code Online (Sandbox Code Playgroud)
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'
Run Code Online (Sandbox Code Playgroud)
脚本如下
#!/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
Run Code Online (Sandbox Code Playgroud)
jw0*_*013 67
您的问题实际上是Bash FAQ #89:只需添加</dev/null
以防止ffmpeg
读取其标准输入。
我冒昧地为您修复了您的脚本,因为它包含许多潜在的错误。几个重要的点:
文件名处理起来很棘手,因为大多数文件系统允许它们包含普通人会认为是垃圾的各种无法打印的字符。做出诸如“文件名仅包含‘正常’字符”之类的简化假设,往往会导致出现脆弱的 shell 脚本处理“正常”文件名,然后打破他们遇到不符合脚本假设的特别讨厌的文件名的那一天。另一方面,正确处理文件名可能会很麻烦,如果遇到奇怪文件名的机会预计接近零(即您只在自己的文件上使用脚本,并且你给自己的文件“简单”的名字)。有时可以通过根本不解析文件名来完全避免这个决定。幸运的是,这可以通过find(1)
's-exec
选项实现。只需{}
输入 to 参数-exec
,您就不必担心解析find
输出。
使用sed
或 其他外部进程来执行简单的字符串操作(如剥离扩展名和前缀)是低效的。相反,使用作为 shell 一部分的参数扩展(没有外部进程意味着它会更快)。下面列出了有关该主题的一些有用文章:
使用$( )
,不再使用``
:
Bash FAQ 82。
避免使用大写变量名。该命名空间通常由 shell 保留用于特殊目的(如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
' _ {} +
Run Code Online (Sandbox Code Playgroud)
注意:我使用 POSIXsh
是因为您没有使用或需要bash
原始文件中的任何特定功能。
Mar*_*ams 20
我找到了解决方案。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
Run Code Online (Sandbox Code Playgroud)
解决了这个问题。
归档时间: |
|
查看次数: |
17958 次 |
最近记录: |