ตัดไฟล์วิดีโออย่างแม่นยำจากบรรทัดคำสั่ง


22

ฉันมีปัญหาในการค้นหาแอปพลิเคชัน cli ที่สามารถใช้ไฟล์วิดีโอ (avi, mkv และ mp4 ได้อย่างดี) และตัดคลิปสั้น ๆ (2-6 วินาที) ด้วยความแม่นยำของเวลาที่แม่นยำ ฉันได้ลองffmpeg , mencoder , avidemuxและmp4boxแต่พวกเขาทั้งหมดตัดกับคีย์เฟรมซึ่งสร้างคลิป 6+ วินาที มีเครื่องมือที่จะเข้ารหัสไฟล์อินพุตอีกครั้งและตัดเวลาที่ถูกต้องหรือตัดไม่ถูกต้องเข้ารหัสอีกครั้งแล้วตัดอย่างแม่นยำหรือไม่


คุณอาจต้องเปลี่ยนรหัสใหม่ก่อนที่จะตัดให้ถูกต้อง คุณสามารถเพิ่มความเร็วได้โดยตัดกุญแจหลักที่อยู่รอบ ๆ ออกไปก่อนและเปลี่ยนรหัสตัวอย่างใหม่เท่านั้น
Nifle

4
คุณลองคำสั่ง FFmpeg ใด ฉันเชื่อว่าถ้าคุณถอดรหัสวิดีโอมาก่อน (เช่นวาง-ssพารามิเตอร์หลัง -i ) ควรมีความแม่นยำมากขึ้น
slhck

1
เคล็ดลับ FFmpeg ทำงานได้! ฉันไม่ได้ตระหนักถึงคำสั่งที่มีความสำคัญมาก นี่เป็นสิ่งเดียวกันสำหรับเครื่องมืออื่น ๆ หรือไม่?
curmil

คำตอบ:


23

ตัดวิดีโอด้วย ffmpeg

คุณสามารถตัดวิดีโอด้วย FFmpeg ได้อย่างถูกต้อง ตั้งแต่รุ่น 2.5 มันง่ายมาก เช่นนี้จะตัด 10 วินาทีเริ่มต้นจาก 0 นาที, 3 วินาทีและ 123 มิลลิวินาที

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

ตำแหน่งและเวลาอาจเป็นวินาทีหรือในhh:mm:ss[.xxx]รูปแบบ

โปรดทราบว่าในตัวอย่างเหล่านี้วิดีโอจะได้รับการเข้ารหัสอีกครั้งโดยใช้ตัวเข้ารหัสx264 เสียงถูกคัดลอก

นอกจากนี้คุณยังสามารถใช้-toแทน-tการระบุจุดสิ้นสุดแทนระยะเวลา ในกรณีนี้-toจะเทียบเท่ากับ-tเนื่องจากการใส่-ssส่วนหน้า-iffmpeg จะค้นหาจุดนั้นก่อนแล้วจึงเริ่มส่งออก

ดูที่รายการค้นหาวิกิ


การตัดที่แม่นยำสำหรับffmpegรุ่นที่เก่ากว่า

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

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

ที่นี่-toและ-tประพฤติแตกต่างกัน -t 10จะสร้างคลิปยาวสิบวินาทีในขณะที่-to 10จะสร้างคลิปที่มีความยาวเจ็ดวินาที


แทนที่จะ-c:v libx264 -c:a libfaacคิดว่าเราสามารถใช้คำสั่ง-acodec copy -vcodec copyffmpeg เพื่อตรวจจับและใช้โคเดกเดียวกับไฟล์ต้นฉบับ มีใครยืนยันได้บ้าง
Baodad

2
@ Baodad คุณทำได้ แต่สิ่งนี้จะไม่ถูกตัดอย่างแม่นยำ เมื่อคัดลอกบิตสตรีมวิดีโอ / เสียง ffmpeg ต้องเริ่มต้นที่คีย์เฟรมซึ่งอาจถูกวางไว้ที่ทุก ๆ วินาทีหรือแยกออกจากกัน
slhck

เอาชนะข้อผิดพลาด "libfaac" "ที่ไม่รู้จักได้อย่างไร
Doug

@Doug -c:a aac -strict experimentalเลือกการเข้ารหัสที่แตกต่างกันเช่น นั่นเป็นทางออกที่ง่ายที่สุด
slhck

1

เครื่องมือบรรทัดคำสั่ง Linux เดียวที่ฉันพบในตอนนี้ซึ่งสามารถตัดที่เฟรมที่แน่นอน (หรือด้วยความแม่นยำของเฟรม) คือmelt( sudo apt-get install melt)

สมมติว่าคุณมีinputvid.mp4- ก่อนตรวจสอบการตั้งค่าการเข้ารหัสด้วยคำพูดffmpeg(ที่นี่ฉันแค่บอกว่าฉันต้องการเข้ารหัสอีกครั้งเพื่อ-f mp4แต่เป็นไฟล์/dev/nullเพื่อให้การส่งออกถูกทิ้งฉันเปลี่ยนเส้นทาง stderr เพื่อให้ฉันสามารถ grep ผ่านมัน - ทราบตรงกลาง คำสั่งจะแจ้งให้และคุณควรตอบyด้วย ENTER เพื่อให้กระบวนการดำเนินการและทิ้งข้อมูลที่เป็นประโยชน์นี่คือกับ ffmpeg 3.3.3 บน Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

ตกลงดังนั้นเราจะเห็นตัวffmpegเลือกlibx264และaacตัวเข้ารหัสสำหรับวิดีโอนี้ จากนั้นเราสามารถป้อนสิ่งนี้ในสำหรับmelt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... และmeltจะตัดส่วนระหว่างเฟรม 7235 และ 7349 ลงในไฟล์ใหม่, cut.mp4. จากนั้นเพื่อตรวจสอบว่าcut.mp4ลูปถูกต้องใช้meltอีกครั้งเพื่อเล่นซ้ำสองครั้ง - และเล่นไปที่หน้าต่าง SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... และนี่คือสิ่งที่ffmpegเห็นสำหรับไฟล์นี้:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

การตั้งค่าการเข้ารหัสวิดีโอสำหรับcut.mp4ดูเหมือนจะเหมือนกับinputvid.mp4ยกเว้นบิตเรตวิดีโอเปลี่ยนจาก 389 kb / s เป็น 526 kb / s และการตั้งค่าการเข้ารหัสเสียงเกือบจะเหมือนกันยกเว้นอัตราการสุ่มเปลี่ยนจาก 44100 เป็น 48000 Hz; แม้ว่าที่สามารถควบคุมได้ด้วย:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... อย่างไรก็ตามถึงกระนั้นอัตราบิตสุดท้ายของวิดีโอสำหรับฉันก็จบลงที่ 337 kb / s ถึงกระนั้นการตัดลูปก็ละเอียด (และนั่นรวมถึงเสียง) เมื่อเล่นในลูปดังนั้นฉันเดาว่านี่เป็นความแม่นยำของเฟรม ...


1
meltกำลังเข้ารหัสวิดีโออีกครั้งและใช้ไลบรารี FFmpeg ที่อยู่ด้านล่าง หากคุณอนุญาตให้เข้ารหัสอีกครั้ง ffmpeg สามารถสร้างเอาต์พุตเดียวกัน
Gyan

ขอบคุณ @Gyan - ไม่ทราบว่า (โดยเฉพาะที่meltใช้ไลบรารี FFmpeg) รู้ดี!
sdaau

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

0

เช่นเดียวกับ Baodad กล่าวในความคิดเห็น (ฉันโพสต์เพราะหาไม่เจอถ้าคุณอ่านเร็ว) วิธีที่ดีกว่าคือการตรวจจับตัวเข้ารหัสเสียง / วิดีโอโดยอัตโนมัติโดย ffmpeg ดังนั้น:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • เริ่ม @ 00: 05: 17.18
  • input = in.mp4
  • stop @ 00: 06: 29.10
  • output = out.mp4

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