เปลี่ยนอัตราเฟรมของวิดีโอ MP4 ด้วย ffmpeg


8

ฉันมีวิดีโอในรูปแบบ mp4 ที่มีอัตราเฟรม.33(1 เฟรมเป็นเวลา 3 วินาที) ฉันต้องการเพิ่มอัตราเฟรมเป็น 5 เฟรม / วินาที ฉันได้ลองใช้คำสั่งด้านล่าง แต่ไม่ได้ทำสิ่งใด:

ffmpeg -i <input.mp4> -r 5 <output.mp4>

แนวคิดใดที่ ffmpeg ไม่สนใจ-rตัวเลือก


หากคุณกำลังพยายามเพิ่มความเร็ว / ลดความเร็ววิดีโอแทนการทำซ้ำ / ปล่อยเฟรมดูsuperuser.com/questions/854753/ …และ / หรือaskubuntu.com/questions/370692/ …
Peter Cordes

คำตอบ:


7

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ไม่มีคำตอบในปัจจุบันเป็นวิธีที่แนะนำอีกต่อไป

Lossless (วิดีโอ) remuxing

ดังที่ระบุไว้ในความคิดเห็นมีวิธีการทำเช่นนี้ที่วิดีโอไม่ จำเป็นต้องเข้ารหัสอีกครั้ง มันต้องทำการ remuxingไฟล์เป็น MKV formatterter รูปแบบอื่นแล้วทำการ remuxing กลับไปเป็น MP4 นี่คือตัวอย่างที่เปลี่ยนวิดีโอเป็น 12 เฟรม / วินาที:

mkvmerge --default-duration 0:12fps --fix-bitstream-timing-information 0 original-video.mp4 -o temp-video.mkv
ffmpeg -i temp-video.mkv -c:v copy slow-video.mp4

หากวิดีโอมีเสียงคุณสามารถทำให้ช้าลงได้โดยไม่ต้องเปลี่ยนระดับเสียง แต่ไม่ใช่การแปลงแบบไม่สูญเสีย ตัวอย่างด้านล่างถือว่าวิดีโอต้นฉบับเป็น 24 เฟรม / วินาทีเพื่อให้เสียงจำเป็นต้องชะลอความเร็วลงครึ่งหนึ่ง (0.5) โดยใช้ตัวกรองatempoของ ffmpeg

mkvmerge --default-duration 0:12fps --fix-bitstream-timing-information 0 original-video.mp4 -o temp-video.mkv
ffmpeg -i temp-video.mkv -c:v copy -c:a aac -filter:a "atempo=0.5" slow-video-with-audio.mp4

FFMPEG Wiki Guidance

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

การเร่ง / ลดความเร็ววิดีโอ

คุณสามารถเปลี่ยนความเร็วของการสตรีมวิดีโอโดยใช้ตัวกรองวิดีโอ setpts โปรดทราบว่าในตัวอย่างต่อไปนี้กระแสเสียงจะไม่เปลี่ยนแปลงดังนั้นจึงควรปิดการใช้งานด้วย - และ

ในการเพิ่มความเร็วของวิดีโอเป็นสองเท่าคุณสามารถใช้:

ffmpeg -i input.mkv -filter:v "setpts=0.5*PTS" output.mkv

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

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

ffmpeg -i input.mkv -r 16 -filter:v "setpts=0.25*PTS" output.mkv

ในการชะลอวิดีโอของคุณคุณต้องใช้ตัวคูณมากกว่า 1:

ffmpeg -i input.mkv -filter:v "setpts=2.0*PTS" output.mkv

เรียบ

คุณสามารถทำให้วิดีโอช้า / เร็วได้อย่างราบรื่นด้วยตัวกรองวิดีโอย่อส่วน เรื่องนี้เป็นที่รู้จักกันในนาม

ffmpeg -i input.mkv -filter "minterpolate='mi_mode=mci:mc_mode=aobmc:vsbmc=1:fps=120'" output.mkv

ตัวเลือกอื่น ๆ ได้แก่ slowmoVideo และ Butterflow เร่งความเร็ว / ลดเสียง

คุณสามารถเร่งความเร็วหรือลดความเร็วเสียงด้วยตัวกรองเสียง atempo วิธีเพิ่มความเร็วเสียงเป็นสองเท่า:

ffmpeg -i input.mkv -filter:a "atempo=2.0" -vn output.mkv

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

ffmpeg -i input.mkv -filter:a "atempo=2.0,atempo=2.0" -vn output.mkv

ด้วยการใช้ filtergraph ที่ซับซ้อนคุณสามารถเพิ่มความเร็วของวิดีโอและเสียงในเวลาเดียวกัน:

ffmpeg -i input.mkv -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mkv

1
มันเป็นไปได้ที่จะ / ความเร็วช้าโดยเพียงแค่ remuxing แต่ FFmpeg ไม่ทราบวิธีที่จะทำมัน เช่นสำหรับ mkv, mkvtoolnix สามารถทำได้ เช่นmkvmerge --default-duration 0:24000/1001fps --fix-bitstream-timing-information 0 in.mkv -o out.mkv เปลี่ยน framerate ใน MKV ภาชนะ คุณสามารถทำการ remux ไปยัง MKV และกลับไปเป็น MP4 หรือค้นหาเครื่องมือที่ใช้กับ MP4 ได้โดยตรง xcoding วิดีโอนั้นใช้งาน CPU มากและสูญเสียดังนั้นมันจึงเป็นตัวเลือกที่น่ากลัว
Peter Cordes

เห็นด้วยอย่างยิ่งว่าควรเลือกใช้การรีมิกซ์เป็น framerate ต่ำกว่าเนื่องจากเป็นวิธีการแบบไม่สูญเสียที่ใช้ทรัพยากรน้อยกว่ามาก ในทางปฏิบัติฉันไม่พบเครื่องมือที่ดีสำหรับการทำเช่นนั้นกับ MP4 ฉันไม่ได้ลองมาก่อน แต่กลับมาเมื่อฉันเขียนคำตอบนี้ครั้งแรกที่ฉันทำ MP4-> MKV-> การรีมิกซ์ MP4 และฉันไม่สามารถใช้งานได้โดยใช้ mkvtoolnix, ffmpeg และ / หรือ mp4box ฉันจะลองกับพารามิเตอร์ที่คุณแนะนำ
pseudosavant

6

หากไฟล์อินพุตไม่มีอัตราเฟรมที่ถูกต้องคุณอาจต้องตั้งค่าอย่างชัดเจน

ffmpeg -r 1 -i input.mp4 -r 24 output.mp4

การแปลงรหัสนี้เมื่อคุณจำเป็นต้องรีมิกซ์จริงๆเท่านั้น (ยกเว้นว่าคุณต้องการทำซ้ำ / ปล่อยเฟรมแทนการชะลอความเร็ว / เร่งวิดีโอ)
Peter Cordes

3

ฉันจะได้รับการเปลี่ยนแปลง framerate ที่จะมีผลถ้าไฟล์อินพุตถูกจัดเป็นไฟล์ "ดิบ":

ffmpeg -r 5 -f h264 -i input.h264 -vcodec copy -an output.mkv

หากไม่ระบุ-f h264ว่าจะใช้ค่าเริ่มต้นที่ 25 fps และไม่สามารถเปลี่ยนแปลงได้ เห็นได้ชัดว่านี่เป็นเพราะสตรีมไม่มีข้อมูลที่เป็นเท็จเลยและนี่คือค่าเริ่มต้นของเฟรม ffmpeg

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


1
คำตอบที่เป็นประโยชน์ของฉัน ไม่ต้องเข้ารหัสที่นี่
yota

1

คุณลักษณะดังกล่าว - ของการเปลี่ยนเฟรม - ถูกเรียกว่า "สอดคล้อง" และมักจะใช้ในการผลิตภาพช้าหรือเร็วไปข้างหน้าเช่นแสดงการเจริญเติบโตของพืชในไม่กี่นาทีของวัน ffmpeg ไม่อนุญาตให้เขียนทับ / เปลี่ยนเฟรมโดยไม่ต้องเข้ารหัสใหม่ หากทำเช่นนั้นระยะเวลาจะเปลี่ยนไปและเสียงจะไม่ซิงค์เว้นแต่จะมีการแก้ไขแยกต่างหาก แต่ฉันเกรงว่าเสียงของคุณจะไม่ได้รับความสนใจด้วยอัตรา. 33

คุณต้องการทำตามเพราะคุณต้องการเปลี่ยนเฟรม แต่ ffmpeg ไม่สนใจ-rอย่างเงียบ ๆถ้า framerate ถูกระบุในอินพุตไฟล์ เนื่องจากไฟล์อินพุตของคุณอยู่ในรูปแบบ. mp4, framerate ของมันจะมีความสำคัญกว่า-rเมื่อไม่จำเป็นต้องเข้ารหัสอีกครั้ง สำหรับสิ่งนี้คุณต้องมีเครื่องมืออื่น: mencoder

สมมติว่าไฟล์อินพุตของคุณไม่มีเสียง - น่าจะเป็นจริงสำหรับวิดีโอใด ๆ ที่มีอัตราเฟรม. 33 - สิ่งที่คุณต้องการคือ:

$ mencoder -fps 5 -o <output> -ovc copy -nosound <input.mp4>

โปรดสังเกตว่า mencoder ตามค่าเริ่มต้นจะสร้างเอาต์พุตในรูปแบบ AVI


1
นี่เป็นสิ่งที่ผิด หากrระบุเป็นสวิตช์เอาต์พุต ffmpeg จะสร้างเอาต์พุตที่ framerate ที่ระบุโดยไม่คำนึงถึง framerate ของอินพุต หากrระบุว่าเป็นสวิตช์อินพุต ffmpeg จะทำซ้ำหรือดร็อปเฟรมตามความจำเป็นเพื่อป้อนจำนวนเฟรมต่อวินาทีที่ระบุของอินพุตไปยังตัวกรอง / ตัวเข้ารหัส
Gyan

พฤติกรรมที่คุณอธิบายเมื่อrมีการสลับอินพุตขัดแย้งกับการทดสอบก่อนหน้าของฉันในรูปแบบ. mp4, บันทึก Malvineous '(ในหน้านี้) และคำอธิบายข้อผิดพลาด 403 trac.ffmpeg.org/ticket/403 ; คำอธิบายของคุณเมื่อrใช้กับเอาต์พุตเกิดขึ้นเมื่อเข้ารหัสอีกครั้งในขณะที่สถานการณ์ของ OP น่าจะเป็นกรณีที่สอดคล้องกัน (แก้ไข framerate โดยไม่มีการเข้ารหัสซ้ำ) โดยข้อเท็จจริงที่ว่าเขามี. 33 framerate
Tankman 六四

1
รายงานการตรวจสอบการวางที่นี่ จดบันทึกบรรทัดคำสั่งที่ด้านบนเมทาดาทาอินพุตและเอาต์พุตและสุดท้ายคือหมายเลข ของเฟรมที่เข้ารหัส
Gyan

1
ตกลงว่า OP ต้องการเพียงแค่ปรับไฟล์ แต่คำสั่งที่ให้ไว้คือการเข้ารหัสอีกครั้งเนื่องจาก copy switch (es) ไม่ได้ระบุไว้ ในสถานการณ์สมมตินั้น ffmpeg ควรสร้างกระแสใหม่ที่rfps
Gyan

ขอบคุณ Mulvya สำหรับตัวอย่างผลลัพธ์ที่น่าเชื่อถือ -rใช่คุณมีสิทธิในการใช้งานของ การใช้งานนั้นไม่สามารถส่งผลกระทบต่อการทดลองก่อนหน้านี้ของฉันในการตอบสนองต่อ OP เนื่องจากการพิจารณากรณีที่สอดคล้องฉันไม่เคยละทิ้งพารามิเตอร์การคัดลอกจาก ffmpeg และ-rถูกเพิกเฉย ฉันเขียนคำขอคุณลักษณะ: trac.ffmpeg.org/ticket/5170
Tankman 六四

0

วิธีที่เร็วที่สุดคือการสร้างไฟล์ BAT ในไดเรกทอรีด้วยแถวต่อไปนี้:

@ECHO OFF

for %%f in (*.mp4) do (

echo “fullname: %%f”

del temp.mkv

mkvmerge --default-duration 0:18fps --fix-bitstream-timing-information 0 %%f -o temp.mkv

del %%f

ffmpeg -i temp.mkv -c:v copy %%f

del temp.mkv

)

คุณต้องมี mkvmerge และ ffmpeg ในไดเรกทอรีเดียวกัน มันเปลี่ยนแปลงทุกไฟล์ mp4 ในไม่กี่วินาทีโดยอัตโนมัติโดยไม่สูญเสียคุณภาพ

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