إصلاح ترميز ملفات الترجمة SRT دون فقدان النص الأصلي
شخِّص النصوص المشوهة في ملفات SRT، وميِّز بين أخطاء فك الترميز وفقدان الحروف نهائياً، وأنشئ نسخة منفصلة بترميز UTF-8 باستخدام أداة بايثون آمنة وعينات قابلة للتكرار.

إذا ظهرت نصوص الترجمة في ملف SRT على شكل café بدلاً من café، فلا تسارع بحفظ الملف بترميز UTF-8 على الفور. احتفظ أولاً بنسخة أصلية من بياناته الثنائية (البايتات) دون أي تعديل، وحدد الترميز الذي يُظهر الكلمات بشكل سليم، ثم اكتب النص بعد التحقق منه في ملف منفصل. فحفظ الحروف الخاطئة بترميز جديد سيؤدي فقط إلى تثبيت تلك الأخطاء نهائياً.
يكمن الفارق الجوهري في التمييز بين صلاحية الترميز التقنية وصحة النص الفعلي. ففي التجربة المكونة من مقطعي ترجمة أدناه، يجتاز أحد الملفات المعطوبة فحص UTF-8 الصارم دون أن يحتوي على أي رموز استبدال، ومع ذلك يظل نصه الفرنسي غير صحيح. ويجتاز ملف آخر الفحص نفسه بعد أن استُبدلت ستة حروف أصلية بالرمز �.
يقدم هذا الدليل أداة فحص وتحويل محلية بلغة بايثون، بالإضافة إلى ملفات مصدرية قابلة للتنزيل واختبار قابل لإعادة التطبيق. تركز الأداة على تشخيص الملفات والتحويل الصريح للترميز، ولا تهدف إلى الكشف التلقائي عن الترميز، أو مزامنة الفيديو، أو تقديم وعود باستعادة الحروف المفقودة نهائياً.
تحديد موضع الخلل الفعلي أولاً
إن امتداد الملف .srt يحدد بنية ملف الترجمة، لكنه لا يضمن استخدام ترميز محدد للمحارف. يحتوي ملف SRT على أرقام المقاطع، والرموز الزمنية، والنصوص، والفواصل؛ ويوضح سجل تنسيق SRT بمكتبة الكونغرس أنه نص عادي يفتقر إلى معيار موحد لترميز المحارف.
تعامل مع المشكلة الظاهرة كدافع للبحث والتحقق، وليس كتشخيص نهائي بحد ذاتها:
| ما يظهر أمامك | ما يجب فحصه | الخطوة التالية المناسبة |
|---|---|---|
| ظهور علامات التشكيل أو الرموز بشكل خاطئ في تطبيق واحد | هل تؤدي إعادة فتح الملف الأصلي غير المعدل باستخدام ترميز المصدر المعروف إلى ظهور النص بشكل صحيح؟ | إذا كان الأمر كذلك، فاعتمد فك الترميز الصريح هذا قبل تصدير نسخة جديدة. |
café يستمر في الظهور داخل ملف تمت قراءته بشكل سليم بترميز UTF-8 | هل قُرئ ترميز UTF-8 سابقًا بالخطأ على أنه ترميز آخر ثم حُفظ الملف؟ | عُد إلى البايتات الأصلية، أو تحقق من سجل التحويل بدقة. إعادة الحفظ بترميز UTF-8 لا يُعد إصلاحًا. |
� يظهر مكان حرف أو رمز | هل المحرف U+FFFD محفوظ بالفعل داخل الملف، أم أن التطبيق الحالي يُدرجه أثناء عرض بايتات يتعذر فك ترميزها؟ | افحص الملف المصدري دون أي تعديل؛ فرمز الاستبدال المحفوظ لا يوضح الحرف الأصلي. |
| تظهر مربعات في مشغل الوسائط، بينما يعرض محرر نصوص موثوق المحارف الصحيحة | هل نقاط الترميز الأساسية صحيحة؟ وهل يحمّل المشغل نفس الملف؟ | تحقق من فك الترميز في المشغل، أو دعم الخطوط، أو إعدادات العرض قبل تعديل الملف. |
المحارف وأشكال عرضها أمران مختلفان. يوضح توثيق Python لـ شرح Unicode الفرق بين نقاط الترميز والأشكال الرسومية التي تعرضها الخطوط. وجود نص سليم داخل المحرر يرجح وجود مشكلة في المشغل؛ لكنه لا يثبت أن تثبيت خط معين سيحلها. لم يُختبر أي خط أو مشغل لأغراض هذا المقال.
احتفظ بنسخة احتياطية من البايتات، ثم عاين فك الترميز
نزّل ملف subtitle_encoding.py وضعه بجانب ملف SRT الذي تريد فحصه. تتطلب هذه الأوامر وجود Python 3 مثبتًا مسبقًا دون أي حزم إضافية. أُجريت الفحوصات المحلية هنا باستخدام Python 3.14.3 على نظام macOS. وإذا كان تثبيت Windows لديك يعتمد على مشغّل Python، فاستبدل py -3 بـ python3؛ علمًا بأن تلك البيئة لم تُختبر هنا.
افتح موجه الأوامر في ذلك المجلد. في هذه الأمثلة، استبدل input.srt باسم ملفك الفعلي. واحرص على إبقاء علامات الاقتباس حول المسارات التي تحتوي على مسافات.
إنشاء نسخة غير معدلة
python3 subtitle_encoding.py backup "input.srt" "original-bytes.srt"
يجب ألا يكون مسار الوجهة موجودًا مسبقًا. تنسخ الأداة البايتات دون فك ترميزها، ثم تقرأ النسخة مجددًا وتعرض تجزئة SHA-256 الخاصة بها. كما أنها ترفض استخدام مسار المصدر كوجهة. احتفظ بهذه النسخة الاحتياطية حتى بعد إنشاء ملف ترجمة صالح للاستخدام.
فحص UTF-8 دون حفظ أي تعديلات
python3 subtitle_encoding.py inspect "original-bytes.srt"
يتضمن التقرير strict_utf8, utf8_bom، والترميز المحدد، ومعاينة للنص و replacement_characters . ويستخدم عرض النص الافتراضي الخاص بها utf-8-sig، والذي يتعامل مع علامة UTF-8 البادئة.
strict_utf8: falseتعني أن البايتات فشلت في فحص UTF-8. وهذا لا يخبرك بالترميز الآخر الصحيح.strict_utf8: trueتعني إمكانية فك ترميزها بتنسيق UTF-8. وهذا لا يعني بالضرورة أن الكلمات صحيحة.- يشير عدد الاستبدالات غير الصفري إلى أن فك الترميز المحدد قد أنتج أحرف U+FFFD. تحقق منها جيداً قبل إنشاء ملف جديد.
تطبع عملية الفحص نص JSON متوافقاً مع ASCII حتى لا يخفي خط الطرفية الهوية الحقيقية للحرف: \u00e9 تعني é، و \ufffd تعني حرف الاستبدال. لفحص سطر مريب بالتفصيل، اطلب رقم السطر الفعلي—وليس رقم شارة الترجمة (cue):
python3 subtitle_encoding.py inspect "original-bytes.srt" --encoding cp1252 --line 3
هذا اختبار للقراءة فقط لترميز Windows-1252، وهو برنامج ترميز cp1252 في Python. استخدمه عندما تدعم إعدادات التصدير أو سجل المصدر هذا الاختيار، وليس لمجرد أن هذا المثال تصادف استخدامه للغة الفرنسية. يوضح تقرير السطر اسم كل حرف ونقطة الرمز الخاصة به؛ فمثلاً U+20AC هي علامة اليورو.
اختر الترميز استناداً إلى الأدلة، وليس بناءً على أول معاينة ناجحة
اسأل منشئ الملف عن ترميز التصدير الفعلي، أو تحقق من إعدادات تطبيق التصدير، أو قارن النص بنص أصلي موثوق. راجع الأسماء التي تحتوي على علامات تشكيل، وعلامات الترقيم، ورموز العملات، بالإضافة إلى أسطر نموذجية من مختلف أنحاء الملف. إذا كنت لا تجيد قراءة تلك اللغة، فإن نجاح أداة فك الترميز لن يعوضك عن إجراء تلك المراجعة بنفسك.
مصطلح "ANSI" ليس دقيقاً بما يكفي لتحديد برنامج ترميز المصدر. كما أن Windows-1252 وLatin-1 ليسا قابلين للتبادل. في التجربة المرفقة، يُفك ترميز البايت الفردي 80 إلى € تحت ترميز cp1252، ولكنه يتحول إلى حرف التحكم U+0080 تحت ترميز latin-1. وتنجح كلتا العمليتين. ولا يمكن تحديد النص المقصود إلا بمعرفة المصدر الأصلي.
قد تستخدم اللغات الأخرى ترميزات قديمة مختلفة، ولكن اسم اللغة وحده لا يحدد الترميز بدقة. إذا كان سجل الملف مجهولاً واختلفت القراءات المحتملة، فتوقف قبل التحويل واجمع أدلة أوثق حول المصدر.
لا تقم بالتحويل إلا بعد التأكد من قابلية قراءة النص المصدر
بالنسبة للمصدر الذي تأكد أنه بترميز Windows-1252، أنشئ ملف UTF-8 منفصلاً:
python3 subtitle_encoding.py convert "original-bytes.srt" "repaired-utf8.srt" --from-encoding cp1252
python3 subtitle_encoding.py inspect "repaired-utf8.srt"
تقوم أداة التحويل بفك ترميز المصدر بالكامل بصرامة، ثم ترميز ذلك النص بتنسيق UTF-8، والتحقق من أن فك ترميز المخرجات يعيد النص نفسه تماماً، ثم إعادة قراءة البايتات المكتوبة. وهي لا تعدل أرقام المقاطع، أو الطوابع الزمنية، أو الحوار، أو الوسوم، أو نهايات الأسطر. وقد يختلف تسلسل البايتات الجديد على الرغم من بقاء النص المفكوك متطابقاً.
وترفض الأداة عمداً ما يلي:
- الكتابة فوق ملف وجهة موجود مسبقاً؛
- المتابعة عند حدوث خطأ أثناء فك الترميز الصارم؛ أو
- كتابة نص يحتوي على U+FFFD، حتى لو كان ذلك المحرف مقصوداً.
يُعد القيد الأخير تدبيراً احترازياً: فهذه الأداة لا يمكنها تخمين ما كان يفترض أن يمثله محرف الاستبدال. وحذفه لمجرد إنجاح الأمر من شأنه إتلاف الأدلة لا استعادة النص الأصلي. ويوضح توثيق معالجات الأخطاء في Python سبب اختلاف replace و ignore عن فك الترميز الصارم: فهما يستبدلان البيانات المعيبة أو يتجاهلانها، ولا مكان لأي منهما في خطوة التحويل هذه.
إذا حدث خطأ في الإدخال/الإخراج، فلا تستخدم المخرجات المعطوبة. فقد يتبقى ملف جديد غير مكتمل؛ احتفظ بالملف الأصلي واستخدم اسماً جديداً للملف الوجهة عند المحاولة لاحقاً. يمكن الاطلاع على تفاصيل سلوك الأداة واستخدامها بالكامل في ملف README القابل للتنزيل.
ماذا عن UTF-8 المزود بعلامة BOM؟
علامة UTF-8 BOM هي تسلسل بايتات بادئ يبلغ EF BB BF. ويقوم utf-8-sig مرمز في Python بتجاوز هذا التوقيع عند فك الترميز وإضافته عند الترميز.
بالنسبة لمصدر UTF-8 مؤكد يحتوي على علامة BOM، استخدم --from-encoding utf-8-sig. تكتب الأداة عادةً ترميز UTF-8 بدون علامة BOM؛ لا تضف --with-bom إلا إذا كانت متطلبات التطبيق المستلم تفرض ذلك. تغيير علامة BOM لا يمكنه تحويل café إلى café. لا تثبت هذه التجربة التوافق مع أي مشغل أو محرر أو منصة رفع بعينها.
خمسة ملفات صغيرة توضح لماذا لا تكفي صلاحية ترميز UTF-8 وحدها
تستخدم التجربة مقطعي ترجمة فرنسيين مؤلفين بالكامل ذاتياً. وهما ليسا مأخوذين من فيلم أو عميل أو منتج ترجمة:
1
00:00:01,000 --> 00:00:04,000
Émile dit : « Le prix est de 12,50 €. »
2
00:00:05,000 --> 00:00:08,000
Le café est fermé.
في 13 سبتمبر 2026، قام سكريبت يعتمد على المكتبة القياسية لـ Python 3.14.3 بإنشاء خمسة تمثيلات للبايتات ومقارنة كل منها بالمصدر المعروف. هذه عمليات فحص حتمية للبايتات والنصوص، وليست معياراً لقياس جودة الترجمة. احفظ الملفات المرتبطة على القرص بدلاً من نسخ معايناتها من المتصفح: فالبايتات المختلفة هي جوهر هذه التجربة.
| نسخة قابلة للتنزيل | البايتات | ترميز UTF-8 صارم؟ | نص صحيح عند فك تشفيره بترميز UTF-8؟ | حفظ U+FFFD في نص UTF-8 الخاص به |
|---|---|---|---|---|
| UTF-8 أصلي | 132 | نعم | نعم | 0 |
| Windows-1252 أصلي | 125 | لا | لا يمكن فك تشفيره كـ UTF-8؛ صحيح تحت ترميز cp1252 | لا ينطبق |
| أداة فك ترميز خاطئة، أُعيد حفظه كـ UTF-8 | 147 | نعم | لا | 0 |
| محارف بديلة، أُعيد حفظه كـ UTF-8 | 137 | نعم | لا | 6 |
| UTF-8 محوّل بشكل صحيح | 132 | نعم | نعم | 0 |
تحتفظ كل نسخة بنفس سلسلتي الطوابع الزمنية. الملف المحوّل بشكل صحيح متطابق بايت ببايت مع ملف UTF-8 الأصلي. ويثبت ملفا UTF-8 التالفان حقيقة أدق لكنها مفيدة: لا الترميز الصحيح ولا الطوابع الزمنية غير المتغيرة يضمنان صحة نص الترجمة. كما أن تطابق الطوابع الزمنية لا يوضح إطلاقاً ما إذا كان هذا المسار المصطنع يتطابق مع فيديو حقيقي.
لإعادة إنتاج الملفات الخمسة بنفسك، نزّل ملف reproduce.py وشغّله مع تحديد اسم دليل غير موجود مسبقاً:
python3 reproduce.py encoding-experiment
يكتب السكربت ملفات الاختبار وملف results.json يحتوي على النص الكامل، والتحويلات، وقيم التجزئة (hashes)، وإصدار بيئة التشغيل، والتأكيدات البرمجية. قارنه مع نتائج التجربة المسجلة؛ حيث سيختلف طابع وقت الإنشاء فقط. تتضمن السكربتات والملفات التعليمية الأصلية ترخيص MIT.
اختبرت عمليات فحص المحوّل المحلي أيضاً رفض الكتابة فوق المخرجات الموجودة، ورفض مسار المصدر، وفشل برنامج الترميز غير الصحيح، ورفض محرف U+FFFD، والحفاظ على نهايات الأسطر CRLF، والإخراج الصريح لعلامة BOM. تتحقق هذه الفحوصات من سلوك معالجة الملفات في هذه الأداة، ولا تختبر تصيير المشغّلات، أو التوقيت مع وسائط حقيقية، أو الترجمة عبر BookTranslator.
إذا تم حفظ الأحرف التالفة بالفعل
رموز المودجيباكي (mojibake) المحفوظة: تقصّي المسار الدقيق للخطأ
اتبعت نسختنا المصابة بالمودجيباكي تسلسلاً معروفاً: تم فك ترميز بايتات UTF-8 الأصلية بصيغة Windows-1252، ثم حُفظت تلك الأحرف الخاطئة بصيغة UTF-8. وتتضمن النتيجة café وتسلسل رمز اليورو التالف €.
نظراً لأن هذا التحويل المحدد لم يفقد أي بايتات، يمكن لسكربت إعادة الإنتاج عكس هذه العملية: إعادة ترميز النص الخاطئ باستخدام cp1252، ثم فك ترميز البايتات الناتجة بصيغة UTF-8. وهو يتحقق من صحة النص المسترد بمطابقته مع الأصل.
يعد هذا دليلاً عملياً يخص هذا التسلسل المعروف بعينه، وليس توجيهاً لتطبيق عملية "إصلاح مودجيباكي" شاملة على كل ملف SRT. فقد يحتوي الملف على أحرف صحيحة، أو سجل تعديلات مختلط، أو نص تم تغييره بالفعل عبر محاولة إصلاح سابقة. يفضل دائماً استخدام المصدر الأصلي غير المعدل ومسار التحويل القياسي. وإن لم يتبقَ لديك سوى نسخة المودجيباكي المحفوظة، فاحتفظ بها وحدد طريقة تشكلها أولاً قبل محاولة تطبيق تحويل عكسي على نسخة أخرى.
محارف الاستبدال المحفوظة: الحرف المفقود لم يعد مُرمَّزاً هناك
أُنشئ نموذج الفقد هذا عن طريق فك ترميز بايتات Windows-1252 بتنسيق UTF-8 مع تفعيل الاستبدال، ثم حفظ النتيجة. تحولت محارف أصلية مختلفة إلى نفس علامة � . لا تحمل العلامة المحفوظة معلومات كافية لتحديد المحرف الأصلي الذي كان يشغل هذا الموضع.
لا تخلط بين هذا وبين مجرد رؤيته � داخل أحد التطبيقات. فإذا ظلت البايتات الأصلية كما هي دون تعديل، فقد يظل فك الترميز الصحيح قادراً على استعادة النص—كما حدث مع ملف المصدر بتنسيق Windows-1252. افحص ذلك المصدر قبل الجزم بفقدان البيانات نهائياً.
إذا كانت النسخة الوحيدة المتبقية قد استبدلت بالفعل النص المفقود برمز U+FFFD أو بعلامات استفهام صريحة، فأعد تصدير الملف أو احصل على نسخة مصدرية سليمة من جديد، أو تحقق من التفريغ اليدوي بمقارنته بمواد موثوقة. قد تكون علامة الاستفهام العادية أيضاً علامة ترقيم صحيحة؛ لذا فإن مجرد وجودها لا يثبت شيئاً بمفرده. كما أن أي استبدال يبدو منطقياً يقدّمه نموذج ذكاء اصطناعي ليس سوى تخمين، وليس استعادة لبيانات الملف الأصلية.
الهدف هو الحصول على مصدر قابل للقراءة—وليس مجرد نجاح تنفيذ الأمر
قبل اعتماد الملف المُصلَح، قارن عينة من الكلمات والرموز بالمصدر الموثوق، وتأكد من أن أسطر التوقيت وفواصل المشاهد لم تتغير، وافتح الملف الجديد في التطبيق الذي ستستخدمه لتشغيله. يحافظ السكربت على النص بعد فك ترميزه، لكنه ليس أداة للتحقق من صحة بنية SRT النحوية أو اختباراً لاعتماد جاهزية التشغيل.
إذا أصبحت قادراً الآن على قراءة ملف الترجمة ولا تحتاج إلى لغة أخرى، فقد انتهت مهمتك بنجاح. أما إذا كنت بحاجة إلى مراجعة الترجمة عملياً مع الفيديو أو إجراء المزيد من التعديلات، فإن مقارنة برامج الترجمة توضح الأدوار المختلفة لكل أداة.
وفقط عندما يصبح النص المصدري موثوقاً به—وتكون بحاجة فعلية إلى لغة أخرى—يمكنك الانتقال إلى أداة ترجمة ملفات الترجمة من BookTranslator واستخدام سير عمل ترجمة الترجمات المرئية بالذكاء الاصطناعي. تعامل مع إصلاح الترميز، والترجمة، ومشاهدة المسار النهائي كمهام منفصلة تماماً؛ فنجاح أي منها ليس دليلاً على نجاح المهام الأخرى.
مقالات ذات صلة





