نحو معيار موحّد لبيانات التلاوات الصوتية للقرآن الكريم
وقت القراءة: نحو ٤٥ دقيقة
المقدمة
بسم الله الرحمن الرحيم
منذ عدة أشهر بدأت رحلة مع عدد من أعضاء المجتمع للبحث في إمكانية بناء معيار موحّد للبيانات القرآنية. واليوم أشارككم جزءًا من هذه الرحلة، وهو بحثي في بيانات التلاوات الصوتية. لعل هذا البحث يفتح باب النقاش، ويساعدنا في الوصول إلى معيار يمكن للمشاريع القرآنية البناء عليه.
بدأ الموضوع من مشاركة لطارق منصور، من فريق تطبيق الكتاب، تحدث فيها عن مشكلة الاعتماد على مصادر التلاوات الصوتية، وبالذات في أوقات الذروة. وذكر مصدرين: MP3Quran، الذي يوفر ملفات للسور كاملة وتوقيتات للآيات في بعض التلاوات، وEveryAyah، الذي ينظم التلاوات أساسًا في ملفات صوتية مستقلة لكل آية.
كذلك يعتمد أحد المشاريع مفتوحة المصدر، مصحف عماد (Flutter)، على ثلاثة مصادر صوتية: MP3Quran، وQuran Foundation (Quran.com)، وItqan CMS.
وبعد ذلك عمل هادي الأحمد وإبراهيم يوسف على مشروعين في هذا الموضوع: quranrouter لهادي، وهو تجربة React لطبقة توجيه داخل التطبيق، وquran-api-unified لإبراهيم، وهي حزمة TypeScript توحّد النص والصوت والترجمة والتفسير، وتنفذ التبديل بين المصادر.
وأعتقد أن هذه الجهود كلها تلتقي عند هدف واحد: بناء Quran Recitation Audio Router. أما بناء الـrouter نفسه فهو جهد برمجي مستقل، بينما يركز هذا البحث على السؤال الذي يسبقه: ما شكل البيانات التي يحتاجها حتى يستطيع فهم المصادر المختلفة والتبديل بينها من غير خلط؟
والحقيقة أن بناء الراوتر ليس المجال الذي أستطيع أن أقدم فيه أفضل ما عندي، لكن ما أستطيع تقديمه هو دراسة هياكل بيانات المصادر والمساعدة في بناء هيكلة البيانات الموحّدة. وأدعو مهندسي البرمجيات إلى الاستفادة من هذا العمل لبناء الراوتر، حتى ينتفع به أصحاب التطبيقات القرآنية.
يتكون هذا البحث من أربعة أجزاء:
- شرح التحدي: اختلاف هياكل بيانات المصادر، ومشكلة المعرّفات عند التبديل بينها.
- عرض المصادر: مصادر التلاوات المتاحة اليوم، وكيف ينظم كل منها بياناته.
- تصور الحقول المشتركة: المعلومات الأساسية التي نحتاج إلى وصفها في بيانات التلاوات.
- مراجعة المصطلحات: المصطلحات القرآنية الصحيحة لهيكلة البيانات الموحّدة، تمهيدًا لبناء معيار موحّد.
حسب مخرجات البحث، فقد نشرت أداة تساعدك على فهم كل مصدر بيانات ذكر في هذا البحث.
تحديث نموذج حصر المصطلحات القرآنية
نشرت سابقًا عن مشروع حصر المصطلحات القرآنية، وهدفه بناء معجم للمصطلحات المستخدمة في سياق البيانات والبرمجة؛ حتى يسهل علينا تسمية الـobjects والـlabels والحقول في قواعد البيانات.
وأثناء بحثي في بيانات التلاوات الصوتية اكتشفت عددًا من المصطلحات التي تحتاج إلى الحصر والمراجعة، وقد أضفتها إلى جدول حصر المصطلحات القرآنية. أتمنى منكم مراجعته ومشاركة ملاحظاتكم.
شرح التحدي
قبل أن أشرح المشكلة، أوجه الشكر لكل المصادر المذكورة، وجزاهم الله خيرًا على إتاحة هذه التلاوات مجانًا. وما سأذكره هنا ليس انتقاصًا من جهودهم، بل محاولة لفهم مواطن النقص؛ حتى تتحسن البيانات ويستطيع المطورون خدمة عدد أكبر من المستخدمين.
يعاني مطورو التطبيقات من تعدد مصادر التلاوات الصوتية، لكن المشكلة الأكبر ليست وجود أكثر من مصدر، بل أن كل مصدر ينظم البيانات بطريقة مختلفة وينظر إلى التلاوة من زاوية مختلفة. فـMP3Quran ينظم الصوت حول القارئ وتلاواته وملفات السور، بينما EveryAyah أقرب إلى فهارس ومسارات لملفات مستقلة، ويجمع QuranAPI ملفات الآيات من EveryAyah وملفات السور من MP3Quran تحت مفاتيح محلية خاصة به.
وهذا يعني أن الحقول والمعرّفات لا تمثل دائمًا الشيء نفسه. فقد يدل المعرّف في مصدر على قارئ، وفي مصدر آخر على تلاوة أو مجلد ملفات، وقد لا يفصل المصدر أصلًا بين اسم القارئ والرواية ونمط الأداء. كذلك قد يقدم مصدر ملفًا كاملًا للسورة مع توقيتات للآيات، بينما يقدم مصدر آخر ملفًا مستقلًا لكل آية.
لنفترض أن المستخدم يستمع الآن إلى سورة الفاتحة، ووصل إلى الآية الثانية، والتلاوة المرتلة للقارئ مشاري العفاسي. إذا احتاج الـrouter إلى التبديل من مصدر إلى آخر، فما البيانات التي سيرسلها إلى المصدر الجديد؟ هل يرسل معرّف القارئ؟ هذا المعرّف محلي وقد يدل على شيء مختلف في المصدر الآخر. وهل يكفي اسم القارئ؟ الاسم وحده لا يثبت أن الملفين للتلاوة نفسها، أو للرواية ونمط الأداء نفسيهما. ثم هل سيبحث عن ملف السورة كاملًا ويحتاج إلى توقيت الآية، أم عن ملف مستقل للآية الثانية؟
هنا تظهر المشكلة التي يحاول هذا البحث معالجتها. نحتاج أولًا إلى وصف واضح يفرّق بين القارئ، والرواية، ونمط الأداء، والتلاوة، والملف الصوتي، ونطاقه، والتوقيتات المرتبطة به. وبعد ذلك نحتاج إلى خريطة ربط (mapping) تصل معرّفات كل مصدر وحقوله بهذه المفاهيم من غير خلط. من دون ذلك قد ينتقل التطبيق إلى صوت يحمل اسم القارئ نفسه، لكنه لا يمثل التلاوة نفسها، أو قد لا يستطيع متابعة التلاوة من الموضع الذي وصل إليه المستخدم.
مصادر التلاوات المتاحة اليوم
في هذه الجولة بدأت بثلاثة مصادر تختلف في طريقة تنظيم الصوت ووصفه:
- الأول: MP3Quran
- الثاني: EveryAyah
- الثالث: QuranAPI
وهذه ليست قائمة نهائية بكل مصادر التلاوات، لكنها نقطة بداية جيدة؛ لأن كل واحد منها ينظر إلى البيانات بطريقة مختلفة. وسأشرح كل مصدر من ثلاث زوايا: ما البيانات التي يقدمها، وكيف ينظمها، وما المشكلات التي تظهر عند محاولة ربطه بالمصادر الأخرى.
ربما يكون MP3Quran من أكثر المصادر استخدامًا في التطبيقات القرآنية. وسأشرح هنا هيكلة بيانات المصدر باختصار، ثم أتوقف عند بعض مواضع الالتباس التي قد تساعدنا لاحقًا في تصميم هيكلة البيانات الموحّدة.
أولًا: ما يقدمه MP3Quran
لفهم هيكلة بيانات المصدر، نبدأ بمورد reciters. يعيد المصدر قائمة بالقراء، ويوجد داخل كل قارئ مصفوفة moshaf. كل عنصر في هذه المصفوفة يمثل تلاوة لذلك القارئ، وليس ملفًا صوتيًا واحدًا. ويمكن تمثيل العلاقات كالآتي:
reciter
├── id, name
└── moshaf[]
└── moshaf
├── id معرّف التلاوة لدى MP3Quran
├── name الاسم المعروض، مثل: حفص عن عاصم - مرتل
├── rewaya_id معرّف الرواية في كتالوج /riwayat
├── moshaf_type معرّف التصنيف المركب في كتالوج /moshaf
├── surah_list أرقام السور المتاحة
├── surah_total العدد المعلن للسور
└── server المسار الأساسي لملفات السور
├── 001.mp3 سورة الفاتحة
├── 002.mp3 سورة البقرة
└── ...
وهنا مثال بسيط من البيانات الفعلية يوضح أن القارئ الواحد قد يملك أكثر من moshaf:
{
"id": 102,
"name": "ماهر المعيقلي",
"letter": "م",
"moshaf": [
{
"id": 133,
"name": "المصحف المجود - المصحف المجود",
"rewaya_id": 22,
"surah_total": 114,
"moshaf_type": 222,
"surah_list": "1,2,3,...,114",
"server": "https://server12.mp3quran.net/maher/Almusshaf-Al-Mojawwad/"
},
{
"id": 103,
"name": "المصحف المعلم - المصحف المعلم",
"rewaya_id": 21,
"surah_total": 38,
"moshaf_type": 213,
"surah_list": "1,78,79,...,114",
"server": "https://server12.mp3quran.net/maher/Almusshaf-Al-Mo-lim/"
},
{
"id": 102,
"name": "حفص عن عاصم - مرتل",
"rewaya_id": 1,
"surah_total": 114,
"moshaf_type": 11,
"surah_list": "1,2,3,...,114",
"server": "https://server12.mp3quran.net/maher/"
}
]
}
ملاحظة: اختصرت قيم surah_list في المثال باستعمال ....
وهناك أيضًا موردان مرتبطان بكل عنصر moshaf متداخل تحت القارئ، وهما riwayat وmoshaf.
قبل شرح العلاقة، يجب الانتباه إلى أن MP3Quran يستعمل اسم moshaf في موضعين مختلفين:
reciters.moshaf: مصفوفة التلاوات التي تخص قارئًا معينًا. يحمل كل عنصر معرّفه المحلي، والمسار الأساسي لبناء روابط الملفات، والسور المتاحة.
- مورد
/moshaf: كتالوج مشترك لتصنيفات مركبة، مثل حفص عن عاصم - مرتل. لا يمثل العنصر فيه تلاوة بعينها، بل تصنيفًا يمكن أن ترتبط به تلاوات مختلفة.
وبعبارة أبسط: عنصر moshaf المتداخل تحت القارئ يمثل تلاوة تخص ذلك القارئ، أما مورد /moshaf فهو كتالوج يصنّف التلاوات.
يظهر ذلك في تلاوة ماهر المعيقلي المرتلة. فمورد reciters يعيد التلاوة الآتية داخل سجل القارئ:
{
"reciters": [
{
"id": 102,
"name": "ماهر المعيقلي",
"moshaf": [
{
"id": 102,
"name": "حفص عن عاصم - مرتل",
"rewaya_id": 1,
"moshaf_type": 11
}
]
}
]
}
يعرّف rewaya_id: 1 رواية هذه التلاوة. نبحث عن id: 1 في مورد riwayat، فنجد:
{
"riwayat": [
{
"id": 1,
"name": "حفص عن عاصم"
}
]
}
ويعرّف moshaf_type: 11 تصنيف التلاوة. نبحث عن id: 11 في مورد /moshaf، فنجد:
{
"riwayat": [
{
"id": 11,
"moshaf_type": 1,
"moshaf_id": 1,
"name": "حفص عن عاصم - مرتل"
}
]
}
ملاحظة: يستعمل مورد /moshaf المفتاح riwayat لاحتواء القائمة، مع أن عناصرها تمثل تصنيفات مركبة. وهذا موضع آخر لعدم اتساق التسميات في المصدر 😅.
وتكون العلاقة كالآتي:
ماهر المعيقلي
└── moshaf[] تلاوة متداخلة في سجل القارئ
├── id: 102 معرّف تلاوة ماهر نفسها
├── rewaya_id: 1 → /riwayat → id: 1 → حفص عن عاصم
└── moshaf_type: 11 → /moshaf → id: 11 → حفص عن عاصم - مرتل
ثانيًا: المصطلحات القرآنية المستعملة
سبق أن كتبت عن مشكلة عدم اتساق المصطلحات في التقنيات القرآنية هنا، وناقشت بعض أمثلتها مع إبراهيم يوسف هنا. وتظهر المشكلة نفسها داخل MP3Quran؛ إذ لا تتبع أسماء الموارد والحقول قاعدة واحدة.
وقد تحققت من الأمثلة التالية في الإصدار v3، وهو أحدث إصدار موثق حاليًا:
| الموضع | المسميات المستعملة | موضع عدم الاتساق |
| تسمية القوائم | reciters وsuwar | جمع إنجليزي في الأول، وجمع عربي مكتوب بالحروف اللاتينية في الثاني |
| السورة | sura وsurah وsoar وsuwar | أربع صيغ لكتابة اسم السورة وجمعها |
| الرواية | rewaya وrewayah وriwayat | اختلاف التهجئة وقاعدة الجمع للمفهوم نفسه |
| مدلول الرواية | يضم مورد /riwayat روايات مثل «حفص عن عاصم»، وقيمًا مثل «المصحف المعلم» و«المصحف المجود» | خلط مستوى الرواية بمستوى نمط الأداء أو التلاوة |
قد تبدو هذه التفاصيل صغيرة، لكنها مؤثرة جدًا عند بناء مكتبة أو ربط أكثر من مصدر. فالاسم المتسق يساعد المطور على توقّع الحقول وفهم العلاقات بينها. أما هنا، فيحتاج إلى حفظ الاستثناءات، وقد يفسر البيانات تفسيرًا خاطئًا؛ كأن يعامل «المصحف المجود» على أنه رواية، أو يفترض أن كل ظهور لـmoshaf يؤدي الدور نفسه.
من الاسم نفسه يتضح أن EveryAyah ينطلق من ملف الآية. وهو مختلف عن MP3Quran؛ فلا ينشر هرمية بيانات واضحة من نوع «قارئ ← تلاوات ← ملفات صوتية»، بل هو أقرب إلى مكتبة ملفات صوتية لها عدة فهارس منفصلة.
في اللقطة التي راجعتها بتاريخ 13 أغسطس 2026، وجدت ثلاثة فهارس رئيسية للصوت:
- الأول:
recitations.js، وهو ملف JSON فيه 79 سجلًا.
- الثاني: Ayat MP3، وهي صفحة تعرض 80 مدخلًا لتلاوات ذات ملفات مستقلة للآيات.
- الثالث: Page MP3، وهي صفحة تعرض 67 رابطًا لمجلدات
PageMp3s.
والجدير بالذكر أن هذه القوائم لا تتطابق تمامًا؛ لذلك لا أتعامل مع واحدة منها على أنها الفهرس الكامل والنهائي للمصدر.
أولًا: البيانات التي ينشرها EveryAyah
ماذا يوجد في recitations.js؟
أما recitations.js فهو بسيط جدًا. يحتوي على ayahCount، وهي مصفوفة فيها عدد آيات كل سورة، ثم مفاتيح نصية من "1" إلى "79". ولكل مفتاح ثلاثة حقول فقط:
{
"ayahCount": [7, 286, 200, "..."], // 7= الفاتحة
"15": {
"subfolder": "Alafasy_128kbps", // مسار المجلد الذي يحتوي ملفات الآيات
"name": "Alafasy", // اسم التلاوة كما نشره المصدر
"bitrate": "128kbps" // وصف نصي لمعدل البت
}
}
ولا يوضح المصدر هل هذه المفاتيح معرّفات ثابتة، كما أنها ليست معرّفات للأشخاص بالضرورة. والجدير بالذكر أن name قد يجمع في نص واحد اسم القارئ ونمط الأداء والرواية واللغة والمترجم. مربك قليلًا 😅.
ملفات الآيات والصفحات
ملف الآية يأخذ غالبًا هذا الشكل:
https://everyayah.com/data/{subfolder}/{SSS}{AAA}.mp3
فـSSS هو رقم السورة من ثلاث خانات، وAAA هو رقم الآية من ثلاث خانات. فمثلًا 001001.mp3 هو ملف الآية الأولى من سورة الفاتحة. لكن وجود سجل في الفهرس لا يعني بالضرورة أن مجلده يحتوي جميع ملفات القرآن؛ فالتغطية تختلف بين المجلدات.
أما ملفات الصفحات فتوجد عادة داخل PageMp3s بأسماء مثل Page001.mp3 إلى Page604.mp3. وهي ملفات تجمع تلاوة صفحة كاملة، لكنها ليست متاحة لكل التلاوات المفهرسة، وبعض مجلداتها ناقص أو فارغ. ولا يحدد EveryAyah طبعة المصحف أو نظام الصفحات في حقل مستقل؛ لذلك لا يكفي عدد الصفحات وحده لإثبات الطبعة أو القراءة المقصودة.
الترجمات الصوتية للآيات
يوجد في recitations.js ثمانية سجلات مرتبطة بترجمات أو مواد متعددة اللغات، منها الإنجليزية والفارسية والأردية والبوسنية والأذربيجانية. لكن اللغة والمترجم والقارئ ليست حقولًا مستقلة؛ بل تظهر داخل name أو اسم المجلد، كما في الترجمة الإنجليزية والمادة الأردية.
وهنا تظهر نقطة مهمة: الترجمة المنطوقة ليست بالضرورة «نوع تلاوة» من المحور نفسه الذي يضم المرتل أو المجود، بل محتوى صوتي مصاحب يحتاج إلى وصف مستقل.
قيم bitrate
حقل bitrate يصف معدل البت بالكيلوبت في الثانية، لكن نوعه في EveryAyah هو string. والقيم العددية التي ظهرت في الفهرس هي:
16, 32, 40, 46, 48, 64, 128, 192 kbps
هذه قيم نصية مرصودة وليست enum موثقًا. وحتى طريقة الكتابة ليست متسقة؛ فالمصدر يستعمل 64kbps و64Kbps. كما توجد حالات يذكر فيها اسم المجلد 16 أو 40 أو 48 kbps، بينما يحمل حقل bitrate القيمة 64Kbps.
والأهم أن القيمة المكتوبة لا تضمن دائمًا معدل البت الفعلي للملف؛ لذلك يجب أن تفرّق هيكلة البيانات الموحّدة بين القيمة التي يعلنها المصدر والقيمة التي نقيسها من الملف.
مسار تلاوات ورش
يوجد في EveryAyah مسار مستقل باسم warsh/، ويحتوي على ثلاثة مجلدات منشورة:
- الأول:
warsh_Abdul_Basit_128kbps
- الثاني:
warsh_ibrahim_aldosary_128kbps
- الثالث:
warsh_yassin_al_jazaery_64kbps
وتظهر هذه المسارات أيضًا في حقل subfolder داخل recitations.js. لذلك يمكن تكوين رابط ملف الآية بالطريقة المعتادة، مثل:
https://everyayah.com/data/warsh/warsh_ibrahim_aldosary_128kbps/001001.mp3
لكن warsh/ يبقى اسم مسار، ولا يوجد في recitations.js حقل مستقل باسم riwayah. نحن نفهم «ورش» مصطلحيًا على أنه رواية، لكن EveryAyah لم ينشره هنا كبيان منظم بهذا النوع.
ثانيًا: المصطلحات القرآنية المستعملة
في EveryAyah لا تكمن المشكلة في كثرة الحقول؛ فالحقول قليلة جدًا. المشكلة أن name وsubfolder يجمعان مفاهيم قرآنية مختلفة داخل نص واحد:
| الموضع | أمثلة من المصدر | موضع الالتباس |
| ألفاظ الأداء | Murattal وMujawwad وMuallim | تظهر داخل الاسم، ولا يعرّفها المصدر في حقل مستقل لنمط الأداء |
| لفظ الرواية | يظهر في اسم مثل (Warsh) Ibrahim Al-Dosary ومسار warsh/ | نفهم Warsh مصطلحيًا على أنه رواية، لكن المصدر ينشره كنص فقط |
| الترجمات | (English) Translated by Sahih International Recited by Ibrahim Walk | اللغة والمترجم والقارئ مجتمعة في name واحد |
| اسم القارئ | Menshawi في بعض الحالات، وMinshawy في أخرى | الشكلان موجودان، لكن المصدر لا ينشر علاقة alias أو معرّف شخص يربط بينهما |
إذن لا يحمل name في recitations.js بنية واحدة ظاهرة؛ فقد يكون نصًا قصيرًا، أو يجمع الاسم مع كلمات تدل على الأداء أو الرواية، أو يجمع اللغة والمترجم والقارئ.
ثالثًا: هل يحتاج EveryAyah نفسه إلى التغيير؟
ربما لم يكن هدف EveryAyah أصلًا أن يقدم هيكلة بيانات مصدر متكاملة؛ فهو يبدو أقرب إلى أرشيف منظم للملفات الصوتية الخام. ولهذا لا أرى أن الحل يبدأ بالضرورة من تغيير المصدر نفسه. يمكن أن يبقى EveryAyah كما هو، بينما تصف هيكلة البيانات الموحّدة ملفاته وتفصل ما جمعته الأسماء والمسارات: القارئ، والتلاوة، والرواية، ونمط الأداء، واللغة، والتغطية، وخصائص الملف الصوتي.
الوضع في QuranAPI مختلف قليلًا عن المصدرين السابقين. فالمشروع يقدم بيانات القرآن في ملفات JSON، ومنها النصوص والترجمات والتفاسير، لكن ما يهمنا هنا هو الجزء الصوتي فقط.
في هذا الجزء لا يقدم QuranAPI تلاوات أصلية مستقلة؛ بل يجمع خمسة قراء، ويربط ملفات الآيات من EveryAyah بملفات السور من MP3Quran، ثم ينشر روابط ملفات بديلة في مستودعات The Quran Project. لذلك هو أقرب إلى مجمّع ومرآة منه إلى مصدر أصلي للتلاوات.
أولًا: قائمة القراء
نبدأ بمورد reciters.json، وهو أبسط مورد صوتي في QuranAPI:
{
"1": "Mishary Rashid Al Afasy",
"2": "Abu Bakr Al Shatri",
"3": "Nasser Al Qatami",
"4": "Yasser Al Dosari",
"5": "Hani Ar Rifai"
}
المفاتيح من "1" إلى "5" هي معرّفات محلية داخل QuranAPI، وليست معرّفات القراء في EveryAyah أو MP3Quran. ووظيفتها الأساسية أن تكون مفتاح ربط يجمع اسمًا معروضًا، ومجلدًا في EveryAyah، ومسارًا في MP3Quran.
ثانيًا: ملفات الآيات وملفات السور
يقدم QuranAPI الصوت على مستويين:
فمثلًا، يعيد مورد الآية الأولى من سورة الفاتحة خمسة عناصر. وإذا أخذنا العنصر الأول فقط فشكله كالآتي:
{
"1": {
"reciter": "Mishary Rashid Al Afasy",
"url": "https://the-quran-project.github.io/Quran-Audio/Data/1/1_1.mp3",
"originalUrl": "https://everyayah.com/data/Alafasy_128kbps/001001.mp3"
}
}
أما مورد سورة الفاتحة فيعيد الشكل نفسه، لكن الرابطين هذه المرة يشيران إلى ملف السورة كاملة، لا إلى آية واحدة:
{
"1": {
"reciter": "Mishary Rashid Al Afasy",
"url": "https://github.com/The-Quran-Project/Quran-Audio-Chapters/raw/refs/heads/main/Data/1/1.mp3",
"originalUrl": "https://server8.mp3quran.net/afs/001.mp3"
}
}
إذن كل عنصر يحمل ثلاثة حقول فقط:
- الأول:
reciter: اسم القارئ بالإنجليزية.
- الثاني:
url: رابط الملف في مستودعات The Quran Project.
- الثالث:
originalUrl: الرابط الذي ينسب إليه QuranAPI أصل الملف؛ وهو من EveryAyah للآيات، ومن MP3Quran للسور.
لا يحمل العنصر نفسه رقم السورة أو الآية، بل نعرفهما من مسار ملف JSON الذي طلبناه. كما لا يوضح الحقل originalUrl طبيعة العلاقة بين الرابطين: هل هما للملف الصوتي نفسه تمامًا، أم لنسختين مختلفتين من التلاوة نفسها، أم أن أحد الملفين أعيد ترميزه؟
ثالثًا: كيف يربط QuranAPI المصدرين؟
يستعمل QuranAPI المفتاح نفسه للقارئ في ملفات الآيات والسور كالتالي:
| مفتاح QuranAPI | الاسم | مجلد الآيات في EveryAyah | مسار السور في MP3Quran |
1 | Mishary Rashid Al Afasy | Alafasy_128kbps | afs |
2 | Abu Bakr Al Shatri | Abu_Bakr_Ash-Shaatree_128kbps | shatri |
3 | Nasser Al Qatami | Nasser_Alqatami_128kbps | qtm |
4 | Yasser Al Dosari | Yasser_Ad-Dussary_128kbps | yasser |
5 | Hani Ar Rifai | Hani_Rifai_192kbps | hani |
هذا يعني أن المفتاح "1" مثلًا يجمع اسم مشاري العفاسي مع مجلد آيات في EveryAyah ومسار سور في MP3Quran. لكنه لا يثبت أن ملفات الآيات وملفات السور تعود إلى التلاوة نفسها لمجرد أنها جُمعت تحت الاسم والمفتاح نفسيهما.
رابعًا: أين يظهر الصوت أيضًا؟
الشكل السابق لا يظهر في موارد الصوت المنفصلة فقط. فمورد الآية مثل /api/1/1.json يضع خريطة ملفات الآيات داخل الحقل audio، ومورد السورة مثل /api/1.json يستعمل الحقل نفسه لملفات السور الكاملة. لذلك لا نعرف مستوى الملف من اسم audio وحده، بل من المورد الأب الذي ظهر فيه.
وتوجد بنية أخرى داخل ملفات القرآن الكاملة بحسب اللغة، مثل english.json. يحمل كل عنصر سورة فيها:
- الأول:
audio: ملفات السورة الكاملة للقراء الخمسة.
- الثاني:
verseAudio: ملفات الآيات للقراء الخمسة.
داخل verseAudio توضع روابط الآيات في مصفوفة اسمها audios. ولا يحمل كل عنصر فيها رقم الآية؛ فالآية الأولى هي العنصر الأول، والثانية هي العنصر الثاني، وهكذا. أي أن العلاقة تعتمد على ترتيب المصفوفة.
خامسًا: التغطية وما لا تعرضه هيكلة بيانات المصدر
تغطي أسماء الملفات المنشورة القرآن كاملًا للقراء الخمسة، لكن هذه النتيجة جاءت من عدّ الملفات، وليست حقلًا منشورًا داخل استجابات QuranAPI.
ورغم بساطة هيكلة بيانات المصدر، توجد معلومات مهمة لا يعرضها QuranAPI:
- لا يوجد معرّف مستقل للتلاوة.
- لا توجد حقول للرواية أو القراءة أو نمط الأداء.
- لا توجد حقول للصيغة أو معدل البت أو المدة أو الحجم.
- لا توجد توقيتات للآيات أو الكلمات داخل ملفات السور.
- لا يوجد معرّف للأصل أو نوع علاقة يوضح هل
url مطابق لـoriginalUrl أو مشتق منه.
إذن أنسب وصف لـQuranAPI في هذا البحث أنه مجمّع ومرآة للبيانات: يقدم شكلًا بسيطًا لربط ملفات آيات وسور لخمسة قراء، لكن هيكلة بيانات المصدر لا تفرّق بين القارئ والتلاوة والرواية والملف الصوتي ورابطه.
سادسًا: المصطلحات القرآنية المستعملة
يستعمل QuranAPI مصطلحات قليلة في الجزء الصوتي، لكنها لا تمثل جميع المفاهيم التي نحتاجها لوصف التلاوات بدقة:
| المصطلح في QuranAPI | كيف يستعمله المصدر | موضع الالتباس |
reciter | اسم القارئ بالإنجليزية | يمثل اسمًا معروضًا فقط، ولا يحدد تلاوة بعينها |
surah وayah | يظهران في مسارات الصوت مثل /audio/{surah}/{ayah}.json | يستعمل التوثيق أيضًا كلمتي chapter وverse لشرح المفهومين نفسيهما |
audio | ملفات آيات داخل مورد الآية، وملفات سور كاملة داخل مورد السورة | اسم الحقل وحده لا يبين هل الملف لآية أم لسورة |
verseAudio | ملفات الآيات داخل ملفات القرآن الكاملة بحسب اللغة | يمزج المصدر بين verse الإنجليزية وayah المكتوبة بالحروف اللاتينية للمفهوم نفسه |
مرة أخرى، المشكلة ليست أن اختيار كلمة إنجليزية بدل أخرى خطأ في ذاته، بل أن المفهوم نفسه يظهر بأسماء مختلفة، وأن الاسم العام مثل audio لا يوضح نطاق الملف الصوتي. وعند بناء هيكلة البيانات الموحّدة سنحتاج إلى تسمية صريحة تفرّق بين ملف السورة وملف الآية، مع الاحتفاظ بأسماء المصدر الأصلية داخل جدول خريطة الربط (mapping).
نحو مصطلحات قرآنية موحّدة
أرى أن معجم المصطلحات يجب أن يكون جزءًا من هذا المعيار، فنحن نحتاج إلى تعريف واضح لكل مفهوم، واسم برمجي ثابت، وأسماء المصادر المقابلة له.
وأفضّل أن نبدأ الآن بقائمة مفاهيم وحقول واضحة يستطيع المجتمع والمختصون مراجعتها. وبعد الاتفاق على هذه المفاهيم يمكن للمطورين مناقشة طريقة تمثيلها تقنيًا في مرحلة لاحقة.
ومثل ماذكرت في أول البحث، فقد استخرجت بعض المصطلحات، فقد تم إضافتها هنا
خاتمة
ربما ذكرت في هذا البحث كثيرًا من الثغرات ومواضع عدم الاتساق، لكن هذا لا ينتقص من قيمة هذه المصادر ولا من جهود القائمين عليها. فقد أسهمت هذه المصادر في خدمة عدد كبير من المسلمين، وانتفع بها كثير منا بشكل أو بآخر.
والهدف من هذا البحث ليس استبدال هذه المصادر، بل تعظيم أثرها. فإذا استطعنا أن نصف بياناتها بلغة مشتركة، ونفرّق بوضوح بين القارئ والرواية والتلاوة والملف الصوتي والتوقيت، فسيصبح من الأسهل على المطورين البناء عليها، وربطها، وإيصالها إلى تقنيات وتجارب جديدة، وربما إلى مستخدمين لم تصل إليهم من قبل.
وما وصلت إليه هنا ليس معيارًا نهائيًا، بل خطوة في رحلة بدأت بحصر المصطلحات، ثم دراسة المصادر واحدًا واحدًا، وستكتمل — بإذن الله — بالمقارنة بينها وبناء هيكلة البيانات الموحّدة وخريطة ربط واضحة لكل مصدر.
أتمنى أن أكون وُفقت في هذا البحث، ولا أستغني عن آرائكم واقتراحاتكم، وبالذات من مطوري التطبيقات القرآنية والمختصين في علوم القرآن والصوتيات.
ما المفاهيم أو الحالات التي ترون أن هذا التصور لم يغطّها بعد؟