[video] كيفية استخراج مقاطع فيديو دقيقة مع ffmpeg؟


Answers

أعتقد أن المشكلة التي يطرحها السؤال والإجابات الأخرى هي أنهم يستخدمون -ss كخيار في ملف الإخراج ، وليس في ملف الإدخال. معظم خيارات ffmpeg ليست عالمية ، ولكن بدلاً من ذلك تنطبق فقط على الملف الذي تسبقه. غالبًا ما لا يكون واضحًا في أي مكان يحتاج إليه الخيار ، لذلك يلزم إجراء التجربة والخطأ أحيانًا.

تستخدم بشكل صحيح ، قبل ملف الإدخال الذي يقصد تطبيقها على -ss و -t عملت بشكل جيد بالنسبة لي. عند تضمين الصوت في الإخراج ، اضطررت إلى استخدام -shortest كخيار لملف الإخراج ، أو الحصول على 2 دقيقة من الصوت مع 2 ثانية من الفيديو.

إصدار ffmpeg N-67413-g2a88c74 (مصدر git أساسًا من 14 ديسمبر 2014)

وهنا سطر الأوامر اعتدت على صنع مقطع في الآونة الأخيرة. (في الواقع تم تعديله ليكون مثالاً أفضل ، منذ أن تركت الصوت في هذا ، ولم أقم بذلك.)

ffmpeg -ss 120.2 -t 0.75 -i ../mcdeint.60p.lossless264.slow.mkv -c:a libopus -shortest -aspect 16:9 -preset veryslow -x264-params nr=250:ref=6 -crf 22 -movflags +faststart clip2.mkv

مع -c:a copy (مصدر يحتوي على صوت AC3) ، يبدأ التشغيل مع مشغل mplayer. ربما يمسك الصوت من بداية الإطار الصوتي الذي يحتوي على البداية ، ومن ثم يجب عليه استخدام aa / v offset في الحاوية. عند بدء التشغيل ، يستغرق الأمر جزءًا من الثانية حتى يتسنى للمقطع الصوتي الحصول على الفيديو قبل هذا الإزاحة ، وحتى ذلك الحين يتم تشغيل الفيديو بمعدل FPS منخفض جدًا. لذلك أنا xcoded الصوت. لا يمكن تشغيل opus ولا pcm_s16le في mp4 ، لذلك استخدمت حاوية mkv لهذا المثال.

المصدر عبارة عن ترميز x264 بدون فقدان ( -qp 0 ) من إخراج -qp 0 بطيء جدًا = 3: 1 ، mcdeint = 3: 1: 10 (في بعض الفيديو المتداخل BFF من قرص DVD NTSC ، من كاميرا DV). إنه ليس كل إطارات I ، إنه إطارات P مع فاصل زمني أساسي في keyframe.

ضبط -s بمقدار 0.2 ثانية فعل بالضبط ما كنت آمل ، لذلك يجب ffmpeg معالجة فك ترميز إلى النقطة المطلوبة. لم تكن مجرد مصادفة لإطار حيث أردت واحدة. ربما -accurate_seek هو الافتراضي؟ أنا أيضا الحصول على نفس النتيجة (بايت GIF بايت متطابقة بايت) كما عند استخدام مصدر فقدان ffvhuff كإدخال. (لكنه يعمل بشكل أسرع ، لأنه لا يحتاج إلى فك ترميزه إلى النقطة المطلوبة.)

هناك خيار آخر يمكن أن يكون مناسبًا هو -seek2any ، ولكنه يقول "السعي إلى عدم الإطار الرئيسي على مستوى demuxer" ، والذي يبدو أنه سيسمح لك بالبحث بطرق من شأنها أن تنتج مخرجات مشوهة. (على سبيل المثال ، بدء فك التشفير دون الحاجة إلى توليد المراجع التي يتطلبها الإطار الحالي ، فما عليك سوى استخدام الرمادي بالكامل؟)

لم أحاول استخدام -c:v copy ، لأنني أقطع مقطعًا قصيرًا حقًا ، لذلك أعلم أنه لن يكون هناك إطارات لأني أحتاج إليها.

هذا هو سطر الأوامر الذي استخدمته بالفعل ، لعمل مقطع قصير من slo-mo بدون صوت.

ffmpeg -ss 120.2 -t 0.75 -i ../vid.yadif3.1,mcdeint3.1.10.ffvhuff.mkv -an -shortest -aspect 16:9 -c:v libx264 -preset veryslow -x264-params nr=250:ref=6 -crf 22 -filter:v "setpts=3.0*PTS" -movflags +faststart -r 20 clip.mp4

لاحظ أن -r 20 مهم ، لأنه بخلاف mkv ، يكون إخراج MP4 لـ ffmpeg ثابتًا بمعدل الإطار فقط (تحرير: لأن -vsync vfr ليس الافتراضي مع muxer mp4). بدون إخبارها بشكل مختلف ، فإنها ستقوم بإعداد FPS = FPS للإدخال ، وإطارات مكررة عند الحاجة لتحقيق ذلك. يمكن لـ x264 و gif المتحركة (مع الشفافية) تشفير الإطارات المكررة بكفاءة عالية ، ولكنها لا تزال سخيفة.

قبل طهي هذا كمثال ، كنت قد فعلت ذلك في 2 خطوات ، واحد خرج إلى MKV ، ثم ffmpeg -i clip.mkv -c:v copy -movflags +faststart -r 20 clip.mp4 to remux. راجع للشغل ، فإنه من الممكن تغيير إطار في الثانية من الفيديو عند remuxing ، دون xcoding ، فقط ليس مع ffmpeg. https://superuser.com/questions/740196/reducing-video-size-with-avconv-why-does-the-size-increase . ولكن على أي حال ، أرسلت ffmpeg 45 إطارًا فقط إلى libx264 عند إنشاء mkv ، على الرغم من أنها تعتقد أنها كانت تصنع فيديو 2.2 مرة بمعدل 60 إطارًا في الثانية. لا تستخدم ffmpeg مع mp4 للعمل مع عناصر FPS المتغيرة.

تحرير: تبين الافتراضات ffmpeg إلى -vsync vfr mkv ، ولكن ليس لـ mp4. مع -vsync vfr ، يمكن أن يكتب ffmpeg VFR إلى خرج mp4 على ما يرام.

ومرة أخرى لإخراج gif ، إذا قررت عدم طرحه مع فيديو HTML5 ( <video controls autoplay loop> <source src="clip.mp4" type="video/mp4"> </video> )

ffmpeg -ss 120.2 -t 0.75 -i ../vid.yadif3.1,mcdeint3.1.10.ffvhuff.mkv -an -shortest -aspect 16:9 -filter:v "setpts=3.0*PTS,scale=854x480" -r 20 clip.gif

اضطررت إلى استخدام scale= نظرًا لأن حاوية gif لا تخزن نسبة عرض إلى ارتفاع ، لذا لا يمكن ضبطها تلقائيًا عند التشغيل. (يتم تحجيم الفيديو 720 × 480 بكسل 16: 9 إلى 854 × 480 عند التشغيل. في الواقع يجب أن يكون 853.333 ، ولكن ذلك يتم تقريبه ، ثم تخزن ffmpeg 853 × 480 في حاوية mkv ، ومن ثم استخدام 16: 9 في كل وقت ، لذا سيعمل mp4 تخزين نسبة العرض إلى الارتفاع المناسبة [SAR 32:27 DAR 16:9] ، بدلاً من [SAR 186:157 DAR 279:157] )

Question

هذا ليس مجال سؤال جديد بشكل خاص هنا ، لكني جربت ما تم اقتراحه هناك دون الكثير من الحظ. لذا ، قصتي:

لقد حصلت على 15 ثانية من الفيديو المباشر من فيديو camera.mov الذي أريد استخلاص مقطع محدد ، والذي يمكنني التعرف عليه من خلال وقت البدء ووقت التوقف ، في ثوانٍ. لقد بدأت بمحاولة تنفيذ ما أسميه "استخراج نسخة": للحصول على الثواني من 9 إلى 12 ،

ffmpeg -i test.mov -vcodec copy -acodec copy -ss 9 -to 12 test-copy.mov

كانت هذه بداية سيئة ، ولكن هناك بعض الإطارات السوداء في بداية ونهاية المقطع ، والتي لا يمكنني الحصول عليها - يجب أن يكون تحريرًا نظيفًا من النص الأصلي. لذلك ، حاولت إعادة ترميز النسخة الأصلية إلى مقطع جديد تم قطعه:

ffmpeg -i test.mov -ss 00:00:09 -t 00:00:03 test-out.mov

هذا أفضل ، ولكن ليس تمامًا: لم تعد هناك إطارات سوداء في بداية المقطع ، ولكنها لا تزال موجودة في النهاية.

بعد بعض المزيد من التصفح والقراءة ، ثم أشك في أن المشكلة هي أن ffmpeg تواجه مشكلة في العثور على النقاط المناسبة بسبب عدم وجود إطارات مفتاحية في الفيديو الأصلي. لذا قمت بإعادة تشفير الفيديو الأصلي إلى (من المفترض) إضافة إطارات مفتاحية ، بطريقتين مختلفتين. نظرًا لأنني أريد أن أتمكن من اختيار الفيديو عند حدود ثانية ("من 9 ثوانٍ إلى 12 ثانية") ، فقد حاولت نسخ العديد من الاقتراحات عبر الويب ،

ffmpeg -i test.mov -force_key_frames "expr:gte(t, n_forced)" test-forced.mp4

و

ffmpeg -i test.mov -g 1 test-g-inserted.mp4

(لقد قمت ببناء هذه البرامج على أساس mp4 استنادًا إلى بعض التعليقات حول حاوية mp4 المطلوبة لدعم البحث في الإطار الرئيسي ، ولكنني بصراحة أخترق هنا.) ثم جربت عملية الاستخراج كما كان من قبل ، ولكن على مقاطع الفيديو الجديدة التي من المفترض أن تحتوي الآن على إطارات مفتاحية (keyframes) فيهم. لا حظ - فكلاهما يبدو متشابهين. البداية على ما يرام ولكن لا تزال هناك إطارات سوداء في النهاية. (FWIW ، كلا test-forced.mp4 و test-g-inserted.mp4 لهما أيضاً إطارات سوداء متتابعة).

إذن: ما زلت عالقاً ، وأرغب في ألا أكون كذلك. هل هناك أي إحصاءات حول ما أفعله خطأ؟ أشعر وكأنني قريب ، لكني في الحقيقة أحتاج للتخلص من تلك الإطارات السوداء ...




أود أن أعرف أيضا. حتى الآن ، قمت بتحويل مقاطع الفيديو الخاصة بي بلا خسارة ، واستخرجت مقطعًا وأعدت تشفيرها بعد التعديل:

ffmpeg -i input -ss 9.48 -t 3.52 -c:v libx264 -crf 0 -g 1 -c:a copy TempIframe.mp4

ولكن هذه العملية تستغرق وقتا طويلا وفقدان ...

لقد جربت ما يلي دون نجاح:

ffmpeg -i source.mp4 -ss 1 -c:v copy -seek2any 1 -avoid_negative_ts 1 -safe 1 -c:a copy segment.mp4





Links