एक लूप में ffmpeg का उपयोग करते समय अजीब त्रुटियां


23

मैं एक खोज के परिणामों के माध्यम से एक 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'

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=। :)
वॉरेन यंग

1
मैंने इसका हल ढूंढ लिया है। बैश स्क्रिप्ट उत्पाद इनपुट के लिए लगता है (अर्थात् 'सी' कुंजी) जो ffmpeg प्रक्रिया के साथ हस्तक्षेप करता है। पाइपिंग "</ dev / null" को ffmpeg में जैसे: ffmpeg -i "./$f" -vcodec libx264 -vprofile high -preset slow -b: v 500k -maxaxize 500k -bufsize 1000k -चेबुड 0 -acodec libfaac -ab 128k "./mp4s/$MP4FILENAME" </ dev / null समस्या को हल करता है। के माध्यम से [ linuxquestions.org/questions/programming-9/… [1]: linuxquestions.org/questions/programming-9/…
मार्क विलियम्स

जवाबों:


56

आपका प्रश्न वास्तव में बैश FAQ # 89 है : बस इसके मानक इनपुट को पढ़ने से </dev/nullरोकने के लिए जोड़ें ffmpeg


मैंने आपके लिए अपनी स्क्रिप्ट को ठीक करने की स्वतंत्रता ले ली है क्योंकि इसमें बहुत सारी संभावित त्रुटियाँ हैं। कुछ महत्वपूर्ण बिंदु:

  • फ़ाइलनामों को संभालना मुश्किल है, क्योंकि अधिकांश फाइल सिस्टम उन्हें सभी प्रकार के अनजाने पात्रों को शामिल करने की अनुमति देता है, जिन्हें सामान्य लोग कचरा के रूप में देखेंगे। "फ़ाइल नाम" जैसी सरल मान्यताओं को बनाने में केवल 'सामान्य' वर्ण होते हैं, जो दिखने वाली नाजुक शेल स्क्रिप्ट का परिणाम देते हैं"सामान्य" फ़ाइल नामों पर काम करने के लिए और फिर दिन को तोड़कर वे एक विशेष रूप से गंदा फ़ाइल नाम में भाग लेते हैं जो स्क्रिप्ट की मान्यताओं का पालन नहीं करता है। दूसरी ओर, फ़ाइल नामों को सही ढंग से संभालना एक ऐसी परेशानी हो सकती है कि आप इसे इस लायक नहीं पा सकते हैं कि अगर किसी अजीब फ़ाइल के नाम का सामना करने का मौका शून्य के पास होने की उम्मीद है (यानी आप केवल अपनी फ़ाइलों पर स्क्रिप्ट का उपयोग करते हैं और आप अपनी खुद की फ़ाइलें "सरल" नाम देते हैं)। कभी-कभी फ़ाइल के नामों को बिल्कुल भी पार्स न करके इस निर्णय से बचना संभव है। सौभाग्य से, उस के साथ संभव है find(1)की -execविकल्प। बस {}तर्क में डाल दिया -execऔर आप पार्स findउत्पादन के बारे में चिंता करने की जरूरत नहीं है ।

  • sedस्ट्रिपिंग एक्सटेंशन और उपसर्ग जैसे सरल स्ट्रिंग ऑपरेशन करने के लिए अन्य बाहरी प्रक्रियाओं का उपयोग करना अक्षम है। इसके बजाय, पैरामीटर विस्तार का उपयोग करें जो शेल का हिस्सा हैं (कोई बाहरी प्रक्रिया का मतलब यह तेज नहीं होगा)। विषय पर कुछ उपयोगी लेख नीचे सूचीबद्ध हैं:

  • उपयोग करें $( ), और ``अब और उपयोग न करें : बैश FAQ 82

  • UPPERCASE चर नामों का उपयोग करने से बचें। वह नेमस्पेस आम तौर पर विशेष उद्देश्यों (जैसे 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
' _ {} +

नोट: मैंने POSIX का उपयोग किया shक्योंकि आपने bashअपने मूल में किसी भी विशिष्ट सुविधाओं का उपयोग या आवश्यकता नहीं की थी ।


3
यह एक शानदार जवाब है! सही स्क्रिप्ट लिखने के प्रयास के लिए धन्यवाद। बस आश्चर्य है कि क्या ग्रेग का विकी गाइड zsh के समान है? धन्यवाद!
आर्ट

1
@Art क्षमा करें, मुझे इस बारे में बहुत जानकारी नहीं है zsh। शायद साइट पर मौजूद zsh के कुछ लोगों को पता होगा।
jw013

समस्या यह है कि मुझे यह जांचने की आवश्यकता है कि क्या ffmpeg बाद में स्क्रिप्ट के निर्णय के लिए एक त्रुटि उत्पन्न कर रहा है या नहीं, परिवर्तित फ़ाइल के पिछले संस्करण को मिटा देना चाहिए। मैं एक plex Media Server के लिए mkv को mp4 में परिवर्तित कर रहा हूं। मेरे पास बड़ी mkv फ़ाइलों के साथ हकलाना है, इसलिए मैंने सभी mkv को mp4 में बदलने का फैसला किया। एक और समस्या यह है कि मुझे चित्र आधारित प्रारूपों के लिए उपशीर्षक स्ट्रीम रूपांतरण विफलता की जांच करने की आवश्यकता है, जिस स्थिति में मैं उप को निकालने के लिए किसी अन्य असफल का उपयोग करता हूं। तो, मैं ffmpeg कैसे चलाऊं, इसका आउटपुट प्राप्त करूं, और इस मुद्दे पर नहीं चलूं?
डकबाड़ी

15

मैंने इसका हल ढूंढ लिया है । बैश स्क्रिप्ट इनपुट उत्पन्न करने के लिए लगता है (अर्थात् 'सी' कुंजी) जो ffmpegप्रक्रिया में हस्तक्षेप करती है।

जोड़ने < /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

समस्या को हल करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.