การตัดที่แม่นยำของวิดีโอ (+ เสียง) ด้วย ffmpeg


10

ฉันต้องการให้เว็บไซต์ของฉันอนุญาตให้ผู้ใช้สร้างคลิปของตนเองได้อย่างถูกต้องจากวิดีโอต้นฉบับที่ฉันให้ไว้

ฉันมีไฟล์วิดีโอต้นฉบับที่ฉันต้องการแปลงเป็นสิ่งที่เหมาะสมสำหรับเว็บไซต์:

Input #0, matroska,webm, from 'source.mkv': 
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s 
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)

ฉันใช้ ffmpeg เพื่อแปลงเช่น:

ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4

การดูวิดีโอนี้กลับมีคุณภาพและขนาดไฟล์เล็กพอสำหรับความต้องการของฉันและโหลด / เล่นบนเว็บไซต์ของฉัน

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

-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4

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

มีวิธีใดที่จะทำให้สิ่งนี้ถูกต้องและสอดคล้องกันเพื่อพูด 0.2 วินาที?

แก้ไข: การเพิ่ม-force_key_frames 00:00:00.2ไม่ได้ช่วย

แก้ไข: ฉันเปลี่ยนรูปวาดเพื่อใช้-c:v libx264 -c:a aac -strict experimentalแทน-codec:v copy -codec:a copyผลลัพธ์ที่ดี (ish)

ไฟล์สามารถเล่นจากภายนอกโดยไม่มีปัญหา - แต่เมื่อฉันโหลดลงในองค์ประกอบวิดีโอ html5 ของฉันและเล่น - ส่วนสุดท้ายของวิดีโอ (เสียงดี) ค้าง ส่วนสุดท้ายที่ค้างจะน้อยกว่าหนึ่งวินาที

ฉันควรลองกับโปรแกรมเปลี่ยนไฟล์วิดีโอตัวอื่นหรือไม่? ทางเลือกที่ดีที่สุดสำหรับ libx264 คืออะไร? จำไว้ว่าฉันอาจต้องการให้เว็บไซต์นี้เป็นสาธารณะ

แต่การแฮงเอาท์ไม่สามารถเล่นได้อย่างถูกต้องโดยไม่มีปัญหากับเครื่องเล่นเช่น MPC หรือ Windows Media Player แนะนำว่าเป็นปัญหากับ Google Chrome หรือองค์ประกอบวิดีโอ HTML หรือไม่ หรือฉันกำลังใช้การเข้ารหัสที่ไม่สนับสนุนหรือบางอย่าง


สิ่งนี้อาจเกี่ยวข้องกับช่วงเวลาของเฟรมหลัก ไม่ว่าในกรณีใดควรย้ายไปที่ SuperUser.com
แบรด

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

ฉันสามารถย้ายมันด้วยตัวเองได้หรือไม่ ฉันจะลองเพิ่มเฟรมหลักลงในไฟล์ต้นฉบับด้วย -force_key_frames 00: 00: 00.2
Pete Oakey

คำตอบ:


9

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

ในการเปลี่ยนคุณภาพผลผลิตเพื่อsource.mp4ใช้งาน-crfตัวเลือกที่มีค่าระหว่าง 18-28 (23 เป็นค่าเริ่มต้น) ดูส่วน CRF ของFFmpeg และ x264 คู่มือการเข้ารหัสสำหรับตัวอย่าง

คำสั่ง trimming ของคุณสามารถทำให้ง่ายขึ้น:

ffmpeg -ss 577.92 -i source.mp4 -ss 0 -t 11.98 -c copy -map 0 clip1.mp4

ฉันแทนที่ด้วย-codec:v copy -codec:a copy -c copy -map 0การทำเช่นนี้จะเป็นการคัดลอกสตรีมทั้งหมดแทนที่จะเป็นสตรีมวิดีโอและเสียงแรกเท่านั้นแม้ว่าอินพุตจะมีสองสตรีมเท่านั้นเนื่องจากคำสั่งก่อนหน้าของคุณ เนื่องจากคุณไม่สามารถปรับขนาดได้โดยไม่ต้องเข้ารหัสซ้ำดังนั้นจึงเป็นสิทธิพิเศษร่วมกัน-codec:v copyและเนื่องจากอินพุตของคุณถูกปรับขนาดตามขนาดที่ตั้งไว้แล้วฉันจึงลบตัวเลือกตัวกรองออก

หากยังไม่แม่นยำเพียงพอให้ลอง:

ffmpeg -i source.mp4 -ss 577.92 -t 11.98 -c copy -map 0 clip1.mp4

มันจะช้าลง แต่อาจแม่นยำยิ่งขึ้น ดูลิงก์ในคำตอบในลิงค์แรกที่ฉันให้ไว้สำหรับคำอธิบายความแตกต่างของตัวอย่างทั้งสองนี้

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


+1 สำหรับเคล็ดลับ แต่ฉันลอง ffmpeg -i source.mp4 -ss 577.92 -t 011.980 -c copy -map 0 clip1.mp4 แต่ส่วนแรก (เกือบหนึ่งวินาที) และส่วนสุดท้าย (อาจจะเป็นหนึ่งในสี่ส่วนที่สอง) ของ พลาดวิดีโอเสียงดีแม้ว่า
Pete Oakey

@PeteOakey คุณลองตัดโดยไม่มีการคัดลอกบิตสตรีม แต่เข้ารหัสซ้ำจริงหรือไม่
slhck

พยายามโดยไม่ต้องคัดลอกบิตสตรีมผลลัพธ์จะต่อท้ายคำถามของฉัน
Pete Oakey

3
การใช้-ssตัวเลือกเอาต์พุตแทนตัวเลือกอินพุตช่วยแก้ไขปัญหาของฉัน: เฟรมวิดีโอแรกอยู่ที่ประมาณ 1 วินาทีในวิดีโอเอาต์พุตโดยมีเฉพาะเสียงก่อนหน้านั้น (ยืนยันด้วยffprobe -show_frames) การย้าย-ssหลังจาก-iทำให้เฟรมเอาต์พุตเสียงและวิดีโอเริ่มต้นที่เฟรม 0
CodeManX
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.