iMovie (ไม่ lossless แต่ดีกว่าก่อน)
iMovie v10 (เปิดตัวบางครั้งหลังจากที่คำถามถูกถาม) ตอนนี้จัดการประเภทสื่อได้ดีขึ้นดังนั้นหลีกเลี่ยงการเข้ารหัสการนำเข้าอีกครั้งสำหรับเนื้อหา H.264 (mp4, m4v, mov, AVHDC, mts, mt2s) ส่วนใหญ่
อย่างไรก็ตามมันจะยังคงเข้ารหัสอีกครั้งในการส่งออกดังนั้นจึงไม่สามารถสูญเสียทางเทคนิค - คุณลักษณะใหม่อีกอย่างหนึ่งคือความสามารถในการปรับแต่งคุณภาพการส่งออกซึ่งสามารถใกล้เคียงกับการสูญเสียมากขึ้น ฉันสงสัยว่าคำตอบส่วนนี้สามารถใช้ได้กับซอฟต์แวร์ตัดต่อวิดีโอ 'project driven' อื่น ๆ (เช่น Premiere หรือ Final Cut) เพราะฉันคิดว่าพวกเขาทั้งหมดเข้ารหัสอีกครั้งในเอาต์พุต
โดยส่วนตัวแล้วฉันคิดว่าการเข้ารหัสซ้ำครั้งเดียวไม่ใช่ปัญหาใหญ่ แต่เข้าใจว่าคุณได้ขอวิธีแก้ปัญหาแบบไม่สูญเสียโดยเฉพาะดังนั้น ...
Lossless (แต่วิธีซับซ้อนกว่า!)
มีข้อ จำกัด ทางเทคนิคเกี่ยวกับวิธีที่แม่นยำในการตัดวิดีโอโดยไม่ต้องเข้ารหัสใหม่อย่างน้อยบางส่วนของวิดีโอและโดยทั่วไปจะขึ้นอยู่กับความถี่ของ i-frame หากทุกเฟรมเป็น i-frame คุณสามารถตัดได้ทุกที่ แต่ถ้าอยู่เพียงไม่กี่วินาทีคุณก็สามารถตัด loss ที่ i-frames เหล่านั้นได้โดยไม่สูญเสียเนื้อหาหรือต้องเข้ารหัสใหม่ (อย่างน้อยส่วนหนึ่งของ สตรีม) เพื่อให้สามารถเริ่มต้นด้วย i-frame
ffmpeg
คำถาม & คำตอบนี้ทำให้เกิดคำถามว่าจะตัดระหว่าง i-frames โดยffmpeg
เฉพาะอย่างไร ฉันไม่รู้แอพ GUI ใด ๆ ที่จะทำเช่นนี้ แต่โดยทั่วไปคุณเรียกใช้คำสั่งบางอย่างดังนี้:
ffmpeg -i input.m4v -vcodec copy -acodec copy -ss 00:01:20.000 -t 00:37:50.000 output.m4v
สองครั้งที่ระบุคือเริ่มต้นและระยะเวลาและสามารถระบุเป็นวินาทีหรือhh:mm:ss.ss
และ-acodec copy
และ-vcodec copy
บอกให้ ffmpeg ไม่เข้ารหัสอีกครั้ง
ฉันไม่แน่ใจว่าจะเกิดอะไรขึ้นถ้าคุณตัดเร็วเกินไป แต่ฉันคิดว่าวิดีโอนั้นว่างเปล่า (หรืออาจเสียหายขึ้นอยู่กับผู้เล่น) จนกว่าจะพบ i-frame ดังนั้นคุณอาจต้องการหา i-frame ที่ใกล้ที่สุดก่อนที่คุณจะตัด คำตอบนี้แก้ปัญหาที่ใช้ffprobe
และawk
แม้จะเล็กน้อยเชื่องช้า โดยพื้นฐานแล้วคุณใช้ffprobe
ในการสแกนเฟรมและค้นหาคีย์เฟรมที่ใกล้ที่สุด ( flags=K
) ก่อนจุดตัดในอุดมคติของคุณ เอาต์พุตเต็มสำหรับแต่ละเฟรมของวิดีโอสามารถเห็นได้ดังนี้:
ffprobe -select_streams v -show_frames <INPUT>
คำตอบที่เชื่อมโยงระบุคำสั่งนี้เพื่อค้นหาคีย์เฟรมก่อนเวลาที่กำหนด:
ffprobe -select_streams v -show_frames -v quiet INPUT.mp4 |
awk -F= '
/pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } }
/pkt_pts_time/ { if (i && ($2 >= 150)) print $2; }
' | head -n 1
และในที่สุดหากคุณต้องการตัดที่ใดที่หนึ่งระหว่างสองเฟรม i คุณสามารถแยกวิดีโอและเข้าร่วมอีกครั้ง จากข้อมูลจากคำตอบนี้ควรเป็นดังนี้:
ffmpeg -f concat -i list_of_videos.txt -c copy OUTPUT.mp4
ไหนlist_of_videos.txt
เป็นไฟล์ข้อความที่เรียบง่ายรายชื่อไฟล์ที่คุณต้องการ concatenate
สรุป
iMovie น่าจะดีพอสำหรับกรณีส่วนใหญ่ (ตั้งแต่ v10) และง่ายมาก
ffmpeg สามารถทำมันแบบ lossless (หรือใกล้เคียงกับ lossless มาก) ด้วยการเล่นซอ ระดับความยากนั้นขึ้นอยู่กับว่าคุณจู้จี้จุกจิกเกี่ยวกับจุดเริ่มต้นที่แม่นยำและความถี่ของ i-frames อย่างไร