Tengo un script bash que recorre los resultados de una búsqueda y realiza una codificación ffmpeg de algunos archivos FLV. Mientras el script se está ejecutando, la salida de ffmpeg parece estar interrumpida y está generando algunos errores de aspecto extraño como el siguiente. No tengo idea de lo que está pasando aquí. ¿Alguien puede señalarme en la dirección correcta?
Es como si el ciclo todavía se estuviera ejecutando cuando no debería estar e interrumpiendo el proceso ffmpeg.
El error específico es:
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'
Algunos detalles más de la salida 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'
El guión es el siguiente
#!/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)
podría ser útil (verman basename
yman dirname
para más información)bash -x myscript
para obtener un seguimiento línea por línea de la ejecución del script, con todas las variables expandidas. Ah, y por cierto, has reinventado labasename
rueda en laFILENAME=
línea. :)Respuestas:
Su pregunta es en realidad Bash FAQ # 89 : solo agregue
</dev/null
para evitarffmpeg
leer su entrada estándar.Me he tomado la libertad de arreglar tu script porque contiene muchos errores potenciales. Algunos de los puntos importantes:
Los nombres de archivo son difíciles de manejar, porque la mayoría de los sistemas de archivos les permite contener todo tipo de caracteres no imprimibles que la gente normal vería como basura. Hacer suposiciones simplificadoras como "los nombres de archivo contienen solo caracteres 'normales'" tiende a generar scripts de shell frágiles que aparecenpara trabajar en nombres de archivo "normales" y luego romper el día en que se encuentran con un nombre de archivo particularmente desagradable que no sigue los supuestos del script. Por otro lado, manejar correctamente los nombres de los archivos puede ser tan molesto que es posible que no valga la pena el esfuerzo si se espera que la posibilidad de encontrar un nombre de archivo extraño sea cercana a cero (es decir, solo usa el script en sus propios archivos y le das a tus propios archivos nombres "simples"). A veces es posible evitar esta decisión por completo al no analizar los nombres de los archivos. Afortunadamente, eso es posible con
find(1)
la-exec
opción de. Simplemente ponga{}
el argumento-exec
ay no tendrá que preocuparse por analizar lafind
salida.Usar
sed
u otros procesos externos para realizar operaciones de cadena simples como quitar extensiones y prefijos es ineficiente. En su lugar, use expansiones de parámetros que son parte del shell (ningún proceso externo significa que será más rápido). A continuación se enumeran algunos artículos útiles sobre el tema:Usar
$( )
y no usar``
más: Bash FAQ 82 .Evite usar los nombres de las variables MAYÚSCULAS. Ese espacio de nombres generalmente está reservado por el shell para fines especiales (como
PATH
), por lo que usarlo para sus propias variables es una mala idea.Y ahora, sin más preámbulos, aquí hay un script limpio para usted:
Nota: Usé POSIX
sh
porque nobash
usaste o no necesitabas características específicas en tu original.fuente
zsh
. Tal vez algunas de las personas zsh en el sitio lo sabrían.He encontrado la solución . El script bash parece producir una entrada (principalmente la tecla 'c') que interfiere con el
ffmpeg
proceso.Agregando
< /dev/null
a laffmpeg
línea de comando, así:soluciona el problema.
fuente