การตัดวิดีโอตามเวลาเริ่มต้นและเวลาสิ้นสุดโดยใช้ ffmpeg


510

ฉันพยายามตัดวิดีโอโดยใช้เวลาเริ่มต้นและเวลาสิ้นสุดของวิดีโอโดยใช้คำสั่งต่อไปนี้

ffmpeg -ss 00:00:03 -t 00:00:08 -i movie.mp4 -acodec copy -vcodec copy -async 1 cut.mp4

โดยใช้คำสั่งดังกล่าวข้างต้นที่ผมต้องการที่จะตัดวิดีโอจากไป00:00:03 00:00:08แต่มันไม่ได้เป็นการตัดวิดีโอระหว่างเวลานั้นแทนที่จะเป็นการตัดวิดีโอใน 11 วินาทีแรก ใครสามารถช่วยฉันแก้ปัญหานี้ได้บ้าง

แก้ไข 1:

ฉันพยายามตัดโดยใช้คำสั่งต่อไปนี้ซึ่งแนะนำโดยmark4o

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

แต่มันก็แสดงให้เห็นข้อผิดพลาดดังต่อไปนี้

โปรแกรมเข้ารหัส 'aac' เป็นการทดลอง แต่ไม่ได้เปิดใช้งานตัวแปลงสัญญาณการทดลอง

ดังนั้นฉันเพิ่ม-strict -2เข้าไปในคำสั่งเช่น

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -strict -2 cut.mp4

ตอนนี้มันทำงานได้ดี


3
เอาต์พุตคอนโซล ffmpeg เต็มของคุณไม่มีข้อมูล โปรดรวมสิ่งนี้เสมอเมื่อถาม ขอบคุณ
slhck

3
คุณได้รับ - จำกัด 2 จากที่ไหน เพียงแค่อยากรู้อยากเห็นเพราะมันไม่ได้อยู่ในเอกสาร: ffmpeg.org/ffmpeg.html
StackOverflowed

มันมีคุณภาพหลังจากติดตั้ง ffmpeg ใน ffmpeg ช่วยให้คุณสามารถหาตัวเลือกนี้
Kalai


1
ฉันคิดว่าปัญหานี่เป็นเพียงความจริงที่คุณใส่จากและไปก่อน -i movie.mp4 อาร์กิวเมนต์ของสตรีมนั้นไปหลังจากนั้นใช่ไหม นั่นเป็นสาเหตุที่วิธีอื่นทำงาน = /
เบรนต์ริทเทนเฮาส์

คำตอบ:


573

คุณอาจไม่มีคีย์เฟรมที่เครื่องหมาย 3 วินาที เนื่องจากเฟรมที่ไม่ใช่คีย์เข้ารหัสความแตกต่างจากเฟรมอื่นจึงต้องการข้อมูลทั้งหมดที่ขึ้นต้นด้วยคีย์เฟรมก่อนหน้า

ด้วยคอนเทนเนอร์ mp4 คุณสามารถตัดที่ไม่ใช่คีย์เฟรมได้โดยไม่ต้องเข้ารหัสอีกครั้งโดยใช้รายการแก้ไข กล่าวอีกนัยหนึ่งหากคีย์เฟรมที่ใกล้ที่สุดก่อน 3 วินาทีอยู่ที่ 0 วินาทีมันจะคัดลอกวิดีโอเริ่มต้นที่ 0 วินาทีและใช้รายการแก้ไขเพื่อแจ้งให้ผู้เล่นเริ่มเล่น 3 วินาที

หากคุณใช้ffmpeg ล่าสุดจาก git master มันจะทำสิ่งนี้โดยใช้รายการแก้ไขเมื่อเรียกใช้คำสั่งที่คุณให้ไว้ หากสิ่งนี้ไม่ได้ผลสำหรับคุณแสดงว่าคุณกำลังใช้ ffmpeg รุ่นเก่ากว่าหรือเครื่องเล่นของคุณไม่รองรับรายการแก้ไข ผู้เล่นบางคนจะไม่สนใจรายการแก้ไขและเล่นสื่อทั้งหมดในไฟล์ตั้งแต่ต้นจนจบ

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

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

เมื่อเข้ารหัสอีกครั้งคุณอาจต้องการรวมตัวเลือกที่เกี่ยวข้องกับคุณภาพเพิ่มเติมหรือตัวเข้ารหัส AAC เฉพาะ สำหรับรายละเอียดดูที่คู่มือการเข้ารหัส x264ของ ffmpeg สำหรับวิดีโอและคู่มือการเข้ารหัส AACสำหรับเสียง

นอกจากนี้-tตัวเลือกจะระบุระยะเวลาไม่ใช่เวลาสิ้นสุด คำสั่งดังกล่าวจะเข้ารหัสวิดีโอ 8s เริ่มต้นที่ 3 วินาที เริ่มต้นที่ 3s -t 5และสิ้นสุดที่ใช้ หากคุณใช้ ffmpeg รุ่นปัจจุบันคุณสามารถแทนที่-tด้วย-toคำสั่งด้านบนเพื่อสิ้นสุดในเวลาที่กำหนด


4
มีทางลัดในการระบุจนถึงจุดสิ้นสุดของวิดีโอหรือไม่
Jikku Jose

20
@JikkuJose: ละเว้น-t/ -toและอาร์กิวเมนต์เพื่อดำเนินการต่อไปยังจุดสิ้นสุด
mark4o

41
หมายเหตุ: จะเร็วกว่าในการจัดหา-ssก่อนป้อนไฟล์อินพุต (ก่อนหน้า-i) เนื่องจากวิธีนั้น ffmpeg จะข้ามไปยังตำแหน่งโดยตรง อย่างไรก็ตามนั่นจะเป็นการตั้งค่าเวลาเป็น "ศูนย์" ไปยังตำแหน่งนั้นซึ่งหมายความว่า-toจะชี้ไปยังเวลาที่ผิด ที่มา: trac.ffmpeg.org/wiki/Seeking
Denilson Sá Maia

4
ฉันได้รับปัญหาการซิงค์เสียงและวิดีโอหลังจากใช้สิ่งนี้ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4แม้ว่าไฟล์ต้นฉบับจะไม่มีปัญหาดังกล่าว
user2002522

6
@ user2002522: -async 1ลองโดยไม่ต้อง
mark4o

431

ลองใช้สิ่งนี้ มันเป็นวิธี ffmpeg ที่เร็วและดีที่สุดที่ฉันเข้าใจได้:

 ffmpeg -ss 00:01:00 -i input.mp4 -to 00:02:00 -c copy output.mp4

คำสั่งตัดแต่งวิดีโอของคุณในไม่กี่วินาที!

ฉันได้อธิบายไว้ในบล็อกของฉันที่นี่ :

-i:นี่ระบุไฟล์อินพุต ในกรณีนั้นคือ (input.mp4)
-ss:ใช้กับ -i ซึ่งจะค้นหาในไฟล์อินพุต (input.mp4) เพื่อวางตำแหน่ง
00:01:00:นี่คือเวลาที่วิดีโอที่ถูกตัดแต่งของคุณจะเริ่มด้วย
-to:สิ่งนี้ระบุระยะเวลาตั้งแต่เริ่มต้น (00:01:40) ถึงสิ้นสุด (00:02:12)
00:02:00:นี่คือเวลาที่วิดีโอที่ตัดแต่งของคุณจะจบลงด้วย
-c copy:นี่เป็นตัวเลือกในการตัดแต่งผ่านสตรีม copy (NB: เร็วมาก)

รูปแบบเวลาคือ: hh: mm: ss

โปรดทราบว่าคำตอบที่ได้รับการโหวตอย่างสูงในปัจจุบันนั้นล้าสมัยและการตัดแต่งจะช้ามาก สำหรับข้อมูลเพิ่มเติมดูที่ ffmpeg นี้อย่างเป็นทางการบทความ


9
ซึ่งประมวลผลไฟล์ 45 นาที 720p ของฉันใน 3 วินาที นี่ควรเป็นคำตอบที่ถูกต้อง
Dheeraj Bhaskar

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

7
ดังที่ @pelson บอกว่าสิ่งนี้จะตัดคีย์เฟรมและปล่อยว่างไว้สองสามวินาทีแรก (ถ้าเวลาตัดอยู่ระหว่างเฟรมหลัก) ffmpeg -ss 00:01:00 -to 00:02:00 -i input.mp4 -ss 00:01:00 -to 00:02:00 -c copy output.mp4ที่น่าสนใจการเปลี่ยนลำดับพารามิเตอร์แก้ปัญหา: อย่างไรก็ตามตอนนี้การข้ามถูกทำลายและเวลาสิ้นสุดไม่ถูกต้อง (ในกรณีของฉัน)
กราฟิลส์

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

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

91
ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -c copy cut.mp4 

ใช้สำเนา -cเพื่อทำในทันที ในกรณีนั้น ffmpeg จะไม่เข้ารหัสวิดีโออีกครั้งเพียงแค่ตัดตามขนาด


2
ของ -c copy ใช้งานได้ดี แต่ถ้าฉันลบ -async 1
dorien

2
สิ่งนี้กลายเป็นความล้มเหลวในการเขียนเนื่องจากส่วนหัวที่ไม่ถูกต้องในกรณีของอินพุตและเอาต์พุตคอนเทนเนอร์ที่ต่างกันเช่นอินพุต. mkv และเอาต์พุต. mp4
Assil Ksiksi

1
เอาล่ะการแปลง. mkv เป็น. mp4 คุณต้องใช้คำสั่งอื่น: ffmpeg -i movie.mkv -vcodec copy -acodec copy converted_movie.mp4และจับกลับ
Vlad Hudnitsky

ข้อดีของการเข้ารหัสซ้ำคืออะไร มันเป็นการใช้งานถ้าเราต้องการวิดีโอขนาดเล็กในรูปแบบเดียวกันหรือไม่
Harsha

29
    ffmpeg -i movie.mp4 -vf trim=3:8 cut.mp4

ดร็อปทุกอย่างยกเว้นตั้งแต่วินาทีที่ 3 ถึงครั้งที่สอง 8


4
ฉันได้ 8 วินาทีแรกด้วยสิ่งนี้โดย 3 วินาทีแรกถูกตรึงบนเฟรมแรก แก้ไขโดยการโยงsetpts=PTS-STARTPTSตัวกรองหลังตัวกรองการตัดแต่ง
jiggunjer

สิ่งนี้บอกว่า "ตัวเข้ารหัส 'aac' เป็นการทดลอง แต่ไม่ได้เปิดใช้งานตัวแปลงสัญญาณทดลองให้เพิ่ม '-strict -2' ถ้าคุณต้องการใช้งาน ' การเพิ่ม -strict -2 ไม่ได้ช่วยอะไร ผลลัพธ์คือไฟล์ที่มีความยาวเป็นศูนย์
Ivan

4
@Ivan คุณลองเพิ่ม-strict -2ก่อนหน้านี้cut.mp4(ตรงข้ามกับส่วนท้ายของบรรทัดคำสั่ง) หรือไม่
Jan Gondol

เฮ้คุณบอกฉันได้ไหมว่าฉันต้องการวิดีโอโดยไม่ต้อง 3 ถึง 8 วินาที?
Parth Solanki

1
นี่คือซุปเปอร์ช้า
Tessaracter

21

หากต้องการตัดตามเวลาเริ่มต้นและสิ้นสุดจากวิดีโอต้นทางและหลีกเลี่ยงการทำคณิตศาสตร์ให้ระบุเวลาสิ้นสุดเป็นตัวเลือกอินพุตและเวลาเริ่มต้นเป็นตัวเลือกเอาต์พุต

ffmpeg -t 1:00 -i input.mpg -ss 45 output.mpg

สิ่งนี้จะสร้างการตัด 15 วินาทีจาก 0:45 ถึง 1:00

นี่เป็นเพราะเมื่อ-ssได้รับเป็นตัวเลือกเอาท์พุทเวลาที่ทิ้งจะยังคงรวมอยู่ในเวลาทั้งหมดที่อ่านจากอินพุตซึ่ง-tใช้เพื่อทราบเมื่อหยุด ในขณะที่หาก-ssได้รับเป็นตัวเลือกอินพุตเวลาเริ่มต้นจะถูกค้นหาและไม่นับซึ่งเป็นที่มาของความสับสน

มันช้ากว่าการค้นหาเนื่องจากเซ็กเมนต์ที่ข้ามนั้นยังคงถูกประมวลผลก่อนที่จะถูกทิ้ง แต่นี่เป็นวิธีเดียวที่จะทำได้เท่าที่ฉันรู้ หากคุณตัดจากส่วนลึกในไฟล์ขนาดใหญ่มันจะฉลาดกว่าที่จะทำคณิตศาสตร์และใช้-ssสำหรับอินพุต


4
ช้า แต่สิ่งเดียวที่ใช้ได้ผลสำหรับฉัน (โดยไม่สูญเสียเฟรมจากคำตอบอื่น ๆ )
techkuz

8

นี่คือสิ่งที่ฉันใช้:

ffmpeg -i input.mkv -ss 00:01:00 -to 00:02:00 -c:v copy -c:a copy output.mp4

สร้างไฟล์ยังสามารถนำมาใช้ในการmp4iMovie

ข้อมูลอ้างอิง: https://www.arj.no/2018/05/18/trimvideo


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

#!/usr/bin/env python3

import subprocess

name = "batman.mp4"

times = []
times.append(["01:06:00", "01:07:00"])
times.append(["01:08:00", "01:09:00"])

open('concatenate.txt', 'w').close()
for idx, time in enumerate(times):
    output_filename = f"output{idx}.mp4"
    cmd = ["ffmpeg", "-i", name, "-ss", time[0], "-to", time[1], "-c:v", "copy", "-c:a", "copy", output_filename]
    subprocess.check_output(cmd)
    with open("concatenate.txt", "a") as myfile:
        myfile.write(f"file {output_filename}\n")

cmd = ["ffmpeg", "-f", "concat", "-i", "concatenate.txt", "-c", "copy", "final.mp4"]
output = subprocess.check_output(cmd).decode("utf-8").strip()

นี้ได้รับการตอบว่าแม้ว่า
Tessaracter

1
วิธีการของฉันแตกต่างจากคำตอบที่ยอมรับ ฉันลองใช้ไฟล์ที่มีระยะเวลานานกว่านี้เพื่อสร้างไฟล์ mp4 @Tessaracter
alper

1
นี่คือคำตอบเดียวที่นี่ที่ทำงานสำหรับฉันสำหรับการตัดคลิปเล็ก ๆ จากวิดีโอขนาดใหญ่ งานนี้และรวดเร็ว !!! ขอบคุณ
lacostenycoder

1
ยินดีต้อนรับฉันดีใจที่ฉันสามารถช่วย ฉันสามารถค้นหาคำตอบนี้หลังจากลองวิธีการมากมาย ส่วนใหญ่ค่อนข้างช้า @lacostenycoder
alper

นี่ไม่สามารถใช้ "-c" กับ "คัดลอก" แทนที่จะแยกออก -c: v และ -c: a หรือไม่
nstenz


-3

แม้ว่าฉัน 6 ปีปลาย แต่ผมคิดว่าคำตอบทั้งหมดข้างต้นไม่ถูกต้องอยู่คำถาม@kalaiจะขอ สคริปต์ทุบตีด้านล่างจะประมวลผลไฟล์ข้อความในรูปแบบต่อไปนี้:

URL | start_time | end_time | filename

ตัวอย่างเช่น

https://www.youtube.com/watch?v=iUDURCrvrMI|00:02:02|00:03:41|1

และห่วงผ่านไฟล์ดาวน์โหลดไฟล์ที่youtube-dlสนับสนุนการคำนวณระยะเวลาระหว่างstart_timeและend_timeและผ่านมันไปffmpegตั้งแต่-tเป็นจริงในช่วงระยะเวลาไม่จริงend_time

ตีฉันถ้าคุณมีคำถามใด ๆ

    for i in $(<video.txt);
    do
        URL=`echo $i | cut -d "|" -f 1`;
        START=`echo $i | cut -d "|" -f 2`;
        END=`echo $i | cut -d "|" -f 3`;
        FILE=`echo $i | cut -d "|" -f 4`;

        SEC1=`echo $START | sed 's/^/((/; s/:/)*60+/g' | bc`
        SEC2=`echo $END | sed 's/^/((/; s/:/)*60+/g' | bc`

        DIFFSEC=`expr ${SEC2} - ${SEC1}`

        ffmpeg $(youtube-dl -g $URL | sed "s/.*/-ss $START -i &/") -t $DIFFSEC -c copy $FILE".mkv";
        ffmpeg -i $FILE".mkv" -f mp3 -ab 192000 -vn $FILE".mp3";
        rm $FILE".mkv";
    done;

เอาต์พุตนี้เป็นไฟล์เสียง mp3 เท่านั้นและไม่ใช่วิดีโอ
lacostenycoder

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