العودة إلى المدونة
13 أغسطس 2026Sergei Solod12 دقائق قراءة

كيف خفّضت فيديو إنتاجيًا من نحو 280 MB إلى نحو 50 MB باستخدام H.264

انخفض فيديو حقيقي من نظام الإنتاج من نحو 280 MB إلى نحو 50 MB بعد أن أعدت بناء إعداد H.264 حول CRF 28 وx264 veryslow وسقف دقة من فئة 720p ومعدلات إطارات مفيدة ومتطلبات معتدلة لفك الترميز. وفي مرحلة أقدم كان المثال نفسه قد انخفض بالفعل من نحو 350 إلى 238 MB، كما أظهر تدقيق المكتبة القديمة أن ملفات H.264 بمعدلات عدة ميغابت في الثانية كانت شائعة.

H.264FFmpegx264ضغط الفيديوأداء الويبتحسين الوسائط

الرقم الذي جعل هذا التحسين ملموسًا أخيرًا كان بسيطًا: أحد فيديوهات الإنتاج التي تابعتها انخفض من نحو 280 MB إلى 50 MB بعد تطبيق سياسة H.264 الجديدة. أي أنه أصبح أصغر بنحو 5.6 مرات، مع توفير يقارب 230 MB أو نحو 82% من الحجم الأصلي.

لم أصل إلى هذه النتيجة عبر الانتقال إلى AV1 أو HEVC أو VP9. بقي الخرج في الإنتاج H.264 داخل MP4. ما تغيّر هو كل ما يحيط ببرنامج الترميز: عدد أقل من البكسلات غير الضرورية، وعدد أقل من العينات الزمنية غير المفيدة، وهدف جودة أقل تحفظًا بكثير، وإنفاق أكبر للمعالجة أثناء الترميز، مع إبقاء متطلبات فك الترميز محدودة عمدًا.

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

كانت السياسة القديمة والجديدة تقريبًا كالتالي:

الإعداد السابق
H.264 Main @ Level 4.0
CRF 19
الإعداد المسبق slow
حتى 1920x1080 / 1080x1920
30 fps
refs = 3
إطارات B = 3
GOP ≈ ثانيتان
VBV ≈ 10M / 20M

الإعداد الجديد
H.264 Main @ Level 3.1
CRF 28
الإعداد المسبق veryslow
سقف من فئة 720p، بلا تكبير
CFR مفيد، عادة <= 30 fps
refs = 4
إطارات B = 5
GOP ≈ 5 ثوان
VBV ≈ 4M / 8M
yuv420p / avc1 / faststart

النتيجة المقاسة: من نحو 280 MB إلى نحو 50 MB

لدي عدة قياسات حقيقية من الإنتاج، لكنها ليست جميعًا التجربة نفسها. الفصل بينها أهم من البحث عن أكبر نسبة مئوية تبدو مثيرة.

القياسقبلبعدالانخفاض
الفيديو نفسه قبل وبعد~280 MB~50 MBأصغر ~5.6× / أقل ~82%
مرحلة أقدم للملف نفسه~350 MB~238 MBأصغر ~1.47× / أقل 32%

الصف الأول هو أقوى دليل مباشر على عنوان المقالة. إنه فيديو واحد بعينه قبل السياسة الجديدة وبعدها: نحو 280 MB أصبح نحو 50 MB. لم أستعد من السجلات القديمة سطر معدل البت/المدة الخاص بهذه الثنائية تحديدًا، لذلك لن أخترعه. تغير الحجم وحده كافٍ: هذا الملف بعينه أصبح أصغر بنحو 5.6 مرات.

حالة ~350→238 MB كانت مرحلة تحسين أقدم للملف نفسه في ذلك الوقت من خط المعالجة. الناتج كان تقريبًا 1264×720 عند 30 fps، ومدته نحو 500 ثانية، من دون صوت، وبمتوسط يقارب 3.8 Mbps. الحساب يتطابق مع الحجم المرصود: 3.8 Mbps لمدة تقارب 500 ثانية تعطي نحو 238 MB. كان ذلك توفيرًا قدره 32% من ~350 MB، لكنه ظل أكبر بكثير مما أريده من ناحية النطاق الترددي.

كما أظهر تدقيق المكتبة القديمة أن ملفات H.264 الكبيرة لم تكن حالة شاذة واحدة. في أحد التدقيقات كان لدي 238 فيديو إنتاجيًا بحجم إجمالي 6.37 GB: منها 117 H.264 و121 AV1. كان 101 ملفًا بحجم 20 MB أو أكثر، و34 ملفًا بحجم 50 MB أو أكثر. بعض أكبر ملفات H.264 كانت كالتالي:

الحجمالمدةمتوسط معدل البت
121.0 MB4:253.83 Mbps
101.2 MB5:192.659 Mbps
92.78 MB4:442.735 Mbps
90.10 MB3:553.206 Mbps
89.74 MB4:412.676 Mbps

هذه ملفات لمحتوى مختلف، لذلك يقدم الجدول سياقًا ولا يمثل اختبار مقارنة مباشرًا. لكنه يوضح أن المثال القديم عند 3.8 Mbps لم يكن حالة شاذة منفردة؛ فقد ظهرت فعليًا قيم تقارب 2.6–3.8 Mbps في عدة ملفات H.264 كبيرة من المكتبة القديمة.

أهم تحسين لم يكن خيارًا واحدًا في FFmpeg

أكبر تغيير كان في طريقة حسابي للتكلفة.

الترميز يحدث مرة واحدة. أما نقل الملف فيحدث كل مرة يطلبه فيها أحد.

في الفيديو الفوري قد يكون إنفاق قدر أكبر بكثير من قدرة المعالج لتوفير قليل من معدل البت صفقة سيئة. ملفاتي تُرمّز مسبقًا ثم تُرسل مرارًا. في هذا النموذج قد يكون توفير عشر دقائق أثناء الترميز بلا قيمة اقتصادية تقريبًا إذا جعل الترميز الأسرع كل طلب لاحق أكبر حجمًا.

لهذا يناسبني -preset veryslow. أنا مستعد لدفع تكلفة المعالجة مرة واحدة إذا كان x264 سيستفيد منها للعثور على تمثيل أكثر كفاءة. المتصفح لا يعيد عمل المرمّز؛ بل يفك فقط تدفق البتات النهائي.

أصبحت القاعدة بسيطة: أنفق قدرة المعالجة على الخطوة التي تحدث مرة واحدة، ووفّر البايتات في الخطوة التي تتكرر.

لماذا بقيت مع H.264 بدل مطاردة أحدث برامج الترميز

لا أدّعي أن H.264 هو أكثر برامج الترميز كفاءة في الضغط. ليس كذلك. قد تكون البرامج الأحدث جذابة جدًا عندما يستطيع نظام التوزيع الاحتفاظ بعدة نسخ واختيار الأنسب لكل عميل.

قيدي كان مختلفًا: عنوان URL واحد، وملف واحد، وبرنامج ترميز واحد، وأقل قدر عملي من مشكلات التشغيل لدى جمهور يعتمد بكثافة على الهواتف.

لهذا الغرض يظل H.264 داخل MP4 خيارًا أساسيًا آمنًا جدًا. توصي Apple حاليًا مطوري الويب باستخدام ملفات MP4 المرمّزة بـ H.264 للفيديو الثابت في Safari. وتذكر وثائق Android الحالية H.264 داخل MP4 وتفرض وجود مفكك ترميز يدعم النمط Main في Android 6.0 والإصدارات الأحدث؛ كما تدرج توصيات تشغيل H.264 دقة 1280×720 عند 30 fps للفيديو عالي الدقة، مع التنبيه إلى أن HD غير متاح على كل الأجهزة. راجع تنسيقات الوسائط المدعومة في Android.

هذا لا يعني أن الأجهزة الحديثة محدودة بالنمط Main أو المستوى 3.1. إرشادات Apple الخاصة بـ HLS، مثلًا، تفضّل عمومًا النمط High على Main أو Baseline. اخترت Main@3.1 لأنني أردت متطلبات فك ترميز متواضعة عمدًا لملف MP4 ثابت واحد، لا لأن Apple تفرضه.

توقفت عن ترميز بكسلات لا حاجة إليها

كانت الدقة واحدة من أكبر وسائل خفض الحجم. أصبح الحد الأقصى لدي نحو 1280×720 للوضع الأفقي، و720×1280 للعمودي، ونحو 960×960 للمحتوى المربع أو المختلط الاتجاه.

لكن القاعدة الأهم هي: لا تكبّر الصورة لمجرد الوصول إلى الحد الأقصى.

إذا كان المصدر 900×600، فإن تحويله إلى 1280×720 لا يعيد أي تفاصيل. هو فقط ينشئ عينات إضافية يجب على المرمّز وصفها. يمكن خفض مصدر 1920×1080 إلى فئة 720p، بينما يمكن أن يبقى مصدر 900×600 قريبًا من حجمه الأصلي. الحد الأقصى سقف، وليس هدفًا يجب بلوغه.

هذا بسيط، لكن التخلص من البكسلات غير الضرورية قد يكون أهم من كثير من التعديلات الدقيقة في إعدادات المرمّز.

لم أختر هذا السقف لأنه رقم دائري جميل. فالإطار 1920×1080 يحتوي 2,073,600 بكسل، بينما يحتوي 1280×720 على 921,600 بكسل. أي إن الانتقال من 1080p إلى 720p يزيل نحو 55.6% من العينات المكانية قبل أن يبدأ برنامج الترميز أصلًا باتخاذ قرارات الضغط.

فكرت أيضًا في جعل 540p الخيار العام. لكن 960×540 لا يحتوي إلا 518,400 بكسل، أي أقل بنسبة 43.75% من 1280×720، فلا يبقى سوى 56.25% من عينات 720p. وفي الرسوم المصورة تمثل هذه العينات الخطوط الدقيقة والعينين والشعر والأصابع والوجوه والحواف الحادة. إذا احتجت إلى بايتات أقل، أفضل تجربة CRF أعلى قليلًا قبل حذف 43.75% أخرى من المعلومات المكانية بلا قياس. يمكن تعديل التكميم في ترميز لاحق، أما التفاصيل التي أزيلت بتخفيض الدقة فقد اختفت بالفعل.

لهذا أجعل فئة 720p سقفي العام المتحفظ، ولا أقول إن 540p سيئ. قد تكون نسخة 540p المقاسة هي الأفضل لملف بعينه. لكنني لا أحول هذا الفقد المكاني غير القابل للعكس إلى قاعدة عامة من دون بيانات.

توقفت عن الدفع مقابل إطارات لا يملكها المصدر فعليًا

معدل الإطارات عامل مضاعف آخر. إذا كانت الرسوم المتحركة تحتوي فعليًا على نحو 16 حالة بصرية مفيدة في الثانية، فإن تخزينها عند 30 أو 60 fps لا يجعل الحركة أفضل تلقائيًا. غالبًا ما يضيف فقط عينات زمنية مكررة أو مصطنعة، ومع ذلك يجب تمثيلها في الملف.

سياستي هي الحفاظ على الإيقاع المفيد للمصدر والبقاء عادةً عند 30 fps أو أقل. في هذا النوع من المحتوى قد تكون 12 أو 15 أو 16 أو 18 أو 20 أو 24 أو 25 أو 30 fps كلها خيارات معقولة إذا كانت تصف المصدر فعلًا.

وأفضّل أيضًا معدل إطارات ثابتًا ونظيفًا في الناتج. VFR ليس معيبًا بحد ذاته؛ لكن CFR يجعل الطوابع الزمنية، وعدد الإطارات، وفحوص المدة، والتنقل داخل الفيديو، والتحقق اللاحق أبسط في خط المعالجة لدي.

المبدأ أهم من أي رقم FPS بعينه: لا تدفع نطاقًا تردديًا مقابل معلومات زمنية غير موجودة في المصدر.

CRF 28 اختيار لهذه الحالة، وليس رقمًا سحريًا

لم أرد دفع كل مقطع نحو معدل بت مستهدف واحد. الرسم شبه الثابت والمشهد المليء بالحركة لا يحتاجان العدد نفسه من البتات كي يبدوا مقبولين.

لذلك أستخدم وضع CRF في x264، ولهذا المحتوى المرسوم الذي يعطي الأولوية للنطاق الترددي استقررت حول -crf 28. توثق FFmpeg قيمة CRF في libx264 باعتبارها تحكمًا في المعدل بوضع الجودة الثابتة؛ راجع وثائق برامج الترميز في FFmpeg.

CRF 28 قيمة هجومية عمدًا. لن أنقلها كما هي إلى مادة مليئة بحبيبات الفيلم، أو فيديو كاميرا كثير الضجيج، أو نص صغير جدًا على الشاشة، أو حالة تكون فيها دقة الصورة أهم من النطاق الترددي.

ولا أملك مقياسًا إدراكيًا عامًا يثبت أن CRF 28 غير ملحوظ بصريًا. ما أستطيع قوله عن حالتي أضيق: الملفات أصبحت أصغر بكثير وظلت تبدو طبيعية بالنسبة إليّ أثناء التشغيل العادي. هذه ملاحظة عملية، وليست ادعاءً بأن CRF 28 عديم الفقد بصريًا.

veryslow مكلف للمرمّز، وليس بالضرورة لمفكك الترميز

الإعداد المسبق لدي هو -preset veryslow. الإعداد الأبطأ يمنح x264 وقتًا أكبر للبحث عن قرارات تنبؤ وترميز أكثر كفاءة. الثمن هو وقت المعالج أثناء الترميز.

الفرق المهم هو أن جهد المرمّز وتعقيد فك الترميز ليسا الشيء نفسه.

يمكنني أن أسمح لـ x264 بالبحث طويلًا، ثم أضع قيودًا مستقلة على التدفق النهائي. مواصفات الخرج المحافظة لدي هي:

H.264، ملف Main
Level 3.1
yuv420p بعمق 8 بت
avc1
refs = 4
إطارات B = 5
B-pyramid = normal
GOP مفتوح = معطل

تتيح FFmpeg ضبط CRF والإعدادات المسبقة والتوليف وقيود النمط والإطارات المرجعية وإطارات B بشكل منفصل. هكذا أفكر فيها أيضًا: دع المرمّز يبحث بعمق، لكن أبقِ جانب التشغيل عاديًا ومتوقعًا.

GOP وVBV حواجز أمان، وليسا أداة التحكم الرئيسية في الجودة

لهذه المقاطع القصيرة التي تُشغَّل تدريجيًا أستخدم GOP أقصى يقارب خمس ثوانٍ: نحو -g 150 عند 30 fps، و-g 120 عند 24 fps، و-g 80 عند 16 fps.

هذا اختيار مناسب لحالتي، وليس قاعدة عامة. للبث التكيفي قيود مختلفة؛ فإرشادات Apple لتأليف HLS، مثلًا، توصي بوجود IDR كل ثانيتين. لا أنقل هذه القاعدة حرفيًا إلى ملفات MP4 ثابتة وقصيرة تُشغَّل تدريجيًا.

وأستخدم تقريبًا:

-maxrate:v 4M
-bufsize:v 8M

هذه القيم سقف للقفزات غير المعتادة في معدل البت. وهي لا تعني «رمّز كل شيء عند 4 Mbps». يظل CRF مسؤولًا عن التوزيع المعتاد للبتات، لذلك يمكن للمقاطع السهلة أن تصبح صغيرة جدًا.

جعلت حاوية MP4 تقليدية قدر الإمكان أيضًا

أستخدم avc1 صراحةً. توصي وثائق Apple الحالية لـ HLS بصيغ عينات مثل avc1 بدل avc3. هذا ليس سبب صغر ملفاتي، لكنه ينسجم مع هدفي في إنتاج H.264 داخل MP4 بصورة تقليدية.

وأستخدم -movflags +faststart. تقول وثائق الحاويات في FFmpeg إن faststart ينقل فهرس moov إلى بداية ملف MP4. كما تشترط متطلبات Android للبث عبر HTTP أن يأتي moov بعد ftyp وقبل mdat في MPEG-4.

ftyp
moov
mdat

لا يحسن faststart الضغط. هو فقط يجعل التشغيل التدريجي عبر HTTP أكثر سلاسة.

لخرج SDR عادي أستخدم 8 بت yuv420p وأحدد BT.709 بنطاق محدود/فيديو. إذا كان المقطع بلا صوت فلا أضيف مسارًا صوتيًا من لا شيء. ولهذا المحتوى المرسوم أستخدم أيضًا -tune animation؛ وأتعامل معه كاختيار خاص بنوع المحتوى، لا كجزء من متطلبات التوافق العامة.

إعداد FFmpeg الأساسي

لمصدر مرسوم بسرعة 30 fps، يبدو الجزء المركزي من الأمر تقريبًا هكذا:

ffmpeg -i input \
  -c:v libx264 \
  -preset veryslow \
  -tune animation \
  -crf 28 \
  -profile:v main \
  -level:v 3.1 \
  -pix_fmt yuv420p \
  -tag:v avc1 \
  -refs 4 \
  -bf 5 \
  -g 150 \
  -maxrate:v 4M \
  -bufsize:v 8M \
  -x264-params "open-gop=0:b-pyramid=normal:nal-hrd=none" \
  -color_range tv \
  -color_primaries bt709 \
  -color_trc bt709 \
  -colorspace bt709 \
  -an \
  -movflags +faststart \
  output.mp4

تعمدت ألا أثبت مرحلتي التحجيم ومعدل الإطارات في المثال. لا ينبغي تكبير مصدر 900×600 لمجرد أن الحد الأقصى 1280×720، ولا ينبغي إجبار رسوم متحركة ذات معدل إطارات منخفض طبيعيًا على 30 fps لمجرد أن المثال يستخدم -g 150.

الأمر يطبق السياسة؛ لكنه ليس السياسة نفسها.

لماذا أصبحت الملفات أصغر بعدة مرات

لم تكن هناك تعليمة سحرية واحدة.

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

لهذا فإن قول «هذا الملف H.264» يخبرك بالقليل جدًا عن حجمه. قد يختلف ترميزان H.264 للمصدر نفسه اختلافًا كبيرًا لأن اسم برنامج الترميز لا يصف الدقة، أو معدل الإطارات، أو التحكم في المعدل، أو الإعداد المسبق، أو بنية GOP، أو النمط، أو تجهيز المصدر.

في حالتي كان تغيير هذه القرارات المحيطة أهم من تغيير برنامج الترميز نفسه.

ما الذي لا تثبته النتيجة

لم أعزل كل إعداد في تجربة مضبوطة، لذلك لا أستطيع بصدق إسناد نسبة دقيقة من التوفير إلى veryslow أو CRF 28 أو خفض الدقة أو خفض معدل الإطارات كل على حدة.

كما لا أستطيع الادعاء بأن كل ناتج عند CRF 28 غير ملحوظ إدراكيًا. «لا يوجد تراجع واضح في الجودة» هو ما لاحظته لهذا النوع من المحتوى المرسوم عند أحجام المشاهدة المعتادة، وليس ضمانًا علميًا لأي فيديو.

ولا أقول إن ملف H.264 واحد هو البنية الصحيحة لكل موقع. تعدد النسخ، والبث التكيفي، وHDR، و4K، والتفاوض على برنامج الترميز تغير المفاضلات.

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

كيف غيّرت هذه النتيجة أسلوبي في التحسين

كنت أفكر في تحسين الفيديو أساسًا كمشكلة إعدادات ترميز. الآن أفكر فيه كمشكلة تكلفة على عمر الملف.

قد يعمل المرمّز مرة واحدة. أما البايتات فقد تعبر الشبكة آلافًا أو ملايين المرات.

وهذا يغير معنى كلمة «مكلف».

لا أمانع إنفاق قدرة معالجة إضافية مرة واحدة. ما أرفضه أكثر هو إرسال بكسلات ناتجة عن التكبير، أو إطارات لا تضيف حركة مفيدة، أو معدل بت لا يحتاجه المحتوى، في كل طلب لاحق.

بقي برنامج الترميز تقليديًا: H.264 داخل MP4. التحسين حدث حوله.

لهذه الحالة، الدرس أوضح من أي خيار منفرد في FFmpeg: حسّن التكلفة التي تدفعها مرارًا، لا التكلفة التي تدفعها مرة واحدة.