ฉันจะลดขนาดวิดีโอด้วย ffmpeg ได้อย่างไร


201

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

ฉันลืมที่จะเขียนสิ่งหนึ่งเลย เมื่อวิดีโอสามารถใช้คำบรรยาย (* .srt หรือ * .sub) ฉันต้องการแปลงให้เหมาะกับพารามิเตอร์ของไฟล์วิดีโอที่แปลงแล้ว


4
ฉันไม่ได้ใช้มัน แต่ffmpegหน้า man จะแสดง-fsตัวเลือกเพื่อ จำกัด ขนาดเอาต์พุตสิ่งที่ต้องการffmpeg -i in.avi -fs 100M out.aviทำงานหรือไม่
Kevin

1
ฉันจะไม่นำคุณไปสู่หน้าคน:man ffmpeg | wc -l --> 5254

3
.aviไม่ได้เป็นปัญหาหลัก .. aviเป็นเพียงภาชนะ ปัญหาหลักคือตัวแปลงสัญญาณที่คุณใช้ .. หลาย ๆ.avivids (มากที่สุด) ใช้ตัวแปลงสัญญาณแบบเก่า (เช่น XviD) ซึ่งใช้ได้ แต่มีขนาดใหญ่กว่าสำหรับคุณภาพเดียวกันเมื่อเปรียบเทียบกับตัวแปลงสัญญาณรุ่นหลัง .. โดยทั่วไปคุณจะได้รับ การเข้ารหัสอย่างแน่นหนาโดยใช้H.264มาตรฐานการบีบอัดวิดีโอ (เช่นตัวแปลงสัญญาณx264) และการaacบีบอัดสำหรับเสียง .. คอนเทนเนอร์และตัวแปลงสัญญาณที่คุณใช้นั้นขึ้นอยู่กับคุณและโทรศัพท์ของคุณ ... .mp4คอนเทนเนอร์นั้นได้รับการยอมรับอย่างดี .. (แต่โทรศัพท์ของคุณสามารถจัดการได้: ดูลิงค์นี้
Peter.O

@Kevin ต้องการพารามิเตอร์เพิ่มเติมสำหรับการแปลง
xralf

@hesse มันหมายความว่าอะไร?
xralf

คำตอบ:


277

ดูนี้คำตอบ อ้างถึงด้านล่างเพื่อความสะดวก:

คำนวณบิตเรตที่คุณต้องการโดยหาร 1 GB ด้วยความยาววิดีโอในไม่กี่วินาที ดังนั้นสำหรับวิดีโอที่มีความยาว 16:40 (1,000 วินาที) ให้ใช้บิตเรตเป็น 1000000 ไบต์ / วินาที:

ffmpeg -i input.mp4 -b 1000000 output.mp4

ตัวเลือกเพิ่มเติมที่อาจมีมูลค่าการพิจารณาคือการตั้งค่าปัจจัยอัตราคงที่ซึ่งจะลดอัตราบิตเฉลี่ย แต่รักษาคุณภาพที่ดีขึ้น แปรผัน CRF ระหว่างประมาณ 18 และ 24 - ยิ่งต่ำยิ่งเรตมากขึ้น

ffmpeg -i input.mp4 -vcodec libx265 -crf 20 output.mp4

เปลี่ยนแปลงตัวแปลงสัญญาณตามต้องการ - libx264 อาจพร้อมใช้งานถ้าไม่ใช้ libx265 โดยมีขนาดไฟล์ใหญ่ขึ้นเล็กน้อย


วิดีโอขนาด 338 MB ลดขนาด 130 MB คุณภาพลดลงอย่างรวดเร็ว มีคำอธิบายสำหรับกระบวนการนี้ไหม? ผู้เขียนต้นฉบับไม่ได้อธิบายแนวทางของเขา
xralf

13
คำสั่งที่สองการใช้-crf 24วิดีโอ 255.3MB ที่ฉันมีและลดลงเป็น 72.7MB โดยไม่ลดคุณภาพอย่างเห็นได้ชัด มี upvote!
Patrick Roberts

2
ลดลงอย่างน่าประทับใจวิดีโอ ~ 2G ถึง 14MB ยังคงดูดีนี่เป็นผลการค้นหาครั้งแรกและเป็นสิ่งที่ฉันต้องการจริงๆขอบคุณ!
sinisterstuf

5
อาจเป็นการดีที่จะทราบว่าขณะนี้คุณสามารถใช้libx265เพื่อลดขนาดได้มากขึ้น
ZN13

6
ffmpeg -i input.avi -vcodec libx264 -crf 24 output.aviมือสอง มันลดวิดีโอ 100mb เป็น 9mb .. การเปลี่ยนแปลงคุณภาพวิดีโอน้อยมาก ขอขอบคุณ!
alpha_989

32

นอกจากว่าคุณกำลังมองหาบิตเรตที่เฉพาะเจาะจงฉันขอแนะนำ-crfตัวเลือกนี้ นี่คือการx264เข้ารหัสที่ใช้บ่อยที่สุด : http://slhck.info/articles/crf

กล่าวโดยย่อ: CRF ที่ 23 จะสร้างภาพยนตร์คุณภาพ "DVD" (~ 700MB-1GB) และค่า CRF ที่ต่ำกว่าจะมีคุณภาพสูงกว่า (ไฟล์ขนาดใหญ่)


3
โปรดให้ตัวอย่างของคำสั่งเต็มแทนการเชื่อมโยงไปยังเว็บไซต์ภายนอก (ซึ่งสามารถทำลายสักวันหนึ่ง :)
เจคเบอร์เกอร์

1
@Vicky Chijwani ระบุรหัสในตัวอย่างด้านบน สิ่งนี้เหมาะสำหรับความคิดเห็น แต่เป็นกิจกรรมแรกของฉันในเว็บไซต์นี้ ลิงค์มีคำอธิบายเพิ่มเติมเกี่ยวกับตัวเลือก crf แต่ไม่จำเป็นต้องใช้รหัสในการทำงาน
Tom Kelly

27

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

ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv

20

ฉันทดสอบคำตอบอื่น ๆ ส่วนใหญ่ที่เสนอสำหรับคำถามนี้ ข้อสรุปข้อมูลการทดสอบอยู่ด้านล่าง นี่คือคำตอบที่เสนอที่ฉันทดสอบ:

(BR) แก้ไขบิตเรตโดยใช้:

ffmpeg -i $infile -b $bitrate $newoutfile 

(CR) แปรผันปัจจัยอัตราคงที่โดยใช้:

ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile

(SZ) เปลี่ยนขนาดหน้าจอวิดีโอ (เช่นขนาดครึ่งหนึ่งของพิกเซล) โดยใช้:

ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile

(BL) เปลี่ยนโปรไฟล์ H.264 เป็น "พื้นฐาน" โดยใช้:

ffmpeg -i $infile -profile:v baseline $outfile

(DF) ใช้การประมวลผล ffmpeg เริ่มต้นโดยใช้:

ffmpeg -i $infile $outfile

ข้อมูล

  • "ขนาด" - ขนาดพิกเซลร้อยละของวิดีโอที่แปลงแล้วซึ่งสัมพันธ์กับต้นฉบับ
  • "bitrate" - บิตเรตของวิดีโอต้นฉบับและวิดีโอที่แปลงแล้ว
  • "definition" - ขนาดพิกเซลของวิดีโอ
  • "convert" - เวลาในการแปลงวิดีโอในไม่กี่วินาที

ฉันคำนวณบิตเรตเป้าหมายสำหรับ (BL) โดยใช้วิธีที่เสนอ

=== ไฟล์ A - วิธีที่โหนดช่วยในการขับเคลื่อน Angular-Fnbixa7Ts6M.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        64152 kb    214%       76%        40%        83%        76%
bitrate     411 kb/s    883        313        165        342        313
definition  1920x1080   1920x1080  1920x1080  960x540    1920x1080  1920x1080
convert     --          648        509        225        427        510

=== ไฟล์ B - การใช้ GraphQL พร้อม Angular _ By - Lee Costello-OGyFxqt5INw.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        410301 kb   33%        109%       28%        143%       109%
bitrate     2687 kb/s   880        2920       764        3843       2920
definition  3840x2160   3840x2160  3840x2160  1920x1080  3840x2160  3840x2160   
convert     --           2307       3188       1116       2646       3278

สรุป

  • วิธีการ (SZ) เป็นวิธีที่เร็วที่สุดแน่นอน มันเร็วกว่า 2X ถึง 4X นี่อาจเป็นปัญหาอย่างมากสำหรับวิดีโอความละเอียดสูงเนื่องจากวิธีการอื่น ๆ ทั้งหมดใช้เวลาในการแปลงนานกว่าความยาวจริงของวิดีโอ! ตัวอย่างเช่นวิธีการ (CR) ใช้เวลา 53 นาทีในการแปลงวิดีโอ 21 นาที

  • วิธีการ (SZ) เป็นวิธีที่ดีที่สุดแน่นอนหากคำจำกัดความของวิดีโอมีขนาดใหญ่กว่าคำจำกัดความของหน้าจอที่จะแสดง ตัวอย่างเช่นหากโทรศัพท์ของคุณสามารถแสดงภาพ 1080p เท่านั้นการส่งวิดีโอ 3840x2160 นั้นสิ้นเปลือง มันจะเป็นการดีที่สุดถ้าจะลดขนาดลงเหลือ 1080p

  • คำตอบที่เสนอบางข้อเพิ่มขึ้นจริงขนาดของวิดีโอบางรายการ ตัวอย่างเช่นวิธี (BR) มากกว่าสองเท่าของขนาดตัวอย่าง 1080p อย่างไรก็ตามมันทำให้ขนาด 2160p เป็นหนึ่งในสาม สำหรับตัวอย่างที่มีความละเอียดสูงวิธีการ (CR), (BL) และ (DF) ทั้งหมดจะเพิ่มขนาดของวิดีโอ

คำตอบที่ถูกต้อง (หรือดีที่สุด)

เป็นการดีที่สุดที่จะลดความละเอียดลงไปที่ระดับสูงสุดที่หน้าจอเป้าหมายรองรับ

หากคุณต้องการลดขนาดไฟล์เพิ่มเติมมันจะขึ้นอยู่กับตัวเลือกส่วนบุคคล คุณสามารถลดเนื้อหาข้อมูลหรือเพิ่มการบีบอัด

  • คุณสามารถลดความละเอียดได้มากขึ้นหากไม่ใช่สิ่งที่คุณกังวล

  • หากวิดีโอไม่มีฉากแอ็คชั่นที่รวดเร็วคุณอาจต้องลดอัตราเฟรมลง

  • หากคุณมีโปรเซสเซอร์ที่ทรงพลังและพื้นที่เป็นปัญหาเดียวคุณสามารถเพิ่มอัตราการบีบอัดได้

  • อัตราบิตเป็นการรวมกันของหลายปัจจัย ดังนั้นเพียงแค่บอก ffmpeg ให้ลดอัตราบิตอาจไม่ให้ผลลัพธ์ที่คุณต้องการ

  • อีกวิธีหนึ่งของเนื้อหาข้อมูลที่ต่ำกว่าคือการลดความลึกของสี วิธีการทำสิ่งนี้ยังไม่ได้กล่าวถึง


13

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

ffmpeg -i input.mp4 output.mp4

ในกรณีของฉันมันลดบิตเรตของทั้งวิดีโอและเสียง (คุณสามารถตรวจสอบและเปรียบเทียบอินพุตและไฟล์เอาท์พุตได้โดยใช้ffprobeมัน) แปลงวิดีโอ 700 Mb เป็น 60 Mb ซึ่งมีคุณภาพคล้ายกัน


1
ไปจาก 4Gb ถึง 2Gb ด้วยสิ่งนี้ขอบคุณ !!
Sam Hosseini

1
(จาก 10Mo ถึง 1.2Mb, ffmpeg auto แปลงวิดีโอของฉันซึ่งอยู่ในVP8เป็นVP9 )
sodimel

เพิ่มขนาดของวิดีโอของฉันจาก 10.8MB เป็น 14MB
pjtnt11

3

ฉันมีสูตรดั้งเดิมที่ฉันสร้างขึ้นเองเพื่อแปลงวิดีโอ Motion JPEG ที่กล้องตัวเก่าของฉันสร้าง (เป็นวิดีโอที่มีขนาดใหญ่มากเนื่องจากแต่ละเฟรมเป็นภาพ JPEG ทั้งหมด) ถึง h264 นี่คือการปรับตัวสำหรับวิดีโอประเภทอื่น (หลักสูตร ฯลฯ )

ฉันไม่ได้ใช้ ffmpegแต่mplayer และ mencoder ก่อนอื่นเราต้อง demux เสียงด้วย mplayer:

mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
  • -vo nullและ-ao nullพารามิเตอร์บอก mplayer เพื่อไม่ให้สารสกัดจากวิดีโอ

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

mencoder <video> -ovc x264 \ 
         -x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
         -nosound -o video1.h264
  • คุณสามารถเพิ่มพารามิเตอร์slow_firstpassลงใน-x264encoptsหากคุณหวาดระแวงด้วยคุณภาพสุดท้ายของวิดีโอ คู่มือ Mencoder บอกว่าตัวเลือกนี้จะปิดการใช้งานพารามิเตอร์บางอย่างที่“ ปรับปรุงความเร็วในการเข้ารหัสอย่างมีนัยสำคัญในขณะที่มีผลกระทบเพียงเล็กน้อยหรือไม่มีผลต่อคุณภาพของบัตรผ่านขั้นสุดท้าย” ดังนั้นใช้งานได้เฉพาะในขั้นตอนสุดท้าย

  • คุณควรลองหลาย ๆ ค่าสำหรับcrf - ลองเริ่มจาก 25 และเพิ่มขึ้นเรื่อย ๆ จนกว่าคุณจะสังเกตสิ่งประดิษฐ์ที่วิดีโอที่เกิดขึ้น (ค่าที่สูงกว่าบีบอัดมากกว่า) โปรดจำไว้ว่าผ่านการเข้ารหัสที่ตามมาจะปรับปรุงคุณภาพที่คุณได้รับการเลือกสรรสำหรับCRF

  • ทางเลือกสำหรับveryslowที่ตั้งไว้ช้า , ช้า , กลางฯลฯ ดูคู่มือ mencoder สำหรับรายการที่สมบูรณ์

  • ratetolควบคุมการเปลี่ยนแปลงบิตเรต - ฉันไม่แน่ใจว่าฉันทำสิ่งที่ถูกต้องที่นี่หรือไม่ แต่ฉันตั้งค่าไว้ที่ค่าสูงสุดเพื่อให้อิสระอย่างเต็มที่กับ mencoder ในการเลือกบิตเรตที่เหมาะสมสำหรับแต่ละฉาก

หลังจากผ่านครั้งแรกคุณจะทราบว่าบรรทัดสุดท้ายให้บิตเรตเฉลี่ยที่คุณจะใช้ในขั้นตอนถัดไป:

(...)
x264 [info]: kb/s:526.43

เปลี่ยนพารามิเตอร์crf ที่แนะนำในการผ่านครั้งแรกเป็นบิตเรตที่จำเป็นในการผ่านครั้งต่อไป:

mencoder <video> -ovc x264 \
       -x264encopts slow_firstpass:ratetol=100:preset=veryslow:bitrate=526:pass=3 \
       -nosound -o video2.h264

การเข้ารหัสรหัสผ่านที่สองนี้จะอ่านสถิติที่สร้างที่รหัสผ่านครั้งแรก ( divx2pass.logและdivx2pass.log.mbtree) เพื่อเพิ่มประสิทธิภาพการบีบอัด

  • โปรดทราบว่าคุณจะใช้อินพุตวิดีโอเดียวกันไม่ใช่วิดีโอที่สร้างจากการส่งผ่านครั้งแรก - การส่งผ่านครั้งแรก 'มีประโยชน์สำหรับการตรวจสอบคุณภาพเริ่มต้นเท่านั้น

  • โปรดทราบว่าpass=3( ไม่ pass=2 ) จะสร้างไฟล์สถิติใหม่เพื่อให้คุณสามารถทำซ้ำขั้นตอนสุดท้ายได้หลายครั้งตามที่คุณต้องการ ฉันมักจะทำpass=3สองครั้งและให้ความสนใจกับผลบิตเรตเสมอ

ในขณะเดียวกันคุณสามารถบีบอัดเสียงได้เช่นกันโดยใช้lameหรือoggenc:

oggenc -q<n> <audio_pcm.wav>

ในที่สุดเราจะทำการรีมิกซ์เสียงและวิดีโอ

mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
         -of lavf -lavfopts format=mp4 -o <video>.mp4
  • การ-of lavf -lavfopts format=mp4สร้างmp4รูปแบบไฟล์โดยใช้ lavopts muxers

3

ฉันบีบอัดงานนำเสนอวิดีโอ HD ความยาว 40 นาทีจาก 505MB ถึง 183MB
นั้นจะมาจาก 100MB → 36MB
วิดีโอต้นฉบับเป็น HD และเอาท์พุทเป็นศูนย์เกือบแตกต่างที่เห็นได้ชัดเจน
เป็นไฟล์วิดีโอ"ฉันต้องการเก็บไว้ แต่ HD นั้นเกินความเป็นจริง"
นี่คือคำสั่งที่ฉันใช้ด้วยเหตุผล:

ffmpeg -n -loglevel error -i inputfile.mp4 -vcodec libx264 -crf 28 -preset faster -tune film outputfilename.mp4

  • -n: หลีกเลี่ยงการเขียนทับไฟล์เอาต์พุต (ปลอดภัยยิ่งขึ้นสำหรับการทดสอบแล้วทำการแบ็ตช์)
  • -loglevel error : แสดงข้อผิดพลาดและซ่อนแถวและแถวของความคืบหน้า
  • -i inputfile.mp4 : ชื่อไฟล์อินพุต
  • -vcodec libx264: swiped จากคำตอบด้านบน
  • -crf 28: การบีบอัดแบบ Single-Pass ที่มีความแตกต่างเล็กน้อย ( "0 = lossless, 23 = ค่าเริ่มต้น, 51 = แย่ที่สุด; ช่วงที่มีสติอยู่ในช่วง17–28 " ) เอกสารอ้างอิง
  • -preset faster: ดูเร็วกว่าการเข้ารหัสเริ่มต้นของเอกสารอ้างอิง "ปานกลาง" 2 เท่า
  • -tune film: ระบุอินพุตเป็นวิดีโอ HQ (ตัวเลือกอื่นรวมถึง 'การ์ตูน', 'ภาพนิ่ง' .. ) เอกสารอ้างอิง
  • outputfilename.mp4 : ชื่อไฟล์ที่ส่งออก

สำหรับไดเรกทอรีของไฟล์วิดีโอ:

for i in *.{avi,flv,m4v,mov,wmv,mp4,MP4,TS,mkv}; do ffmpeg -n -loglevel error -i "$i" -vcodec libx264 -crf 28 -preset faster -tune film "cc${i}"; done

ปัญหาที่พบ:

  • วิธีที่สะอาดกว่าในการรวบรวม "ไฟล์วิดีโอทั้งหมด" โดยไม่ต้องมีนามสกุลทั้งหมดในคำสั่ง
  • วิธีที่สะอาดกว่าในการส่งออกชื่อไฟล์โดยไม่มีคำนำหน้า "cc" และสามารถยืนยันวิดีโอก่อนที่จะลบ
  • .webmไฟล์ไม่ทำงานกับคำสั่ง มีการแลกเปลี่ยน"cc${i}""${i%.*}.mp4"

Handbrake เป็นทางเลือกโอเพนซอร์ซกับ UI


มันได้ผล. แต่มันใช้เวลามากเกินไป มีการปรับปรุงสำหรับเวลาดำเนินการน้อยลงหรือไม่
Nirali

2

คุณจะต้องใช้การเข้ารหัส 2 รอบเพื่อ "พอดี" วิดีโอภายในขนาดไฟล์ที่กำหนด (บิตเรต) โดยไม่ลดคุณภาพลงอย่างมาก นี่เป็นหัวข้อที่ละเอียดมาก: http://web.archive.org/web/20171130050515/http://www.mpabo.com/2014/12/14/ffmpeg-and-x264-encoding-guide/


1

ฉันเขียนสคริปต์ทุบตีเพื่อลดขนาดของวิดีโอและลองใช้ค่า CRF ที่แตกต่างกันโดยอัตโนมัติ

โดยทั่วไปคุณจะ

  • เลือกช่วงของค่า CRF
  • เรียกใช้สคริปต์
  • ตรวจสอบขนาดของวิดีโอที่สร้างและเลือกวิดีโอที่คุณต้องการ

สิ่งนี้มีประโยชน์จริง ๆ เมื่อคุณมีขนาด จำกัด ที่คุณต้องการบรรลุและคุณไม่รู้ว่าค่า crf คืออะไรซึ่งจะช่วยให้คุณทำ

ฉันหวังว่านี่จะช่วยใครซักคน ฉันแบ่งปันกับเพื่อนร่วมงานและทุกคนเห็นว่าเป็นประโยชน์

#!/bin/bash

# bigger values of crf will lead to a bigger compression (smaller video size)
#for i in 1 2 3 4 5
for i in {25..28}
do
# you can remove the option -y if you want to be asked if to overwrite a file with the same name (leave the -y only if you understand what you are doing, otherwise you might rewrite an important file)
   ffmpeg -y -i NAMEOFTHEVIDEOTOCOMPRESS.mp4 -c:v libx264 -crf $i -preset veryfast -profile:v baseline -level 3.0 -strict -2 out_$i.mp4
   printf "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Done compression at crf=$i \n\n"
done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.