ใช้ตัวแปลงสัญญาณคัดลอก ffmpeg เพื่อรวมไฟล์ * .ts ไว้ใน mp4 เดียว


47

ฉันมีกลุ่มต่าง ๆ ที่อธิบายโดยไฟล์ index.m3u8 ไฟล์เดียว:

index.m3u8        
segment1_0_av.ts  
segment2_0_av.ts  
segment3_0_av.ts  
segment4_0_av.ts  
segment5_0_av.ts

ฉันรู้ว่าพวกเขาทั้งหมดถูกเข้ารหัสด้วยวิธีเดียวกัน ffprobe ให้สิ่งต่อไปนี้แก่ฉัน:

Input #0, mpegts, from 'segment1_0_av.ts':
  Duration: 00:00:10.00, start: 0.100511, bitrate: 1251 kb/s
  Program 1 
    Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 960x540 [SAR 1:1 DAR 16:9], 12.50 fps, 25 tbr, 90k tbn, 25 tbc
    Stream #0:1[0x101]: Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 105 kb/s
    Stream #0:2[0x102]: Unknown: none ([21][0][0][0] / 0x0015)

ฉันต้องการรวมไว้ใน mp4 คอนเทนเนอร์เดียว แต่เมื่อฉันลองคำสั่งเช่น:

ffmpeg -f concat -i filelist.txt -c copy output.mp4

โดยที่สร้างไฟล์ filelist.txt จากไฟล์ index.m3u8 มันบ่นว่าไม่สามารถอ่านไฟล์ต่าง ๆ ได้ แต่การแปลงไฟล์ ts ด้วยตนเองดูเหมือนว่าจะทำงานได้ดี ฉันคิดว่าฉันใช้ ffmpeg ไม่ถูกต้อง

ฉันจะใช้ ffmpeg เพื่อรวมไฟล์ ts ที่อธิบายโดย index.m3u8 ไปยังคอนเทนเนอร์ mp4 เดียวโดยใช้ตัวแปลงสัญญาณคัดลอกได้อย่างไร

คำตอบ:


58

ฉันไม่แน่ใจว่าทำไม ffmpeg ให้ข้อผิดพลาดแก่คุณ อย่างไรก็ตาม ts เป็นหนึ่งในไม่กี่รูปแบบที่สามารถต่อกันได้ จากนั้นเมื่อคุณมี ts เพียงตัวเดียวให้ส่งต่อไปยัง mp4

ภายใต้หน้าต่าง:

copy /b segment1_0_av.ts+segment2_0_av.ts+segment3_0_av.ts all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

ภายใต้ GNU / Linux ให้ใช้ bash:

cat segment1_0_av.ts segment2_0_av.ts segment3_0_av.ts > all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

12
-bsf:a aac_adtstoascนอกจากนี้คุณยังอาจต้อง
Camilo Martin

1
ที่น่าสนใจที่จะทราบว่าคำสั่งไม่ffmpeg copy ...ได้เป็นcopy ...(ภายใต้ Windows)
Ron Royston

25

การใช้การคัดลอกหรือแมวเพื่อรวมไฟล์ต่าง ๆ เช่นคำตอบยอดนิยมปัจจุบันของ szatmary อาจทำให้คุณมีไฟล์ที่เล่นเกินขีด จำกัด และไม่สามารถหาได้พร้อมกับปัญหาการเล่น

แต่จะรวมไฟล์เหล่านี้ต้องใช้ ffmpeg ตามคำแนะนำในhttps://trac.ffmpeg.org/wiki/Concatenate (ติดตั้ง ffmpeg ที่นี่หากคุณยังไม่มีhttps://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg )

หากคุณขี้เกียจอ่านลิงค์แรกของฉันโดยทั่วไปคุณต้องสร้างไฟล์. txt ที่แสดงรายการไฟล์ทั้งหมดที่คุณต้องการรวมเช่นนั้น (ลิงก์แรกของฉันให้คำแนะนำเกี่ยวกับวิธีการทำอย่างง่ายดาย) ในโฟลเดอร์ที่คุณ ' กำลังทำการต่อกันอีก:

file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

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

(for %i in (*.ts) do @echo file '%i') > mylist.txt

ตรวจสอบอีกครั้งว่าไฟล์. txt ของคุณดูดีและจัดรูปแบบถูกต้อง!

หลังจากนี้ให้รัน commandline:

ffmpeg -f concat -i mylist.txt -c copy all.ts

โดยที่ 'mylist.txt' เป็นไฟล์. txt ที่คุณเพิ่งสร้างขึ้น

ตรวจสอบว่าไฟล์ผลลัพธ์เล่นวิดีโออย่างถูกต้องหรือไม่ จากที่นี่คุณสามารถส่งผ่านไปยัง mp4 ตามปกติหากคุณต้องการ:

ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

นั่นfor %i in (*.ts) doไม่ได้เรียงอย่างถูกต้องสำหรับ i> = 10 นอกจากนั้นทุกอย่างก็ใช้ได้ขอบคุณ อันที่จริงมีปัญหากับไฟล์ที่ตัดแบ่งแล้วไม่ต้องพูดถึงว่าไฟล์ที่ทำโดยใช้วิธีการของคุณกลายเป็นเล็กลง 16% (ฉันมี 1,400 ส่วน 400kb)
ผู้ใช้

@user สำหรับตัวเลขตามลำดับคุณสามารถวนซ้ำตามตัวเลขเช่นfor i in {1..10}; do echo file \'$i.ts\' >> list.txt ; done
qwr

8

2017 คำตอบ

แต่เมื่อฉันลองคำสั่งเช่น...นั้นมันบ่นว่าไม่สามารถอ่านไฟล์ต่าง ๆ ได้

เมื่อฉันดำเนินการffmpeg -i some.ts -c copy some.mp4กับวิดีโอฉันได้รับข้อความแสดงข้อผิดพลาดนี้:

Malformed AAC bitstream detected: use the audio bitstream filter 
'aac_adtstoasc' to fix it ('-bsf:a aac_adtstoasc' option with ffmpeg)

av_interleaved_write_frame(): Operation not permitted

ไม่น่าแปลกใจที่การดำเนินการffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4แก้ไขนั้น


3
รับพอใหม่ffmpegและตอนนี้มันจะทำโดยอัตโนมัติ
llogan

7

วางทั้งหมดเข้าด้วยกัน

ใช้คำตอบของ Juan Aquino (และแก้ไขคำสั่งแรกให้เข้ากันได้กับ Bash และการใช้ไฟล์ตามลำดับที่เป็นธรรมชาติ) บวกกับคำตอบ 7vujy0f0hy ของสคริปต์การทำงานที่ง่ายสำหรับเชลล์ Linux Bash คือ:

#!/bin/bash
for i in `ls *.ts | sort -V`; do echo "file $i"; done >> mylist.txt
ffmpeg -f concat -i mylist.txt -c copy -bsf:a aac_adtstoasc video.mp4

4

วิธีที่ถูกต้องในการเชื่อมต่อไฟล์วิดีโอหลายไฟล์จากเพลย์ลิสต์ m3u8 คือ

ffmpeg -i "index.m3u8" -codec copy output.mp4


  • เพลย์ลิสต์ m3u8 สามารถอยู่บนเว็บหรืออยู่ในไดเรกทอรี
    • มันมีรายการของเส้นทางไฟล์ที่สัมพันธ์กับรายการเพลง
  • -codec copy เพื่อหลีกเลี่ยงการเข้ารหัส
  • เรื่องประเภทภาชนะ:
    • *.mp4 ใช้ได้ แต่ดูเหมือนช้าเล็กน้อยในการ mux เมื่อดึงเพลย์ลิสต์จากเว็บ
    • *.mkvหรือ*.tsทำงานได้ดีที่สุดสำหรับฉัน

2

คุณสามารถทำการต่อข้อมูลแบบง่าย ๆ ได้

for f in ./{0..<number>}.ts; do cat $f >> out.ts; done

แทนที่<number>ด้วยจำนวนสูงสุด (ชัด) ตัวแปรที่มี ffmpeg ทำงานไม่ถูกต้อง ไฟล์วิดีโอที่ส่งออกจะพูดติดอ่างแปลก ๆ

ฉันใช้ for for เพื่อให้แน่ใจว่าลำดับที่ถูกต้องของไฟล์ บางทีคุณไม่ต้องการมัน บางทีมันอาจเป็นไปได้ที่จะไพพ์เอาต์พุตเป็น ffmpeg และแปลงเป็น mp4 ได้ทันที


0

คำตอบยอดนิยมทั้งหมดสำหรับคำถามนี้ที่ทำให้ผู้อ่านเข้าใจผิดในการเชื่อมไฟล์ TS ก่อนที่จะเรียกใช้ ffmpeg ไม่ถูกต้อง เพื่อให้แน่ใจว่าเสียงและวิดีโอจะไม่หลุดจากการซิงค์ระหว่างแอสเซมบลีของ mp4 สตรีมควรใช้ฟีเจอร์ "-f concat" ที่ไม่ดี แต่สำคัญของ ffmpeg

    delimiterBeforeFileNumber="-"
    ls |egrep '[.]ts$' \
        |sort "-t$delimiterBeforeFileNumber" -k2,2n \
        |sed -r "s/(.*)/file '\1'/" >ts.files.txt

    ffmpeg -f concat -i ts.files.txt -c copy tsw.014.ts.mp4

โค้ดการเตรียมการสองบรรทัดเพิ่งสร้างไฟล์ที่มีรายการไฟล์ TS ในรูปแบบบรรทัดนี้:

    file 'seg-37-a.ts'

ที่จริงแล้วเมื่อฉันลองสิ่งนี้มี "พูดติดอ่าง" เล็กน้อยระหว่างส่วนต่าง ๆ ในวิดีโอสุดท้าย อย่างน้อยก็ในกรณีนี้มันช่วยให้การต่อไฟล์ TS เป็นเรื่องแรก
Sphinxxx

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