J'ai un script bash parcourant les résultats d'une recherche et effectuant un encodage ffmpeg de certains fichiers FLV. Pendant que le script s'exécute, la sortie ffmpeg semble être interrompue et génère des erreurs étranges comme celle ci-dessous. Je n'ai aucune idée de ce qui se passe ici. Est-ce que quelqu'un peut-il me montrer la bonne direction?
C'est comme si la boucle était toujours en cours d'exécution alors qu'elle ne devrait pas l'être et interrompant le processus ffmpeg.
L'erreur spécifique est:
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'
Quelques détails supplémentaires sur la sortie 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'
Le script est le suivant
#!/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)
pourrait être utile (voirman basename
etman dirname
pour plus d'informations)bash -x myscript
pour obtenir une trace ligne par ligne de l'exécution du script, avec toutes les variables développées. Oh, et d'ailleurs, vous avez réinventé labasename
roue sur laFILENAME=
ligne. :)Réponses:
Votre question est en fait Bash FAQ # 89 : ajoutez simplement
</dev/null
pour empêcherffmpeg
de lire son entrée standard.J'ai pris la liberté de réparer votre script pour vous car il contient beaucoup d'erreurs potentielles. Quelques points importants:
Les noms de fichiers sont difficiles à gérer, car la plupart des systèmes de fichiers leur permettent de contenir toutes sortes de caractères non imprimables que les gens normaux considéreraient comme des ordures. Faire des hypothèses simplificatrices comme «les noms de fichiers ne contiennent que des caractères« normaux »» tend à produire des scripts shell fragiles qui apparaissentpour travailler sur des noms de fichiers "normaux", puis casser le jour où ils tombent sur un nom de fichier particulièrement méchant qui ne suit pas les hypothèses du script. D'un autre côté, une gestion correcte des noms de fichiers peut être si gênante que vous pouvez trouver que cela ne vaut pas la peine si la chance de rencontrer un nom de fichier étrange est proche de zéro (c'est-à-dire que vous n'utilisez le script que sur vos propres fichiers et vous donnez à vos propres fichiers des noms "simples"). Il est parfois possible d'éviter complètement cette décision en n'analysant pas du tout les noms de fichiers. Heureusement, c'est possible avec
find(1)
l'-exec
option de. Mettez simplement{}
l'argument dans-exec
et vous n'avez pas à vous soucier de l'analyse de lafind
sortie.L'utilisation de
sed
ou d'autres processus externes pour effectuer des opérations de chaîne simples comme supprimer les extensions et les préfixes est inefficace. Utilisez plutôt des extensions de paramètres qui font partie du shell (aucun processus externe ne signifie qu'il sera plus rapide). Quelques articles utiles sur le sujet sont listés ci-dessous:Utilisez
$( )
et n'utilisez``
plus: Bash FAQ 82 .Évitez d'utiliser des noms de variable UPPERCASE. Cet espace de noms est généralement réservé par le shell à des fins spéciales (comme
PATH
), donc l'utiliser pour vos propres variables est une mauvaise idée.Et maintenant, sans plus tarder, voici un script nettoyé pour vous:
Remarque: J'ai utilisé POSIX
sh
parce que vous n'avez pas utilisé ou n'avez pas besoin debash
fonctionnalités spécifiques à votre original.la source
zsh
. Peut-être que certaines des personnes zsh sur le site le sauraient.J'ai trouvé la solution . Le script bash semble produire une entrée (à savoir la touche «c») qui interfère avec le
ffmpeg
processus.Ajout
< /dev/null
à laffmpeg
ligne de commande, comme ceci:résout le problème.
la source