خمس ثوانٍ من الصمت
سجّلت قارئة من تشيلي حسابًا، ورفعت ملف PDF من 74 صفحة لرواية أطفال — "¿Quién le tiene miedo a Demetrio Latov?" للكاتبة Angeles Durini — ثم ضغطت على توليد كتاب صوتي. وبعد خمس عشرة ثانية، وصلها بريد إلكتروني: "كتابك الصوتي جاهز."
لم يكن جاهزًا. كانت مدّة الملف 5.6 ثوانٍ، ولم يحتوِ على شيء.
هذا النوع من الأخطاء لا تكتشفه إلا في بيئة الإنتاج، لأن ملفات PDF التي اختبرنا عليها كانت تحوي نصًا مدمجًا، بينما ملفها لم يكن كذلك. كان الكتاب قد مُسح ضوئيًا، صفحة تلو الأخرى، عام 2012 ببرنامج Adobe Acrobat Pro — وكل صفحة محفوظة كصورة. بالنسبة لخط معالجتنا، كان ملف PDF عبارة عن 74 صفحة فارغة.
لماذا تكسر ملفات PDF الممسوحة ضوئيًا خطوط إنتاج الكتب الصوتية
يمكن لملف PDF أن يحمل النص بطريقتين مختلفتين تمامًا:
- ملفات PDF نصّية — حيث تُخزَّن الكلمات كأحرف فعلية مع خط وموقع. أي مكتبة (pypdf أو pdfminer أو pypdfium2) قادرة على استخراجها في أجزاء من الثانية.
- ملفات PDF صورية (المسوحات) — حيث تكون الصفحات صورًا بصيغة JPEG أو TIFF مضمّنة داخل غلاف PDF. ومن منظور مكتبة استخراج النصوص، تحتوي هذه الصفحات على صفر من الأحرف.
كل ما يأتي من ماسح ضوئي مسطّح أو كاميرا هاتف أو مشروع رقمنة قديم (مثل Google Books و archive.org وإعادة طباعات الأعمال في الملكية العامة وكتب الأطفال المستعملة) يميل لأن يكون من النوع الثاني. تبدو متطابقة تمامًا لعين الإنسان، لكنها مختلفة جذريًا بالنسبة للبرمجيات.
عند فحص الملف الذي فشل رفعه، أعاد محلّل PDF لدينا حرفيًا 17 بايتًا من القمامة — وحدات بايت تحكّم لا حروفًا — لكامل الكتاب البالغ 74 صفحة. ثم أطعم خط الإنتاج تلك الـ17 بايتًا لمحرّك تحويل النص إلى كلام بإخلاص شديد، فأنتج 5 ثوانٍ من المتمتمات. ثم أرسل بريدًا إلى القارئة يخبرها بأن كتابها الصوتي جاهز.
ما الذي بنيناه
الحلّ بسيط من حيث المفهوم: اكتشاف غياب نصّ صالح للاستخدام في ملف PDF، ثم تطبيق OCR على كل صفحة. أما التنفيذ ففيه بضع نقاط تستحق الشرح.
1. كاشف نصّ متناثر
قبل أن نندفع نحو تشغيل OCR على كل عملية رفع، نتفحّص نتيجة الاستخراج الأصلي. إذا أعاد ملف PDF بأكمله أقل من 200 حرف، أو إذا كان المتوسط أقل من 30 حرفًا لكل صفحة عبر 4 صفحات أو أكثر، نعتبره مسحًا ضوئيًا وننتقل إلى مسار OCR. أما ملفات PDF النصّية العادية — وهي تمثّل أكثر من 90% من الحالات — فلا تشغّل المسار البطيء أبدًا.
2. pypdfium2 و tesseract (Apache 2.0 من البداية إلى النهاية)
نُصيّر كل صفحة باستخدام pypdfium2 (وهو غلاف Python لمحرّك PDFium من Google، بترخيص Apache 2.0) بمعامل تكبير 2.5× — أي ما يعادل تقريبًا 180 DPI، وهي دقّة كافية للتعرّف الموثوق على الأحرف. ثم تمرّ كل صورة عبر tesseract مع تحميل نموذج متعدّد اللغات: eng+spa+por+fra+deu+pol+ita+tur. ويتولّى tesseract استنتاج اللغة الفعلية من أشكال الرموز.
تخلّينا عمدًا عن PyMuPDF — أشهر مكتبة PDF في Python — لأن ترخيصها AGPL مزعج لخدمة مستضافة. الانتقال إلى pypdfium2 استغرق أمسية واحدة وأزال الحافة القانونية كلّيًا. معلومة مفيدة إذا كنت تبني أي منتج تجاري متعلّق بـ PDF.
3. الكشف التلقائي عن اللغة
كان كتاب القارئة بالإسبانية، لكن لغة واجهتها كانت الإنجليزية — لذا قبل إصلاحنا، حتى لو نجح OCR، لكان خطّ الإنتاج قد ركّب نصًا إسبانيًا بصوت إنجليزي (آلي ومنطوق بشكل خاطئ). أمّا الآن، فإن كشف اللغة نفسه يستخدم النص الناتج من OCR. بعد 3 صفحات عينيّة، يصنّف langdetect المحتوى ويختار الصوت المناسب — وفي هذه الحالة: الإسبانية لأمريكا اللاتينية.
4. مسار فشل صريح
إذا استرجع OCR رغم كل ذلك أقل من 100 حرف (ملفات PDF زخرفية فقط، أو ملفات تالفة)، فإننا الآن نُطلق خطأ واضحًا بدلًا من توليد الصمت: "هذا الملف من نوع PDF لا يحتوي على نصّ قابل للاستخراج. الرجاء رفع ملف EPUB أو TXT أو ملف PDF نصّي." يُعلَّم عمل الكتاب الصوتي على أنه فاشل، ولا يُرسَل أي بريد، ولا تُخصم أي اعتمادات.
هل لديك ملف PDF ممسوح ضوئيًا؟ جرّبه الآن.
MimicReader مجاني للساعة الأولى من الصوت كل شهر. بلا بطاقة. أسقط أي ملف PDF — نصيًا كان أم ممسوحًا — وسنتولّى نحن الباقي.
ابدأ مجانًاالنتيجة
أعدنا تشغيل ملف PDF الخاص بالقارئة عبر خط الإنتاج المُحدَّث. خمس دقائق من OCR استخرجت 144,710 حرفًا من نصّ إسباني نظيف من صفحاتها الـ74 الممسوحة. ثم قطّعها خط الإنتاج إلى 1,127 مقطعًا وأنتج كتابًا صوتيًا مدّته ساعتان و43 دقيقة مع مزامنة قراءة جنبًا إلى جنب — تظليل كلمة كلمة مرتبط بالصوت. أرسلنا لها بريدًا بالإسبانية، على حسابنا، واعتذرنا عن المحاولة الأولى.
استغرقت إعادة التوليد بأكملها نحو 90 دقيقة على ساعة الحائط: حوالي 5 دقائق لـ OCR، و80 دقيقة لتحويل النص إلى كلام، وبضع دقائق لمعايرة الصوت (EBU R128) ولتجهيز ملف M4A النهائي. هذا أبطأ من ملف PDF نصّي — لكنه يعمل. أما قبل ذلك، فلم يكن يعمل إطلاقًا.
ماذا يعني هذا إن كان لديك رفّ ممتلئ بالمسوحات
إذا كنت تكتنز كتبًا ممسوحة ضوئيًا — إعادات طبع قديمة، روايات نفدت من السوق، رقمنات في الملكية العامة من archive.org، أو مسوحاتك الخاصة لكتاب وصفات جدّتك — فهي لم تعد عالقة على الورق. ارفعها. نحن نتولّى OCR.
حاليًا نشغّل OCR بـ 12 لغة: الإنجليزية، الإسبانية، البرتغالية، الفرنسية، الألمانية، البولندية، الإيطالية، التركية، العربية، اليابانية، الكورية، والهندية. أما الكتاب الصوتي نفسه فيمكن توليده بأي من 23 لغة صوتية. وإذا كان كتابك الممسوح بلغة لا ندعمها بعد في OCR، فأرسل لنا ملاحظة — إضافة حزمة لغة جديدة إلى tesseract لا تتطلّب سوى دقائق معدودة.
ملاحظة حول الترخيص التجاري
كامل حزمة OCR التي نستخدمها — tesseract و pypdfium2 و pytesseract — مرخّصة بـ Apache 2.0. وهذا أمر مهمّ إن كنت تبني شيئًا مماثلًا: PyMuPDF هو الخيار السهل لتصيير PDF في Python، لكن ترخيصه AGPL يُلزمك بفتح المصدر لكامل خدمتك من نوع SaaS إن استخدمته في الإنتاج. أما pypdfium2 مع tesseract فيمنحانك الإمكانات نفسها دون أي تركة ترخيصية.
الخطأ الذي جعلنا أفضل
تُلتقَط معظم أخطاء الإنتاج أثناء الاختبار. أمّا هذا الخطأ فلم يُلتقَط، لأن الفرضية — "ملفات PDF تحتوي على نصّ" — كانت صحيحة لكل ملف تطوير استخدمناه يومًا. لزم الأمر قارئة حقيقية من تشيلي، في ساعتها الأولى على المنصّة، حتى يطفو إلى السطح.
لذا، شكرًا لكم أيها القرّاء الحقيقيون. أنتم تجدون الأخطاء التي لا نستطيع نحن العثور عليها.