FFmpeg का उपयोग करके दो MP4 फ़ाइलों को कैसे संक्षिप्त करें?


443

मैं ffmpeg का उपयोग करके दो mp4 फाइलों को समाप्‍त करने की कोशिश कर रहा हूं। मुझे इसकी स्वचालित प्रक्रिया की आवश्यकता है इसलिए मैंने ffmpeg को चुना। मैं दो फाइलों को .ts फाइलों में परिवर्तित कर रहा हूं और फिर उन्हें संक्षिप्त कर रहा हूं और फिर उस .ts फाइल को एनकोड करने की कोशिश कर रहा हूं। फ़ाइलें h264 हैं और aac एन्कोडेड हैं और मैं गुणवत्ता को यथासंभव या मूल के करीब रखने की उम्मीद कर रहा हूं।

ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4

दुर्भाग्य से मैं निम्नलिखित त्रुटि संदेश ffmpeg से एन्कोडिंग के दौरान वापस आ रहा हूँ:

[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s    
av_interleaved_write_frame(): Error while opening file

यह एन्कोडिंग के माध्यम से आधे रास्ते के बारे में होता है जो मुझे लगता है कि आप दो .ts फ़ाइलों को एक साथ नहीं रख सकते हैं और यह काम कर सकता है।

जवाबों:


786

FFmpeg में तीन संघटन विधियाँ हैं:

1. समतल वीडियो फिल्टर

यदि आपके इनपुट में समान पैरामीटर (चौड़ाई, ऊंचाई, आदि) नहीं हैं, या समान प्रारूप / कोडेक्स नहीं हैं, या यदि आप कोई फ़िल्टर करना चाहते हैं तो इस विधि का उपयोग करें। (आप बस उन इनपुटों को फिर से एनकोड कर सकते हैं जो मेल नहीं खाते हैं इसलिए वे समान कोडेक और अन्य मापदंडों को साझा करते हैं, फिर अन्य इनपुटों को फिर से एन्कोडिंग करने से बचने के लिए कॉनकैट डिमॉक्सर का उपयोग करें)।

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
       -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] 
                        concat=n=3:v=1:a=1 [v] [a]" \
       -map "[v]" -map "[a]" output.mkv

ध्यान दें कि यह विधि फिर से एनकोड करती है।

2. कॉनकैट डिमॉक्सर

इस पद्धति का उपयोग तब करें जब आप पुनः-एनकोड से बचना चाहते हैं और आपका प्रारूप फ़ाइल स्तर संगति का समर्थन नहीं करता है (सामान्य उपयोगकर्ताओं द्वारा उपयोग की जाने वाली अधिकांश फाइलें फ़ाइल स्तर संगति का समर्थन नहीं करती हैं)।

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

विंडोज के लिए :

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3. अवतल प्रोटोकॉल

इस पद्धति का उपयोग उन प्रारूपों के साथ करें जो फ़ाइल स्तर के समाकलन (एमपीईजी -1, एमपीईजी -2 पीएस, डीवी) का समर्थन करते हैं। करो नहीं MP4 के साथ उपयोग करें।

ffmpeg -i "concat:input1|input2" -codec copy output.mkv

यह विधि इन स्वरूपों की प्रकृति और इस पद्धति द्वारा किए गए सरलीकृत संगति के कारण, MP4 सहित कई प्रारूपों के लिए काम नहीं करती है।


यदि संदेह है कि किस विधि का उपयोग करना है, तो समतल डिमॉक्सर का प्रयास करें।

और देखें


3
Windows कमांड प्रॉम्प्ट एस्केप कैरेक्टर ^ है; मैं भी उद्धरण चिह्नों के साथ समस्याओं में भाग गया तो यह बन गया: ffmpeg -i concat: input1 ^। Input2 -codec कॉपी आउटपुट
user423430

1
मददगार जवाब। और यह मेरे लिए और भी अधिक समझ में आता है जब मैंने इस भिन्नता को पढ़ा: superuser.com/a/607384/74576
रयान

3
कॉन्कैट डिमॉक्सर वीडियो के लिए काम करता है, लेकिन मैं ऑडियो खो रहा हूं
Lo'c

24
एक oneliner उपयोग के लिए: ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv(mkv mp4 से अधिक कोडेक स्वीकार करता है, लेकिन आप इसे mp4 के साथ भी आज़मा सकते हैं)। -safe 0के बारे में शिकायत हाल ही में ffmpeg संस्करणों के लिए है असुरक्षित फ़ाइल नाम , और -type fकेवल वे फ़ाइलें सूचीबद्ध करने के लिए है। मैंने | sortफ़ाइलों को वर्णानुक्रम में क्रमबद्ध करने के लिए जोड़ा ; क्योंकि findउन्हें फाइल सिस्टम पर सहेजे जाने के क्रम में पढ़ा जाता है। व्हॉट्सएप के साथ फाइल के लिए भी काम करता है।
एरिक

1
मेरे लिए, विंडोज में, दोहरे उद्धरण चिह्नों ने काम किया (आपके उदाहरण में एकल के बजाय) ffmpeg -i "concat:input1|input2" -codec copy output:। पाइप चरित्र से बचने की कोई आवश्यकता नहीं है।
शोव्लट

83

MP4 फ़ाइलें के लिए

के लिए .mp4 फ़ाइलें (जो मैं DailyMotion.com से प्राप्त: 50 मिनट टीवी प्रकरण, केवल तीन भागों में तीन .mp4 वीडियो फ़ाइलों के रूप में डाउनलोड,) निम्नलिखित के लिए एक प्रभावी समाधान था विंडोज 7 , और करता नहीं फिर से एन्कोडिंग शामिल फ़ाइलें।

मैंने फाइलों का नाम बदला (as file1.mp4 , file2.mp4 , file3.mp4 ) जैसे कि भागों को पूरा टीवी एपिसोड देखने के लिए सही क्रम में था।

फिर मैंने एक साधारण बैच फ़ाइल (concat.bat) बनाई , जिसमें निम्न सामग्री है:

:: Create File List
echo file file1.mp4 >  mylist.txt 
echo file file2.mp4 >> mylist.txt
echo file file3.mp4 >> mylist.txt

:: Concatenate Files
ffmpeg -f concat -i mylist.txt -c copy output.mp4

बैच फ़ाइल , और ffmpeg.exe , जरूरी दोनों एक ही फ़ोल्डर में रखा के रूप में .mp4 फ़ाइलों में शामिल हो गए किया जाना है। फिर बैच फ़ाइल चलाएँ। आमतौर पर इसे चलाने में दस सेकंड से भी कम समय लगेगा।

परिशिष्ट (2018/10/21) -

क्या आप देख रहे थे पुन: लिखने का एक बहुत बिना वर्तमान फ़ोल्डर में सभी mp4 फ़ाइलों को निर्दिष्ट करने के लिए एक विधि है, तो अपने Windows में यह कोशिश बैच फ़ाइल के बजाय ( चाहिए विकल्प शामिल 0 -सुरक्षित ):

:: Create File List
for %%i in (*.mp4) do echo file '%%i'>> mylist.txt

:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

यह एक बैच फ़ाइल में, विंडोज 7 पर काम करता है। कमांड लाइन पर इसका उपयोग करने का प्रयास करें, क्योंकि यह केवल बैच फ़ाइल में काम करता है!


5
अब तक का सबसे आसान उपाय।
1934286

यह सबसे अच्छा और आसान उत्तर होना चाहिए। अच्छी नौकरी, मेरे भाई। आपने मेरा दिन बचाया।
डिसानियाज़ज़ सिप

यह एक अच्छा समाधान है लेकिन बैच फ़ाइल के बारे में बात करना इस ध्वनि को आदिम बनाता है (जैसे कि यह बैच में किया गया था), और इससे अधिक जटिल है (क्योंकि बैच फ़ाइल पूरी तरह से अनावश्यक है)। यह बहुत स्पष्ट है अगर आप बस दिखाने C:\blah>type mylist.txt<ENTER>(तो वे उस फ़ाइल की सामग्री देखें) फिर ffmpeg -f concat -i mylist.txt -c copy output.mp4<ENTER> भी आप एक संदर्भ में शामिल करना चाहिए trac.ffmpeg.org/wiki/Concatenate (कि संदर्भ भी उसी फ़ाइल नाम, mylist.txt उपयोग करता है)
barlop

यह एक बहुत अच्छा समाधान है क्योंकि यह आपको -iपैरामीटर के लिए फ़ाइलों की लंबी सूची में टाइप करने से बचाता है । लिनक्स पर मैंने यह किया है: ls -1 P1041*.mp4 | sed s/"P"/" file P"/g > mylist.txtजो एक बैच स्क्रिप्ट को कोड करने की तुलना में भी ठंडा है। वैसे भी, -c copyबहुत तेज़ी से प्रदर्शन करता है (जो मुझे पता नहीं था) और यह इस उत्तर का असली जादू है।
वुर्गस्पा

1
मेरी mp4 फाइलों के साथ, मैक पर अपना कॉनैट कोड चलाने के बाद आउटपुट फाइल में कोई ऑडियो नहीं है, ffmpeg v3.2.2 का उपयोग करके।
काक्यो

60

यहाँ एक तेज (1 मिनट से भी कम समय लगता है) और बिना इंटरमीडिएट फ़ाइलों की आवश्यकता के बिना ऐसा करने के लिए दोषरहित तरीका:

ls Movie_Part_1.mp4 Movie_Part_2.mp4 | \
perl -ne 'print "file $_"' | \
ffmpeg -f concat -i - -c copy Movie_Joined.mp4

"Ls" में फ़ाइलें शामिल हैं, "पर्ल" को जोड़ने के लिए एक पाइप में कॉन्सेप्टेशन फाइल ऑन-द-फ्लाई बनाते हैं "-i -" भाग पाइप से पढ़ने के लिए ffmpeg को बताता है

(ध्यान दें - मेरी फ़ाइलों में कोई स्थान या अजीब सामान नहीं था - यदि आपको "कठिन" फ़ाइलों के साथ यह विचार करना है तो आपको उपयुक्त शेल-एस्केपिंग की आवश्यकता होगी)।


2
OSX पर यह किया और यह महान काम किया! कम आवश्यकताओं के साथ भयानक, तेजी से दोषरहित समाधान।
जीएम ल्यूसिड

1
ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne '$_ =~ s/\n$//; print "file '"'"'$_'"'"'\n"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4
व्हाट्सएप

4
ls * | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4यदि आपकी फाइलें अच्छी तरह से नामांकित और क्रम में हैं, तो आप भी कर सकते हैं। ओएस एक्स पर मेरे लिए बहुत अच्छा काम किया, बिल्कुल वही जो मैं चाहता था।
नैटबीट

3
लिनक्स पर मैंने इस ऑनलाइनर का उपयोग किया: ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv(mkv mp4 से अधिक कोडेक्स स्वीकार करता है, लेकिन आप इसे mp4 के साथ भी आज़मा सकते हैं)। -safe 0के बारे में शिकायत हाल ही में ffmpeg संस्करणों के लिए है असुरक्षित फ़ाइल नाम , और -type fकेवल वे फ़ाइलें सूचीबद्ध करने के लिए है। मैंने | sortफ़ाइलों को वर्णानुक्रम में क्रमबद्ध करने के लिए जोड़ा ; क्योंकि findउन्हें फाइल सिस्टम पर सहेजे जाने के क्रम में पढ़ा जाता है। व्हॉट्सएप के साथ फाइल के लिए भी काम करता है।
erik

13
मुझे ffmpegइसे काम करने के लिए इस पैरामीटर को जोड़ना पड़ा :-protocol_whitelist file,tcp,http,pipe
Bensge

44

MP4 फ़ाइलों के लिए:

यदि वे बिल्कुल समान नहीं हैं (100% एक ही कोडेक, एक ही रिज़ॉल्यूशन, एक ही प्रकार) MP4 फ़ाइलें, तो आपको उन्हें पहली बार मध्यवर्ती धाराओं में ट्रांस-कोड करना होगा:

ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts
ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts
// now join
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

ध्यान दें! : आउटपुट पहली फ़ाइल की तरह होगा (और दूसरा नहीं)


2
जैसा कि मेरे जवाब में दिखाया गया है, नीचे, फाइलों को ट्रांसकोडिंग करना आवश्यक नहीं है। FFmpeg किसी भी mp4 फाइल को किसी भी इंटरमीडिएट स्टेप्स के बिना, और बिना किसी री-एन्कोडिंग के कई mp4 फाइल्स को कॉन्टेक्ट कर सकता है। एकमात्र मामला जिसमें किसी भी पुन: एन्कोडिंग की आवश्यकता होगी, अगर मूल फाइलें mp4 फाइलें नहीं हैं, लेकिन इरादा आउटपुट फाइल के रूप में एक mp4 फाइल बनाने का है।
Ed999

@T। टोडुआ: मुझे यह जानने में रुचि होगी कि आपकी दो mp4 स्रोत फ़ाइलों के बीच क्या अंतर हैं। क्या वे विभिन्न नमूना दरों (जैसे 44,100 हर्ट्ज और 48,000 हर्ट्ज) का उपयोग कर रहे हैं? या वे अलग-अलग बिट दरों (जैसे 128 केबीपीएस और 64 केबीपीएस) का उपयोग कर रहे हैं? ऐसे किसी भी मामले में, मुझे यह समझ में नहीं आता है कि कमांड-सी कॉपी (एक स्ट्रीम-कॉपी निर्देश) उन्हें संगत बनाने के लिए स्रोत फ़ाइलों को कैसे संशोधित करेगा।
Ed999 11:27

4
@ T.Todua Hi, जब वीडियो बिना ऑडियो ट्रैक के होते हैं तो कमांड अच्छा काम करता है। हालाँकि, जब myfile1.mp4 ऑडियो के बिना है और myfile2.mp4 ऑडियो के साथ है, तो परिणाम output.mp4 ऑडियो के बिना है। अपेक्षित आउटपुट .mp4 में ऑडियो होना चाहिए। मैं इसे कैसे सुलझाऊं?
उत्तरजाहो

2
@ T.Todua एर .... यह बहुत बुरा है। File1 | file2 file2 | file1 के साथ अलग वीडियो जेनरेट करता है। आदेश महत्वपूर्ण है।
उत्तरZHA

1
मैंने कॉनैट 2 mp4 फाइलों पर आपकी कमांड की कोशिश की। यह काम करता हैं। हालाँकि, दूसरी फ़ाइल का ऑडियो उत्पादित नए अवतरण में आह-ओह-ईई आवाज़ की तरह तड़का हुआ होता है। क्या आपके पास इसे ठीक करना है?
सुपरलाइनक्स

35

मैं .mp3एक .m4aफ़ाइल में तीन ऑडियो फ़ाइलों को संक्षिप्त करने की कोशिश कर रहा था और यह ffmpeg कमांड काम करता है।

इनपुट कमांड:

ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex concat=n=3:v=0:a=1 -f MOV -vn -y input.m4a

के अर्थ: "-filter_complex concat = n = 3: v = 0: a = 1" :

कॉनैट का मतलब है मीडिया कॉन्टेनेट (ज्वाइनिंग) फंक्शन का इस्तेमाल करना।
n का अर्थ है इनपुट फ़ाइलों की कुल संख्या की पुष्टि करें।
v का मतलब वीडियो है ? उपयोग 0 = कोई वीडियो नहीं, 1 = में वीडियो है।
एक साधन है ऑडियो ? 0 = कोई ऑडियो नहीं, 1 = ऑडियो का उपयोग करें।
-f का मतलब है फोर्स सेट फाइल फॉर्मेट (सभी समर्थित फॉर्मेट को देखने के लिए, उपयोग करें ffmpeg -formats)
-vn का मतलब है वीडियो को निष्क्रिय करें (और -anऑडियो को भी निष्क्रिय कर देगा यदि वह नहीं चाहता है)
-y साधन अधिलेखित उत्पादन फ़ाइलें (आउटपुट फ़ाइल पहले से ही मौजूद है)।

अधिक जानकारी के लिए: ffmpeg -h full प्रिंट सभी विकल्पों का उपयोग करें (सभी प्रारूप और कोडेक विशिष्ट विकल्प, बहुत लंबे समय तक)


1
फाई इस का उपयोग करें -f concat -safe 0 -i "file.txt" -c copy -y "OutPut.mp4"यह संक्षिप्त होगा लेकिन जब कुछ वीडियो ऑडियो के साथ हैं और कुछ बिना ऑडियो के हैं तो यह काम नहीं कर रहा है कि मैं इसे कैसे सुलझा सकता हूं।
अहमद

1
यह काम। आपके उत्तर में विस्तृत विवरण के लिए धन्यवाद। यह बहुत मददगार है।
जो टी। बोका

31

मैंने मध्यवर्ती प्रारूप के रूप में mpg का उपयोग किया और यह काम किया (ध्यान दें कि यह एक खतरनाक उदाहरण है, -qscale 0 वीडियो को फिर से एन्कोड करेगा ...)

ffmpeg -i 1.mp4 -qscale 0 1.mpg
ffmpeg -i 2.mp4 -qscale 0 2.mpg
cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4

8
इस टिप्पणी के रूप में, -sameqहटा दिया गया था। -qscale 0इसके बजाय उपयोग करें ।
जेवियर हो

6
-sameq"एक ही गुणवत्ता" का मतलब नहीं है और ffmpeg से हटा दिया गया है जैसा कि @XavierHo द्वारा उल्लेख किया गया है।
२०

3
यह एक मध्यवर्ती प्रारूप के माध्यम से वीडियो को ट्रांसकोड करने के लिए शर्म की बात है, केवल दो फ़ाइलों को संक्षिप्त करने के लिए। आपको पीढ़ी दर पीढ़ी नुकसान होगा। कंटेनर प्रारूप से अधिक गहरा नहीं जाना है और concatffmpeg में कमांड का उपयोग करना है , जैसा कि @rogerdpack ऊपर करता है।
रान्डेल कुक

8
यह एक स्वीकृत उत्तर कैसे है? यह बहुत ही खराब तरीका है।
डिस्प्ले नेम

4
@SargeBorsch क्योंकि यह काम करता है। मैंने पेज पर सब कुछ करने की कोशिश की है - उनमें से कोई भी काम नहीं करता है।

14

Ffmpeg में संघनन के विभिन्न तरीकों पर विस्तृत प्रलेखन यहाँ पाया जा सकता है

आप त्वरित सम्मिश्रण के लिए 'कॉनसैट फिल्टर' का उपयोग कर सकते हैं ।

यह फिर से एनकोड करता है। यह विकल्प सबसे अच्छा है जब इनपुट में अलग-अलग वीडियो / ऑडियो प्रारूप होते हैं।

2 फ़ाइलों को समाप्‍त करने के लिए:

ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

3 फ़ाइलों को समाप्‍त करने के लिए:

ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

यह एक साथ ही कई इनपुट फ़ाइल प्रकारों के लिए काम करता है।


क्या आप इस उदाहरण में दिए गए विकल्पों पर अधिक विवरण निर्दिष्ट कर सकते हैं?
डेवलपर

@ डेवलपर: विकल्पों की व्याख्या के लिए ->
कॉनसेट

4
जब 3 फ़ाइलों को समाप्‍त करना हो, तो आपको concat = n = 3: v = 1: a = 1 का उपयोग नहीं करना चाहिए n = 2
Cynapsis

1
मैं दोषरहित ouput.mp4
संघटन

कमांड को अपडेट करने के लिए इसे इंगित करने और जियोर्गीसेसी के लिए धन्यवाद सिंथेसिस
SJ00

10

मुझे लगता है कि पाइप ऑपरेटर ने मेरे लिए काम नहीं किया जब विकल्प 3 का उपयोग करके कई MP4 को मैक पर स्वीकार करने के लिए स्वीकार किया गया।

निम्नलिखित एक-लाइनर एक मैक (हाई सिएरा) पर काम करता है, जिससे mp4s को समाप्‍त किया जा सके, जिसमें कोई मध्यस्थ फ़ाइल निर्माण आवश्यक नहीं है।

ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4


2
यह सरल उत्तर केवल वही है जो वास्तव में मेरे लिए काम करता है। प्रलेखन के पन्नों पर पृष्ठ यहाँ और अन्य जगहों पर, जबकि यह सरल एक-लाइनर वह सब है जो आवश्यक है - और वास्तव में काम करता है। धन्यवाद।
4

10

यहाँ केवल ffmpegऔर नहीं का उपयोग कर 2 शुद्ध बैश समाधान

  • एक मध्यस्थ फ़ाइल
  • पर्ल, पाइथन और न ही जावास्क्रिप्ट

एक-लाइनर समाधान का उपयोग करना ls

ls video1.mp4 video2.mp4 | while read line; do echo file \'$line\'; done | ffmpeg -protocol_whitelist file,pipe -f concat -i - -c copy output.mp4

फ़ंक्शन जो 0 या 2+ तर्क लेता है

#######################################
# Merge mp4 files into one output mp4 file
# usage:
#   mergemp4 #merges all mp4 in current directory
#   mergemp4 video1.mp4 video2.mp4
#   mergemp4 video1.mp4 video2.mp4 [ video3.mp4 ...] output.mp4 
#######################################
function mergemp4() {
  if [ $# = 1 ]; then return; fi

  outputfile="output.mp4"

  #if no arguments we take all mp4 in current directory as array
  if [ $# = 0 ]; then inputfiles=($(ls -1v *.mp4)); fi
  if [ $# = 2 ]; then inputfiles=($1 $2); fi  
  if [ $# -ge 3 ]; then
    outputfile=${@: -1} # Get the last argument
    inputfiles=(${@:1:$# - 1}) # Get all arguments besides last one as array
  fi

  # -y: automatically overwrite output file if exists
  # -loglevel quiet: disable ffmpeg logs
  ffmpeg -y \
  -loglevel quiet \
  -f concat \
  -safe 0 \
  -i <(for f in $inputfiles; do echo "file '$PWD/$f'"; done) \
  -c copy $outputfile

  if test -f "$outputfile"; then echo "$outputfile created"; fi
}

नोट: इस धागे में कुछ समाधान की कोशिश की थी और कोई भी मुझे संतुष्ट नहीं किया


9

रोज़गारपैक और एड999 के जवाबों के आधार पर, मैंने अपना .sh संस्करण बनाया है

#!/bin/bash

[ -e list.txt ] && rm list.txt
for f in *.mp4
do
   echo "file $f" >> list.txt
done

ffmpeg -f concat -i list.txt -c copy joined-out.mp4 && rm list.txt

यह सभी में शामिल होता है *.mp4 वर्तमान फ़ोल्डर में फ़ाइलों में जाता हैjoined-out.mp4

मैक पर परीक्षण किया गया।

जिसके परिणामस्वरूप filesize मेरी 60 परीक्षण फ़ाइलों का सटीक योग है। कोई नुकसान नहीं होना चाहिए। मुझे जिस चीज की जरूरत थी


9

यह मेरे लिए काम किया (खिड़कियों पर)

ffmpeg -i "concat:input1|input2" -codec copy output

एक उदाहरण...

ffmpeg -i "concat:01.mp4|02.mp4" -codec copy output.mp4

अजगर

कई mp4 के साथ इसे करने के लिए कुछ अजगर कोड का उपयोग करना एक फ़ोल्डर में हैं (python.org से अजगर स्थापित करें, कॉपी करें और पेस्ट करें और इस कोड को mp4.py नामक फ़ाइल में सहेजें और इसे अजगर से फ़ोल्डर में खोले गए cmd से चलाएं। mp4.py और फ़ोल्डर में सभी mp4 को सम्‍मिलित किया जाएगा)

import glob
import os

stringa = ""
for f in glob.glob("*.mp4"):
    stringa += f + "|"
os.system("ffmpeg -i \"concat:" + stringa + "\" -codec copy output.mp4")

संस्करण 2 पायथन के साथ

मेरे ब्लॉग पर मेरे पोस्ट से लिया गया , यह है कि मैं इसे अजगर में कैसे करता हूं:

import os
import glob

def concatenate():
    stringa = "ffmpeg -i \"concat:"
    elenco_video = glob.glob("*.mp4")
    elenco_file_temp = []
    for f in elenco_video:
        file = "temp" + str(elenco_video.index(f) + 1) + ".ts"
        os.system("ffmpeg -i " + f + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + file)
        elenco_file_temp.append(file)
    print(elenco_file_temp)
    for f in elenco_file_temp:
        stringa += f
        if elenco_file_temp.index(f) != len(elenco_file_temp)-1:
            stringa += "|"
        else:
            stringa += "\" -c copy  -bsf:a aac_adtstoasc output.mp4"
    print(stringa)
    os.system(stringa)

concatenate()

1
कॉनकैट प्रोटोकॉल का उपयोग MP4 के साथ नहीं किया जाना चाहिए और स्वीकार किए गए उत्तर में उल्लिखित काम नहीं करेगा ।
ललगन

@LordNeckbeard मुझे आश्चर्य है कि यदि आप आउटपुट बिट्रेट निर्दिष्ट करते समय 2 MP4 वीडियो को बदलने के बारे में इस ffmpeg प्रश्न का उत्तर जानते हैं? video.stackexchange.com/q/24569/5657 धन्यवाद।
रयान

@LordNeckbeard मेरा अनुमान है कि आपका उत्तर सबसे अच्छा होगा, फिर भी, यदि आप इसके लिए तैयार हैं! मैं विशेष रूप से अपने आप से संतुष्ट नहीं हूँ।
रयान

न केवल (जैसा कि लॉर्ड नेकबर्ड बताता है) एक .mp4 फ़ाइल को इंटरमीडिएट .TS प्रारूप में बदलने के लिए आवश्यक है। क्रमांकन सफल होने के लिए, लेकिन, शायद इससे भी बदतर, यह उत्तर इनपुट की आवश्यकता को संबोधित करने के लिए भी शुरू नहीं होता है। वीडियो फ़ाइलों में मैचिंग बिटरेट, फ्रेम दर, नमूना दर, टाइमबेस और अवधि है। उन 5 कारकों के बिना आम तौर पर, फाइलों को समाप्‍त नहीं किया जा सकता है (अर्थात स्ट्रीम कॉपी का उपयोग करके ), लेकिन इसके बजाय फिर से एनकोड किया जाना चाहिए।
Ed999

7

के लिए .mp4फ़ाइलें, मैंने पाया यह बेहतर और तेज खुला स्रोत कमांड लाइन उपकरण का उपयोग करने से काम करता है: mp4box। तो आप इसे इस तरह से उपयोग कर सकते हैं:

mp4box.exe -add video1.mp4 -cat video2.mp4 destvideo.mp4

इसे यहां से अधिकांश प्लेटफार्मों के लिए डाउनलोड करें: https://gpac.wp.imt.fr/mp4box/


2
हालांकि यह किसी के लिए उपयोगी हो सकता है, आवश्यकता थी: " मैं ffmpeg का उपयोग करके दो mp4 फ़ाइलों को संक्षिप्त करने की कोशिश कर रहा हूं। मुझे एक स्वचालित प्रक्रिया के लिए इसकी आवश्यकता है "। कृपया पूरा प्रश्न पढ़ें और कोशिश करें और उत्तर दें जो बिंदु पर है।
thvs86

5
यह उत्तर पूरी तरह से बिंदु पर है। यह एक FOSS टूल है जो समान कार्य करता है। इसे FFmpeg की तरह ही स्क्रिप्ट में इस्तेमाल किया जा सकता है। यह किसी भी FFmpeg जवाब की तुलना में अधिक सरलता से किया गया काम हो जाता है। देखो वे कितने जटिल हैं! उनमें से एक FFmpeg को कॉल करने के लिए Node.js का उपयोग करता है! पागलपन। कृपया रूढ़िवाद के साथ रुकें और कोशिश करें और StackOverflow को फिर से उपयोगी बनाएं। यह साइट आप जैसे पूर्वजों के धन्यवाद की पूर्व छाया की छाया है। इसके अलावा, यह प्रश्न "XY प्रॉब्लम" का एक उदाहरण है, जिसे आप जैसे एक बाज को परिचित होना चाहिए।
4

इससे कोई फर्क नहीं पड़ता कि mp4box एक FOSS उपकरण है। इस सवाल का जवाब ffmpeg का उपयोग करके पूछा गया, न कि mp4box के लिए।
jramos775

@ thvs86 मैं इसका एक उदाहरण हूं। मैं ffmpeg का उपयोग करता हूं क्योंकि यह मीडिया के लिए एक वास्तविक स्विस चाकू है। मैं अपने विशेष उपयोग के मामलों में मदद के लिए भी खोज करता हूं, क्योंकि बहस की प्रगति काफी जटिल हो सकती है (जो कि यहां विभिन्न उत्तरों द्वारा प्रदर्शित की जाती है)। यह पहली बार है जब मैंने mp4box के बारे में सुना है और मुझे यह नहीं मिला अगर यह इस उत्तर के लिए नहीं होता। तो मुझ से +1 और कृपया, कृपया, बिना इंटरनेट इंटरनेट और कठोर नियमों के बारे में जवाब मांगने वाले लोगों के बारे में अधिक सोचें।
पावेल

4

यहाँ एक स्क्रिप्ट है जो मैंने कई GoPro mp4 को 720p mp4 में बनाने के लिए बनाई है। आशा है कि यह मदद की है।

#!/bin/sh
cmd="( "
for i; do
    cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
done
cmd="${cmd} ) | ffmpeg -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4"
echo "${cmd}"
eval ${cmd}

यह सहमति नहीं है। यह कोड इनपुट को अलग नहीं करता है, यह उन्हें फिर से एनकोड करता है। यह किसी भी मनमानी वीडियो फ़ाइलों को लेता है और उन्हें एक आम ऑडियो और वीडियो बिटरेट में बदल देता है (स्रोत फ़ाइलों की मूल बिटरेट या मूल फ़्रेम की परवाह किए बिना)। ओ / पी स्ट्रीम कॉपी का उपयोग करके दो फ़ाइलों में शामिल होना चाहते थे, न कि उन्हें फिर से एनकोड करें, इसलिए यह पूछे गए प्रश्न को संबोधित नहीं करता है।
Ed999

4

यहां प्रलेखन से: https://trac.ffmpeg.org/wiki/Concatenate

यदि आपके पास MP4 फाइलें हैं, तो इन्हें एमपीईजी -2 परिवहन धाराओं में पहले ट्रांसकोडिंग करके दोषरहित रूप से समतल किया जा सकता है । H.264 वीडियो और AAC ऑडियो के साथ, निम्नलिखित का उपयोग किया जा सकता है:

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

यह दृष्टिकोण सभी प्लेटफार्मों पर काम करता है।

मुझे एक क्रॉस प्लेटफॉर्म स्क्रिप्ट में इसे एनकैप्सुलेट करने की क्षमता की आवश्यकता थी, इसलिए मैंने fluent-ffmpegनिम्न समाधान के साथ उपयोग किया और आया:

const unlink = path =>
  new Promise((resolve, reject) =>
    fs.unlink(path, err => (err ? reject(err) : resolve()))
  )

const createIntermediate = file =>
  new Promise((resolve, reject) => {
    const out = `${Math.random()
      .toString(13)
      .slice(2)}.ts`

    ffmpeg(file)
      .outputOptions('-c', 'copy', '-bsf:v', 'h264_mp4toannexb', '-f', 'mpegts')
      .output(out)
      .on('end', () => resolve(out))
      .on('error', reject)
      .run()
  })

const concat = async (files, output) => {
  const names = await Promise.all(files.map(createIntermediate))
  const namesString = names.join('|')

  await new Promise((resolve, reject) =>
    ffmpeg(`concat:${namesString}`)
      .outputOptions('-c', 'copy', '-bsf:a', 'aac_adtstoasc')
      .output(output)
      .on('end', resolve)
      .on('error', reject)
      .run()
  )

  names.map(unlink)
}

concat(['file1.mp4', 'file2.mp4', 'file3.mp4'], 'output.mp4').then(() =>
  console.log('done!')
)

1
ffmpeg \
  -i input_1.mp4 \
  -i input_2.mp4 \
  -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \
  -map [vid] \
  -c:v libx264 \
  -crf 23 \
  -preset veryfast \
  output.mp4

1
सिर्फ एक उत्तर को पोस्ट करने से नहीं, आप थोड़ा स्पष्टीकरण जोड़ सकते हैं जो ओपी और भविष्य के पाठकों के लिए बेहतर समाधान को समझते हैं।
बालगुरुनाथन मारीमुथु

1
इसने एक नया मूक वीडियो बनाया, जिसमें दोनों इनपुट एक-दूसरे के बगल में एक ही समय पर चल रहे थे। मुझे उम्मीद थी कि एक वीडियो एक वीडियो बनाएगा जहां input_1.mp4 खेला गया और फिर input_2.mp4
Alexx Roche

3
यह पूरी तरह से गलत जवाब था। इसने वीडियो को गुप्त नहीं किया, यह सिर्फ उन्हें साइड-बाय-साइड खेलता है, जैसे @AlexxRoche ने उल्लेख किया था।
कलोब तौलिएन

1

वर्तमान निर्देशिका से सभी mp4 फ़ाइलों को विलय

मैं बाहरी फाइल बनाना पसंद नहीं करता जिसे मुझे बाद में डिलीट करना है, इसलिए मेरा सॉल्यूशन फॉलो कर रहा था जिसमें फाइल नंबरिंग लिस्टिंग (जैसे file_1_name, file_2_name, file_10_name, file_20_name, file_100_name...) शामिल हैं

#!/bin/bash
filesList=""
for file in $(ls -1v *.mp4);do #lists even numbered file
    filesList="${filesList}${file}|"
done
filesList=${filesList%?} # removes trailing pipe
ffmpeg -i "concat:$filesList" -c copy $(date +%Y%m%d_%H%M%S)_merged.mp4

मैंने इस कोड को नोटपैड में कॉपी किया और कुछ भी नहीं हुआ।
7vujy0f0hy

1
@ 7vujy0f0hy यह एक बैश शेल के साथ एक लाइन पर काम करता है शायद यह साइबरविन के साथ काम कर सकता है
Pipo

1

नीचे दी गई विभिन्न कोशिशों के बाद पटकथा ने मेरे लिए विंडोज़ 10 पॉवरशेल पर काम किया।

    $files=Get-ChildItem -path e:\ -Filter *.mp4


    $files| ForEach-Object  {"file '$($_.FullName)'"}| Out-File -FilePath e:\temp.txt -Encoding ASCII


    if (-not (test-path "e:\ffmpeg\bin\ffmpeg.exe")) {throw "e:\ffmpeg\bin\ffmpeg.exe needed"}

    E:\ffmpeg\bin\ffmpeg.exe -safe 0 -f concat -i "e:\temp.txt" -c copy -bsf:v hevc_mp4toannexb -an e:\joined.mp4

    # Conversion Cleanup
    Remove-Item e:\temp.txt

यहाँ पहली दो पंक्तियाँ एक टेक्स्ट फ़ाइल temp.txt बनाती हैं जिसमें निम्नलिखित सामग्री होती है

file 'e:\first.mp4'
file 'e:\second.mp4'

अगर ffmpeg रास्ते में उपलब्ध है और "join.mp4" बनाएं

अन्य उत्तरों के प्रमुख अंतर नीचे दिए गए हैं

usage  of -bsf:v hevc_mp4toannexb -an

मेरे mp4 फ़ाइल के ऊपर काम करने के लिए, आपको अपने वीडियो एन्कोडिंग के आधार पर नीचे दिए गए अन्य विकल्पों का उपयोग करने की आवश्यकता हो सकती है।

h264_mp4toannexb

ऐसे सभी संभव बिटस्ट्रीम फ़िल्टर https://ffmpeg.org/ffmpeg-bitstream-filters.html पर देखे जा सकते हैं


मेरा एक सीसीटीवी कैमरे से आने वाला MP4 था। उस आदेश के बिना वार्तालाप आउटपुट फ़ाइल उत्पन्न करने में विफल रहता है। मैं अपनी वेबसाइट से नवीनतम ffmpeg का उपयोग कर रहा हूं।
राहुल मेनदारगी

0

यहां कमांड प्रतिस्थापन और कॉनसेट वीडियो फिल्टर (यह फिर से सांकेतिक शब्दों में बदलना) का उपयोग करके MP4 फ़ाइलों से भरा एक निर्देशिका में शामिल होने के लिए मेरी विधि है - पता लगा कि किसी और को इस वन-लाइनर का कुछ उपयोग मिलेगा, खासकर यदि आपके पास कई फाइलें हैं (मैं सिर्फ एक झपट्टा में 17 फाइलें शामिल हो गई):

ffmpeg $(for f in *.mp4 ; do echo -n "-i $f "; done) -filter_complex \
"$(i=0 ; for f in *.mp4 ; do echo -n "[$i:v] [$i:a] " ; i=$((i+1)) ; done \
&& echo "concat=n=$i:v=1:a=1 [v] [a]")" -map "[v]" -map "[a]" output.mp4

नायब यह आदेश आपकी फ़ाइलों को उस क्रम में जोड़ता है जिसमें उनका नाम दिया गया है (अर्थात जैसा क्रम वे प्रस्तुत करते हैं यदि आप चलाते हैं तो ls *.mp4) - मेरे मामले में, उनमें से प्रत्येक के पास एक ट्रैक नंबर था, इसलिए इसने बहुत काम किया।


0

यहां वर्णित कॉनकैट प्रोटोकॉल; https://trac.ffmpeg.org/wiki/Concatenate#protocol

इंटरमीडिएट फ़ाइलों से बचने के लिए नामित पाइप का उपयोग करते समय लागू किया जाता है

बहुत तेज़ है (पढ़ें: तत्काल), कोई फ्रेम नहीं गिरा है, और अच्छी तरह से काम करता है।

नामित पाइप फ़ाइलों को हटाने के लिए याद रखें और यह जांचने के लिए याद रखें कि क्या वीडियो H264 और AAC है जिसे आप बस ffmpeg -i filename.mp4(h264 और aac उल्लेखों के लिए जांच) कर सकते हैं


-1

पुन: प्रयोज्य PowerShell स्क्रिप्ट के रूप में स्वीकृत उत्तर

Param(
[string]$WildcardFilePath,
[string]$OutFilePath
)
try
{
    $tempFile = [System.IO.Path]::GetTempFileName()
    Get-ChildItem -path $wildcardFilePath | foreach  { "file '$_'" } | Out-File -FilePath $tempFile -Encoding ascii
    ffmpeg.exe -safe 0 -f concat -i $tempFile -c copy $outFilePath
}
finally
{
    Remove-Item $tempFile
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.