ffmpeg เข้าร่วมไฟล์ mp4 สองไฟล์ด้วย ffmpeg บนบรรทัดคำสั่ง


29

ฉันสามารถเข้าร่วมหลายไฟล์ได้สำเร็จโดยใช้คำสั่งต่อไปนี้:

ffmpeg -f concat -i input.txt -codec copy output.mp4

ปัญหาเดียวของคำสั่งนี้คือคุณต้องอ่านไฟล์พา ธ จากไฟล์ข้อความชื่อinput.txtพร้อมเนื้อหาต่อไปนี้:

file 'C:\Users\fabio\Downloads\Super\Sharks\01.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\02.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\03.mp4'

มีวิธีในการบรรลุเป้าหมายเดียวกันโดยไม่ต้องอ่านไฟล์พา ธ จากไฟล์หรือไม่? ฉันได้ลองทำสิ่งต่อไปนี้โดยไม่มีโชค:

ffmpeg -f concat -i file "C:\a\b\01.mp4" file "C:\a\b\02.mp4" -codec copy output.mp4
ffmpeg -f concat -i "C:\a\b\01.mp4" "C:\a\b\02.mp4" -codec copy output.mp4

ฉันต้องใช้คำสั่งอื่นหรือไม่?


คำตอบ:


37

อัพเดต 2019:

ตามที่กล่าวไว้ในความคิดเห็น Stack Overflow มีคำอธิบายที่ดีเกี่ยวกับตัวเลือกที่มีอยู่สำหรับการต่อข้อมูลรวมถึงการอภิปรายเกี่ยวกับวิธีการที่จะใช้ขึ้นอยู่กับประเภทของไฟล์ที่คุณกำลังใช้:

วิธีการต่อไฟล์ MP4 สองไฟล์เข้าด้วยกันโดยใช้ FFmpeg

ต้นฉบับ 2016 คำตอบ:

คุณควรใช้เมธอดโปรโตคอล concatเพื่อรวมไฟล์:

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

นอกจากนี้คู่มือ FFmpeg กล่าวถึงวิธีการเฉพาะสำหรับไฟล์ MP4 เพื่อที่จะทำการเชื่อมโยงไฟล์เหล่านั้นโดยไม่สูญเสียข้อมูล แต่ต้องการให้คุณสร้างไฟล์ชั่วคราว (หรือชื่อไพพ์):

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

1
คำสั่งแรกทำงานให้ฉันอย่างบัตเตอร์มันใช้เวลา 2 ถึง 3 วินาทีในการต่อไฟล์ mp4 ของฉันเข้ากับไฟล์เอาต์พุต (239 MB ประมาณ)
Sachin

22
คำสั่งแรกใช้ไม่ได้สำหรับฉัน มันเพิ่งคัดลอกไฟล์แรก
Luis A. Florit

3
output.mp4นี้ไม่ได้ทำงานก็แค่คัดลอกไฟล์แรกไป
crmpicco

2
การต่อข้อมูลระดับไฟล์ไม่ทำงานสำหรับ MP4 ดังนั้นจึงไม่แนะนำให้ใช้โปรโตคอล concat สำหรับรูปแบบนี้และโดยทั่วไปจะไม่ทำงาน
โลแกน

1
@brasofilo ขอบคุณสำหรับลิงค์ นี่เป็นเวลาที่นานเกินไป แต่ฉันได้อัปเดตคำตอบเพื่อชี้บุคคลในทิศทางนั้น
คาร์สันดาร์ลิ่ง

5

คุณสามารถแทนที่ไฟล์ด้วยรายการโดยแสดงรายการเป็นstdoutและอ่านรายการจากstdinโดย ffmpeg:

(echo file 'a.mp4' & echo file 'b.mp4') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "result.mp4"

การใช้ ffmpeg เวอร์ชั่น 2.4.3-tessus บน Mac OS 10.12.6 นี่เป็นข้อผิดพลาด: "ตัวเลือกที่ไม่รู้จัก 'protocol_whitelist'" หากไม่มีตัวเลือก protocol_whitelist ดูเหมือนว่าจะเพียงแค่ทำสำเนาไฟล์ MP4 ที่สอง
James

2

ไม่ดูเหมือนว่าจะไม่มีวิธีใช้ ffmpeg concat demuxer ในบรรทัดคำสั่งเดียวโดยไม่ต้องแฮ็ค คุณต้องสร้างไฟล์ข้อความที่มีรายชื่อของไฟล์ ฉันคิดว่ามันแปลก ๆ ด้วยตัวเองบางทีใครบางคนอาจจะเพิ่มสิ่งนี้ลงใน FFMpeg ในภายหลัง

คำตอบที่ยอมรับสำหรับคำถามนี้ใช้โปรโตคอล concat ไม่ใช่ concat demuxer ซึ่งเป็นสิ่งที่ OP ขอ


1
จริงๆแล้วมี stdin
Qwertiy

โปรโตคอล concat ไม่ควรใช้กับ MP4 หรือรูปแบบอื่นใดที่ต้องใช้ส่วนหัวร่วม
llogan

1

คุณยังสามารถทำได้ในสคริปต์โดยไม่เปลี่ยนคำสั่ง สิ่งที่ต้องการ:

echo "file fname1" >$$.tmp    #single redirect creates or truncates file
echo "file fname2" >>$$.tmp   # double redirect appends
echo "file fname3" >>$$.tmp   # do as many as you want.

ffmpeg -f concat -i $$.tmp -codec copy output.mp4

rm $$.tmp  # just to clean up the temp file. 
           # For debugging, I usually leave this out.

$$ ขยายเป็น pid ของเชลล์ที่รันคำสั่งดังนั้นชื่อไฟล์จะแตกต่างกันทุกครั้งที่คุณรัน เพื่อให้คุณสามารถใช้ $$. txt หากคุณต้องการ หรืออย่างอื่น...

นอกจากนี้คุณสามารถใช้ไฟล์ที่นี่เพื่อเพิ่มกลุ่มข้อมูลลงในไฟล์:

cat <<EOF >$$.tmp
file fname1
file fname2
file fname3
EOF

bash การแทนค่าตัวแปรใช้งานได้ดังนั้นคุณสามารถกำหนดเนื้อหาของไฟล์โดยทางโปรแกรมโดยไม่ต้องแก้ไข ฉันฝังสิ่งเหล่านี้ลงในลูปตลอดเวลา ในที่สุดการเปลี่ยนเส้นทางจะทำงานเหมือนกับข้างบนดังนั้น> $$. tmp จะตัดทอนแล้วเขียน >> $$. tmp ต่อท้าย


2
คำถามถามว่า "มีวิธีการในการบรรลุเป้าหมายเดียวกันโดยไม่ต้องอ่านไฟล์พา ธ จากไฟล์หรือไม่?" สิ่งที่คุณทำคือให้วิธีเขียนไฟล์พา ธ ไปยังไฟล์ (ก่อนที่จะอ่านไฟล์พา ธ จากไฟล์) นี่ไม่ได้ตอบคำถาม
สกอตต์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.