MusicBee UPnP Plugin المساعدة

الجديد

2.0.9 - 2026-08-23

تفتح إشعار التحديث صفحاته بلغتك

ماذا: تفتح روابط ما الجديد و تنزيل في إشعار التحديث الآن صفحات المكون الإضافي بلغة MusicBee الخاصة، بدلاً من الإنجليزية.

لماذا: كانت تلك الروابط تضيّق اللغة إلى واحدة من أربع لغات — الإنجليزية أو الفرنسية أو الإسبانية أو الألمانية — قبل إرسالها إلى الموقع الإلكتروني، لذلك كان الجميع يتلقون الصفحة الإنجليزية حتى لو كان هناك ترجمة لها. الآن، تمرر هذه الروابط لغة MusicBee دون تغيير وتترك للموقع الإلكتروني حرية تحديد ما سيتم تقديمه، وهو ما كان يفعله زر المساعدة بجانبهما دائمًا.

2.0.8 - 2026-08-22

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

تعرض أجهزتك الشركة المصنعة والطراز والإصدار الصحيحين

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

لماذا: يعلن كل جهاز UPnP عن من صنعه وما هو، وتعرض تطبيقات التحكم ذلك كهوية للجهاز. كان هذا المكون الإضافي لا يزال يعلن عن تفاصيل المكون الإضافي الأصلي الذي تم اشتقاقه منه: اسم مؤلف آخر، وموقع MusicBee بدلاً من موقعه الخاص، ورقم طراز ثابت عند "1.0" منذ الإصدار الأول. من هاتفك، لم يكن هناك طريقة لمعرفة أي مكون إضافي كنت تتحدث إليه، ناهيك عن أي إصدار منه. تأتي هذه التفاصيل الآن من المكون الإضافي نفسه، لذلك يظل الإصدار المعروض بجانب الجهاز صحيحًا مع كل تحديث.

تتوافق إعدادات ملفات تعريف الجهاز مرة أخرى

ماذا: في علامة التبويب "ملفات تعريف الجهاز"، تتشارك التسميات ومربعاتها حافة يسرى واحدة وتجلس بمسافات متساوية، ويقرأ نطاق معدل العينة كصف واحد.

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

2.0.7 - 2026-08-08

المسارات الأكبر تحتفظ بعنوانها وشريط تمرير الموضع الخاص بها

ما الجديد: المسار الأكبر المرسل من الهاتف — ملف FLAC طويل، أو ملف عالي الدقة أو DSD — يعرض الآن عنوانه الصحيح ويمكن التنقل فيه، مثل المسار الصغير. في السابق، كانت بعض هذه الملفات تُشغل عبر الشبكة بدلاً من ذلك، مع عنوان ويب بدلاً من العنوان وشريط تمرير لا يفعل شيئًا.

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

2.0.6 - 2026-08-03

أصبحت الألبومات المرسلة من الهاتف تُشغل الآن دون فجوة بين المقاطع الصوتية، ويتم التعرف على راديو الإنترنت كراديو بدلاً من التعامل معه كأغنية طويلة بشكل غير عادي.

تشغيل الألبومات بدون فجوات

ماذا: عندما ترسل ألبومًا كاملاً من هاتفك، ينتقل MusicBee الآن من مقطع صوتي إلى التالي دون توقف — لذا فإن التسجيلات الحية ومجموعات الدي جي والأعمال الكلاسيكية المتواصلة تبقى متماسكة.

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

يتم التعرف على راديو الإنترنت كراديو

ماذا: يتم تشغيل محطة بث مباشر مرسلة إلى MusicBee كتيار ولا يتم تنزيلها أبدًا.

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

المقاطع الصوتية الطويلة عالية الدقة تحتفظ بنسختها

ماذا: يمكن الآن التنقل في ملفات DSD والتسجيلات الطويلة بدقة 24 بت مثل أي مقطع صوتي آخر.

لماذا: تم التقاطها بواسطة حد الحجم المذكور أعلاه — تجاوزت حركة عالية الدقة مدتها 20 دقيقة أو مقطع DSD مدته 10 دقائق هذا الحد — لذلك تم التخلي عن نسختها وتوقف شريط التمرير عن العمل بالضبط للمادة التي من المرجح أن تستحق التمرير. مع تحديد الراديو بشكل صحيح، لا يلزم وجود حد للحجم.

2.0.5 - 2026-08-03

إصلاحان لتشغيل MusicBee من الهاتف: أصبح مستوى الصوت يعني نفس الشيء في كلا الطرفين، ويستمر تشغيل الألبوم بأكمله بعد المسار الأول.

مستوى الصوت على هاتفك يطابق مستوى الصوت في MusicBee

ماذا: يؤدي رفع مستوى الصوت إلى الحد الأقصى على هاتفك الآن إلى الوصول إلى الحد الأقصى في MusicBee، ويتم قراءة إعداد MusicBee الخاص بشكل صحيح على الهاتف.

لماذا: لم يخبر المكون الإضافي التطبيق المتحكم أبدًا عن أعلى مستوى صوت لديه، لذلك كان على كل تطبيق التخمين. استقر أحدهما على 69، مما يعني أن 100% منه وصل إلى 69% فقط في MusicBee، بينما عادت 100% من MusicBee كـ 144% على الهاتف - ولم تتمكن أزرار الصوت في الهاتف أبدًا من الوصول إلى الحد الأقصى تمامًا. يعرض العارض الآن النطاق بوضوح، لذلك يتحدث الطرفان عن نفس المقياس.

يستمر إرسال الألبوم في عرض عناوينه وشريط التمرير الخاص بموضعه

ماذا: يعرض كل مسار من ألبوم يتم إرساله من الهاتف الآن عنوانه الصحيح ويمكن التنقل فيه، وليس فقط الأول.

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

2.0.4 - 2026-08-02

أصبحت الموسيقى المرسلة إلى MusicBee من هاتف أو خادم آخر تتصرف الآن كمسار حقيقي: يمكنك التنقل خلالها، وتظهر عنوانها الصحيح على الفور. بالإضافة إلى إصلاح لأجهزة بث الصوت عالية الدقة التي تقدم نفسها كجهاز مدمج واحد.

التنقل عبر مسار مرسل من مكان آخر

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

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

العنوان والطول الصحيحان من أول نغمة

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

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

القفزة التي لا يمكن إجراؤها تقول ذلك الآن

ماذا: إذا كان العارض لا يستطيع حقًا الانتقال إلى النقطة المطلوبة، يتم إبلاغ التطبيق المتحكم، ويقوم بالإبلاغ عن ذلك.

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

أجهزة بث الصوت عالية الدقة المدمجة تُقرأ بشكل صحيح

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

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

2.0.3 - 2026-08-02

تطور دور التشغيل إلى: يمكن الآن إرسال الموسيقى إلى MusicBee التي ليست موجودة بالفعل في مكتبته - ملف على هاتفك، أو على NAS، أو على خادم آخر - بدلاً من المسارات التي يمتلكها بالفعل فقط.

تشغيل الموسيقى المرسلة من هاتفك، وليس فقط مكتبتك الخاصة

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

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

المسار الذي لا يمكن تشغيله يوضح ذلك

ماذا: إذا لم يتمكن العارض حقًا من تشغيل ما تم إرساله إليه، فإنه الآن يبلغ ذلك إلى التطبيق الذي أرسله.

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

إرسال مسار جديد أثناء الإيقاف المؤقت يقوم الآن بتشغيل هذا المسار

ماذا: إذا كان MusicBee متوقفًا مؤقتًا وأرسل له تطبيق التحكم الخاص بك شيئًا جديدًا، يبدأ المسار الجديد.

لماذا: استأنف التشغيل الأولوية على التحميل، لذلك استأنف المسار المتوقف مؤقتًا من حيث توقف وتم إسقاط المسار الذي اخترته للتو دون كلمة.

2.0.2 - 2026-08-01

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

البحث حسب الفنان يعمل بالفعل

ماذا: البحث عن فنان من تطبيق التحكم الخاص بك يعرض الآن موسيقى هذا الفنان. يطابق البحث كلاً من Artist للمسار و Album Artist للألبوم، لذلك يتم العثور على مجموعة سواء كتبت اسم المؤدي أو الاسم الذي تم تصنيف الألبوم تحته.

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

صفحة نتائج البحث بشكل صحيح

ماذا: التمرير عبر قائمة طويلة من نتائج البحث ينتقل الآن خلالها. كل صفحة تمرر إليها هي الصفحة التي تحصل عليها عليها.

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

البحث أسرع بكثير على مكتبة كبيرة

ماذا: يقوم البحث الآن بتشغيل استعلام واحد لمجموعة النتائج بأكملها ويقرأ فقط علامات الصفحة التي تنظر إليها.

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

وجه خلطك إلى فلتر

ماذا: إعداد جديد Random plays from في علامة تبويب Library Options. اتركه على All Music وستتصرف مجلدات Random Tracks / Random Albums لتطبيق التحكم الخاص بك كما كانت من قبل؛ اختر أحد فلاتر MusicBee الخاصة بك وكل طلب عشوائي يسحب من هذا الفلتر بدلاً من ذلك. يتم تقديم الفلاتر المخفية أيضًا.

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

المساعدة و GitHub والتحقق من التحديث تصل إلى صفحات حقيقية

ماذا: أزرار Help و GitHub في مربع حوار الإعدادات، والتحقق التلقائي من وجود إصدار جديد، تفتح الآن الصفحات التي تحمل اسمها.

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

2.0.1 - 2026-07-26

جولة من إصلاحات التشغيل والتصفح، تركز على البودكاست وتطبيقات التحكم (مثل BubbleUPnP) التي تدير التشغيل والتبديل العشوائي.

تبدأ ملفات البودكاست بالتشغيل دون توقف مؤقت

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

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

تظهر ملفات البودكاست عند التصفح حسب الفنان

ماذا: يتم الآن تصنيف اسم عرض البودكاست كفنان له — ينعكس في حقلي الفنان وفنان الألبوم (ومتغيرات الفرز الخاصة بهما)، تمامًا كما يملأ بالفعل حقل الألبوم.

لماذا: كان مسار التصفح الذي يجمع حسب حقل الفنان يجد فنان كل بودكاست فارغًا وينتهي إلى مستوى فارغ. معاملة العرض نفسه كفنان — بما يتوافق مع معاملته كألبوم — يعني أن هذه المسارات تصل الآن إلى الحلقات بدلاً من لا شيء.

تعمل "المشغلة مؤخرًا" والإرسال بشكل صحيح بعد إعادة التشغيل

ماذا: لم يعد تشغيل بودكاست أو كتاب صوتي أو بريد وارد أو مسار راديو مباشرة — دون التصفح إليه أولاً، بالطريقة التي تفعلها قائمة "المشغلة مؤخرًا" وأهداف الإرسال في BubbleUPnP — يفشل. يقوم المكون الإضافي الآن بتحميل المسار عند الطلب عندما يُطلب بمعرفه.

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

"مسارات عشوائية" و "ألبومات عشوائية" تعيد النتائج

ماذا: مجلدات التبديل العشوائي "مسارات عشوائية" و "ألبومات عشوائية" في BubbleUPnP، التي تطلب شريحة عشوائية من المكتبة بأكملها، تعود الآن ممتلئة.

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

الألبومات ذات العلامة الفارغة تسرد مساراتها

ماذا: فتح ألبوم تم تجميعه على قيمة فارغة — على سبيل المثال مسارات البريد الوارد التي لا تحمل سنة — يعرض الآن مساراته.

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


2.0.0 - 2026-07-22

هذا هو الإصدار العام الأول من yaiol، وهو فرع مفتوح المصدر من مكون MusicBee الإضافي لـ UPnP. يتم تقديمه في جزأين: كل ما هو جديد في هذا الفرع، ثم الإصلاحات والتحسينات التي تم إجراؤها على المكون الإضافي الأصلي. يحتفظ كل عنصر بنموذج ماذا / لماذا من كتالوج الميزات الداخلية للمشروع، بحيث يكون المنطق وراء كل تغيير موجودًا في الصفحة، وليس مجرد التغيير.

الجديد في هذا الفرع

MediaRenderer - التشغيل إلى MusicBee

N01 - MusicBee كعارض للتشغيل

ماذا: عادةً ما يعمل هذا المكون الإضافي في اتجاه واحد: يتصفح هاتف أو جهاز آخر مكتبة MusicBee ويشغل الموسيقى على نفسه. تضيف هذه الميزة الاتجاه المعاكس - فهي تسمح لـ MusicBee بأن يكون المشغل. من تطبيق تحكم على هاتفك (مثل BubbleUPnP) يمكنك اختيار MusicBee على سطح المكتب كشيء يقوم بالتشغيل، ثم التحكم فيه من يدك: التشغيل، الإيقاف المؤقت، الإيقاف، التخطي للأمام أو الخلف، الانتقال إلى نقطة في المسار، وتغيير مستوى الصوت أو كتمه.

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

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

التمييز بين أجهزتك: يمكنك إعطاء العارض أي اسم تريده (يبدأ بـ "MusicBee (yaiol)"). هذا الاسم هو ما يظهر في قائمة أهداف التشغيل على هاتفك، لذلك عندما يكون هناك أكثر من جهاز كمبيوتر واحد يشغل MusicBee، يمكنك معرفة أيها هو. يسري تغيير الاسم على الفور، دون الحاجة إلى إعادة تشغيل.

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

تشغيله بشكل خاص: تعمل الأدوار الثلاثة بشكل مستقل، لذا يمكنك تشغيل العارض مع ترك مشاركة المكتبة متوقفة. في هذا الإعداد "عارض فقط"، تظل مكتبتك مخفية تمامًا عن الشبكة - يتم الإعلان عن هدف التشغيل فقط - ولن يعرض MusicBee أبدًا التشغيل لنفسه.


سلوك التشغيل

N02 - FLAC 5.1 لا يتم خلطه تلقائيًا

ماذا: كان قيد عدد القنوات في MediaServerDevice.GetEncodedFile هو If StereoOnly OrElse Not isPcmData Then channelCount = 2. كانت عبارة Not isPcmData تقوم بخلط كل تحويل غير PCM (FLAC، MP3، AAC، Ogg) إلى ستريو بصمت بغض النظر عن عدد قنوات المصدر، مما يعطل العارضات القادرة على 5.1 عندما كان المصدر FLAC 5.1. الآن تستثني العبارة الثانية FLAC: Not isPcmData AndAlso encoder.Codec <> FileCodec.Flac. يمر FLAC 5.1؛ ولا يزال MP3/AAC/Ogg يفرض ستريو لأن مشفرات MusicBee سطر الأوامر لتلك التنسيقات تتوقع إدخال قناتين.

لماذا: الهدف من تحويل مصدر FLAC 5.1 إلى إخراج FLAC هو الحفاظ على المزيج متعدد القنوات. جعل الخلط الصامت خيار تحويل FLAC عديم الفائدة للاستماع المحيطي. مع N02، يقوم بالشيء الصحيح.


البنية

التغيير الهيكلي الذي يجعل الفرع قابلاً للتطبيق على مكتبة كبيرة - غائب عن المكون الإضافي الأصلي.

N03 - شجرة التصفح الكسولة (حسب الطلب)

ماذا: قام المكون الإضافي الأصلي ببناء شجرة التصفح بأكملها عند بدء تشغيل MusicBee - تعداد كل مسار، Library_GetFileTags كامل لكل ملف، تجميع التسلسل الهرمي للحاويات بالكامل - قبل فتح منفذ HTTP. في مكتبة حقيقية (أكثر من 50 ألف مسار، 5400 حلقة بودكاست، مئات المحطات) يستغرق ذلك دقائق من البدء البارد، وتبقى الشجرة في ذاكرة الوصول العشوائي إلى الأبد بما في ذلك الفروع التي لا يفتحها أي عميل. لا يبني هذا الفرع أي شيء مقدمًا: يعرض الجذر عنصرًا نائبًا واحدًا مسبوقًا بـ L: لكل نقطة نهاية (L:music، L:podcast، L:filter:…)؛ يتم حساب كل مستوى فقط عندما يتصفح العميل فيه (LazyBrowseEnsureLazyEndpointInMemory ← ذاكرات التخزين المؤقت لكل مستوى)، وتقوم إشعارات تغيير المكتبة بمسح ذاكرات التخزين المؤقت (SetLibraryDirty).

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


الشبكات والمتانة

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

N04 - ربط منفذ HTTP ذاتي الإصلاح

ماذا: لم يعد خادم HTTP الخاص بالمكون الإضافي يموت عندما يكون منفذه المكون غير متاح. ثلاثة تغييرات مرتبطة:

  1. العودة التلقائية عند فشل الربط. يحاول HttpServer.Start المنفذ المكون، وعند SocketException يقوم بمسح ما يصل إلى 20 منفذًا للعثور على أول منفذ متاح. يتم تسجيل المنفذ المربوط الفعلي في Plugin.boundServerPort جديد، و كل ما يعلن عن الخادم - عناوين URL لـ SSDP LOCATION (استجابة NOTIFY + M-SEARCH)، عنوان URL للجهاز (PrimaryHostUrl)، إعادة توجيه منفذ الموجه، وفلاتر SSDP/نقطة التحكم الذاتية - يقرأ الآن boundServerPort بدلاً من Settings.ServerPort. تكتشف عملاء UPnP المنفذ الحقيقي عبر SSDP، لذا فإن المنفذ المنقول يكون شفافًا للعارضات.
  2. إشعار المستخدم. عندما يحدث تراجع (المنفذ المحفوظ ليس هو المستخدم)، يخبر MessageBox مترجم (WarnPortInUse) المستخدم بالمنفذ الذي يخدم بالفعل وأن الأجهزة ستظل تجده - لأن المكون الإضافي يعمل بدون واجهة مستخدم ولن يرى رسالة داخل مربع الحوار إلا شخص يشتبه بالفعل في وجود مشكلة.
  3. استعادة إعادة التشغيل. كان RestartServer (مسار إعادة تشغيل حفظ الإعدادات) يقوم بإلغاء مرجعية Plugin.controller / Plugin.server بشكل أعمى. إذا ألقى Initialise الأولي خطأ قبل إنشائهما (وهو بالضبط ما تسبب فيه فشل الربط)، فإن حفظ الإعدادات التالي كان يصطدم بـ NullReferenceException - تاركًا مكونًا إضافيًا شبه ميت. يقوم الآن بإعادة إنشائهما وبدء تشغيلهما عندما يكون Nothing، لذا فإن حفظ منفذ عامل يعيد إحياء المكون الإضافي دون إعادة تشغيل MusicBee بالكامل.

لماذا: كان المحفز حادثة مستخدم حقيقية. كان المنفذ الافتراضي القديم 49382 يعيش في النطاق الديناميكي لنظام التشغيل Windows (49152-65535)، حيث تحتفظ Hyper-V/WSL2/Docker/WinNAT بكتل كبيرة تتغير عند كل تمهيد - لذا فشل الربط بـ WSAEACCES ("الوصول محظور") على جهاز كان يعمل عليه لأشهر. ثم اصطدم تغيير الافتراضي إلى منفذ متاح مع Serviio (خادم DLNA منفصل موجود بالفعل على المنفذ الجديد)، وفشل بـ WSAEADDRINUSE. تم ابتلاع كل فشل في Initialise، تاركًا المكون الإضافي ميتًا بصمت ثم NRE-ing عند حفظ الإعدادات التالي. بعد N04، يصلح تصادم المنفذ نفسه - يستمر الخادم في العمل على المنفذ المتاح التالي، ويتم إخبار المستخدم، ويعيد العملاء اكتشافه - بدلاً من تعطيل المكون الإضافي بالكامل.

التنفيذ:

  • تم نقل المنفذ الافتراضي 493829779 (أقل من النطاق الديناميكي، لذلك لا يقوم Windows بحجزه تلقائيًا؛ ليس افتراضيًا معروفًا لخادم الوسائط) في جميع إعلانات ServerPort الثلاثة + العودة عند فشل تحليل الإعدادات.
  • Plugin.boundServerPort (حقل مشترك جديد) يحمل منفذ الاستماع المباشر؛ يبقى activeServerPort هو اللقطة المكونة حتى لا يتم تشغيل منطق شارة "إعادة التشغيل مطلوبة" بشكل خاطئ عند التراجع.
  • HttpServer.PortScanRange = 20؛ يتوقف المسح عند أول TcpListener.Start() ناجح ويلقي الاستثناء الأخير فقط إذا فشلت جميع المحاولات.
  • مفتاح مورد EN جديد WarnPortInUse (تتبع الترجمات تمريرة اللغة المحلية وقت النشر).

N05 - إعلانات SSDP عبر مجموعة البث المتعدد (VPN / نقطة إلى نقطة)

ماذا: يتم إرسال إعلانات SSDP إلى مجموعة البث المتعدد لـ UPnP (239.255.255.250) بدلاً من عنوان بث IP. يتم أيضًا قمع خطأ "لا يمكن الوصول إلى كائن تم التخلص منه" غير الضار الذي يتم تسجيله عندما تتسابق استجابة بحث SSDP مع إعادة تشغيل الخادم.

لماذا: على محولات الشبكة من نقطة إلى نقطة / VPN، لا ينطبق بث IP - فشل إرسال البث القديم بـ "وسيطة غير صالحة" وتم تفويت الإعلانات، لذلك كان المكون الإضافي غير مرئي للعملاء على تلك الروابط. إصلاح الإعلان إلى مجموعة البث المتعدد الصحيحة يحل مشكلة الاكتشاف على هذه المحولات بالضبط.

التنقل في المكتبة

تم شحن هذه الميزات في هذا الفرع وليست موجودة في المكون الإضافي الأصلي. جاءت من تصفح مخرجات المكون الإضافي الخاصة من عملاء UPnP حقيقيين.

N06 - عرض المكتبة المستند إلى الفلتر

ماذا: تصبح علامات تبويب الفلتر في MusicBee (ملفات .xautopf في مجلد MusicBee الخاص بالمستخدم) حاويات جذر UPnP في مكتبة المكون الإضافي. ثم يمكن تصفح مسارات كل فلتر في تسلسل هرمي من AlbumArtistSort → Album → Tracks.

لماذا: يتوقع المستخدمون الذين لديهم فلاتر MusicBee منسقة (مثل "مسارات 5 نجوم"، "المضافة مؤخرًا"، "كلاسيكي ← باروك") العثور عليها عند تصفح المكون الإضافي من عميل UPnP. كان المكون الإضافي الأصلي يعرض فقط شجرة المكتبة الخام.


N07 - توصيل حقل SortAlbumArtist

ماذا: يقرأ المكون الإضافي الآن MetaDataType 165 (Sort Album Artist) من MusicBee ويستخدمه لتجميع/فرز الفنانين في طرق عرض التصفح.

لماذا: يستخدم متصفحات Hi-Fi وعشاق الموسيقى أسماء الفنانين المصنفة ("Beethoven, Ludwig van" بدلاً من "Ludwig van Beethoven") لتنظيم المكتبات. توقع قياسي للمستمعين الجادين. مفقود من كلا المصدرين.


N08 - معالجة AlbumArtist متعدد القيم

ماذا: عندما يحتوي حقل AlbumArtist لألبوم على فنانين متعددين مفصولين بـ "; " (مثل "yaiol; Ars Ricercata"), يظهر المسار الآن تحت كل فنان في طرق عرض التصفح، وليس تحت فنان واحد يجمع الأسماء.

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


N09 - غلاف الألبوم للحاوية (upnp:albumArtURI)

ماذا: تتضمن عقد حاوية الألبوم في استجابات تصفح DIDL الآن عنصر upnp:albumArtURI يشير إلى غلاف الألبوم.

لماذا: بدون هذا، يعرض كل ألبوم في عرض تصفح عميل UPnP أيقونة عامة بدلاً من غلاف الألبوم. إشارة بصرية للتنقل؛ متوقعة من قبل كل متصفح Hi-Fi حديث.


N10 - ترتيب المسارات داخل ألبومات الفلتر

ماذا: يتم الآن فرز المسارات داخل ألبوم مكشوف بالفلتر حسب رقم القرص، ثم رقم المسار.

لماذا: ترتيب الألبوم القياسي. بدون فرز صريح، كانت المسارات تعود بأي ترتيب يرجعها الفلتر - عادة ما تبدو عشوائية.


N11 - إصلاح شجرة مجلدات قائمة التشغيل

ماذا: فشلت دالة LoadLibraryPlaylists (التي كتبها ستيفن مايال في حوالي عام 2014) في النزول إلى مجلدات قائمة التشغيل التي تم إنشاؤها حديثًا. انتهى الأمر بأول قائمة تشغيل في كل مجلد، بالإضافة إلى أي مجلدات فرعية، كيتيمة في المستوى الجذر.

لماذا: كانت موجودة في المكون الإضافي الأصلي لمدة أحد عشر عامًا. مرئية في غضون 30 ثانية من فتح BubbleUPnP والنقر على قوائم التشغيل. تم إصلاحها في yaiol عن طريق التكرار الصحيح في المجلدات التي تم إنشاؤها حديثًا أثناء بناء الشجرة.


N12 - تنقية أحرف التحكم غير القانونية في XML

ماذا: أي مسار يحتوي على علامة تحتوي على حرف تحكم C0 (مثل 0x19 من تمريرة ترميز سيئة - UTF-8 ← Latin-1 ← اقتطاع 0x99 إلى 0x19) تسبب في فشل استجابة التصفح بأكملها بـ Action Failed بمجرد دخول المسار السيئ إلى دفعة مقسمة.

لماذا: يمنع XML 1.0 معظم أحرف التحكم C0، ويلقي XmlWriter خطأ عند طلب كتابة أي منها. موجود في المكون الإضافي الأصلي. تم إصلاحه عن طريق إزالة الأحرف غير الصالحة عند كل نقطة خروج Library_GetFileTags عبر XmlConvert.IsXmlChar.


N13 - قائمة الراديو حتمية عبر التصفح المقسم

ماذا: سقط تصفح حاوية الراديو في فرع قائمة الملفات العامة، والذي استدعى files.Sort(AlbumFileComparer) في كل استدعاء. تحتوي إدخالات الراديو على علامات ألبوم/قرص/مسار فارغة، لذا أعادت كل مقارنة 0 - List(Of T).Sort غير مستقر، مما ينتج ترتيبًا مختلفًا في كل استدعاء. تقوم نقاط تحكم UPnP بتقسيم الصفحات (يجلب BubbleUPnP من 0 إلى 15 ثم من 16 إلى النهاية)؛ بين الاستدعاءين، أعيد ترتيب القائمة، لذا ظهرت بعض المحطات في كلتا الصفحتين (مكررة) وبعضها لم يظهر في أي منهما (مفقودة) - تبدو عشوائية في كل تحديث.

لماذا: موجود في المكون الإضافي الأصلي (لم يتصفح مؤلفه الراديو عبر UPnP أبدًا). تم إصلاحه هنا بفرع ContainerCategory.Radio مخصص في Browse، بدون فرز لكل استدعاء؛ يتم فرز radioFiles مرة واحدة عند وقت التحميل حسب العنوان (مستقر). يرى التصفح المقسم الآن ترتيبًا حتميًا؛ الصفحة 1 والصفحة 2 منفصلتان.


N14 - بحث UPnP من فئة الألبوم يعيد حاويات الألبوم

ماذا: بحث UPnP عن استعلامات فئة الألبوم (upnp:class = "object.container.album.musicAlbum"، على سبيل المثال "ألبومات عشوائية" في BubbleUPnP) أعاد قائمة المسارات الكاملة بدلاً من حاويات الألبوم، لذلك عرض العميل صفر ألبومات. كان المعالج الأصلي يحلل فقط المعايير بين قوسين، ثم يرمي جميع المسارات بغض النظر عن الفئة المطلوبة.

لماذا: تم إصلاحه هنا - استعلامات فئة الألبوم الآن تعد الألبومات المميزة (مجمعة حسب AlbumArtist+Album) وتصدر كل منها كحاوية musicAlbum مناسبة مع غلاف الألبوم، يمكن الوصول إليها عبر مساحة المعرف الافتراضي Salb<idx> حتى يتمكن العميل من التعمق في نتيجة وتشغيلها.


N15 - بحث UPnP عامل وواعي بالنطاق مع النقر للتصفح

ماذا: لم يعلن الأصل عن أي إمكانيات بحث (GetSearchCapabilities أعاد فارغًا)، لذلك رفض العملاء حتى إرسال بحث؛ وقرأ الواجهة الخلفية القديمة من musicFiles، وهي فارغة بشكل دائم في عصر الشجرة الكسولة. يعلن هذا الفرع عن الخصائص القابلة للبحث الحقيقية، وينفذ البحث عن المسارات حسب العنوان والألبومات حسب العنوان مقابل المكتبة الكسولة (HandleLazySearch)، ويحدد نطاق الاستعلام إلى الفرع الحالي للعميل عند إرسال معرف حاوية حقيقي (وإلا يستبدل L:music حتى لا تجلب عمليات البحث في الشريط العلوي ضوضاء البودكاست/الراديو/الكتب الصوتية)، ويجعل نتائج الألبوم قابلة للنقر عبر معرفات Ssrch_alb_* الاصطناعية التي يقوم فرع Browse المبكر بربطها مرة أخرى بمسارات الألبوم. (قطعة نتائج فئة الألبوم كحاويات هي N14.)

لماذا: تحول البحث في BubbleUPnP من "المكتبة لا تدعم البحث" إلى إرجاع نتائج مفيدة، محددة النطاق، قابلة للتشغيل. تصميم كامل + الأساليب المرفوضة: SEARCH.md.


N16 - إبطال ذاكرة التخزين المؤقت لـ UPnP (SystemUpdateID)

ماذا: أعاد الأصل SystemUpdateID=0 ثابتًا - عقد إبطال ذاكرة التخزين المؤقت لـ UPnP ContentDirectory - لذلك تعامل العملاء المتوافقون مع المواصفات (BubbleUPnP) مع المكتبة على أنها لا تتغير أبدًا: نتائج تصفح قديمة، صور مصغرة 404 بعد تغيير مخطط URL، ورقصة "إعادة تشغيل MusicBee مرتين لرؤية التغييرات". يزرع هذا الفرع SystemUpdateID من ثواني العصر عند التحميل (لذلك كل إعادة تشغيل تسبق الأخيرة تمامًا) ويزيدها عند كل تغيير في المكتبة وتغيير في الإعدادات (SetLibraryDirty / ResetCacheBumpSystemUpdateId).

لماذا: يلتقط العملاء التعديلات والملفات الجديدة وتغييرات الإعدادات بشكل موثوق في تصفحهم التالي. حد معروف: لا يتم إعادة دفع القيمة الجديدة للعملاء المشتركين بنشاط عبر GENA (متوقفة كعمل مستقبلي)؛ لا يزالون يرونها في تصفحهم التالي.


N17 - غلاف اشتراك البودكاست

ماذا: لم تعرض مربعات البودكاست أي صور - كل طلب /PodcastThumbnail/ أرجع 404. خطأان متراكمان: لم تتحقق سلسلة الحل أبدًا من ذاكرة التخزين المؤقت الفعلية لـ MusicBee (%LocalAppData%\MusicBee\InternalCache\Subscriptions\<name>.jpg، حيث يتم التحميل من واجهة المستخدم لسطح المكتب)، وقامت طبقة HTTP بإلغاء الهروب + تحويل الأحرف الصغيرة بتشويه مفتاح مسار URL للخلاصة إلى آخر جزء من المسار. يحل هذا الفرع العمل الفني من InternalCache الخاص بـ MB ويوجه عمليات البحث عبر slug آمن لعنوان URL يبقى سليمًا في طبقة HTTP (PodcastSlug / podcastSubIdBySlug).

لماذا: يتم الآن عرض غلاف الاشتراك في طرق عرض التصفح (يتم حل جميع الطلبات الـ 22 التي كانت ترجع 404 سابقًا).


N18 - تصفح العلامات الهرمي (المحدد)

ماذا: يمكن وضع علامة هرمي على أي حقل في علامة تبويب خيارات المكتبة وإعطائه محددًا من حرف واحد (محدد حقل + مربع محدد مع إضافة/إزالة، يتم الاحتفاظ به في إعدادات المكون الإضافي). قم بتعيين Grouping إلى / وقيمة مثل Jazz/Cool Jazz ثم يتم تصفحها كـ Jazz › Cool Jazz بدلاً من إدخال مسطح واحد. تحصل المسارات التي تم وضع علامة عليها بالضبط عند فرع (فقط Jazz) على عقدة [Jazz] خاصة بها حتى لا يتم إخفاء أي شيء، وينهار الفرع الذي يحتوي على طفل واحد من تلقاء نفسه، ويتم رفض ; كمحدد لأنه هو محدد MusicBee متعدد القيم الخاص به.

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


N19 - مسار جذر واحد مُسمى بحقل التجميع الخاص به

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

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


N20 - دمج مسارات التصفح التي تشترك في حقل أول

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

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


N21 - مسارات التصفح المصنفة حسب الفئة (قياسي / راديو / بودكاست)

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

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


N22 - تجميع البودكاست حسب سنة النشر

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

لماذا: تصبح اشتراكات البودكاست الكبيرة قابلة للتصفح حسب السنة مثل بقية المكتبة، بدلاً من أن تهبط كل حلقة في كومة واحدة غير مؤرخة لأن المكون الإضافي لم ينظر أبدًا إلى تاريخ نشر كل حلقة.


N23 - طي مستويات التجميع ذات النتيجة الواحدة

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

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


N24 - تجميع/بحث السنة مقابل حقل التاريخ في MusicBee

ماذا: لم يعد شرط السنة يستعلم عن حقل "السنة" ذي التاريخ الكامل في MusicBee بقيمة مكونة من أربعة أرقام فقط، وقد اختفى التسمية المستعارة لحقل السنة المبرمجة بشكل ثابت، بحيث يتم الآن حل كل حقل تجميع بشكل عام من تعريف المسار.

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


N25 - فصل حقول التجميع "السنة" و "السنة (yyyy)"

ماذا: تعرض مسارات تجميع الألبوم والتصفح الآن كلا حقلي السنة الخاصين بـ MusicBee - السنة (علامة التاريخ الكامل) و السنة (yyyy) (السنة المكونة من أربعة أرقام فقط) - حتى يتمكن المستخدم من اختيار أي منهما عند تحديد تجميع ألبوم أو مسار تصفح.

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


N32 - الفلاتر وقوائم التشغيل المثبتة مجمعة حسب النوع في الجذر

ماذا: يظهر الفلتر المثبت الآن مباشرة أسفل مجلد الفلاتر في جذر التصفح، وتظهر قائمة التشغيل المثبتة مباشرة أسفل مجلد قوائم التشغيل، بدلاً من تجميع جميع التثبيتات في كتلة واحدة في نهاية الجذر. يجلس كل اختصار مثبت مع نوعه الخاص.

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

مربع حوار الإعدادات والتعبئة

N26 - مربع حوار الإعدادات المقسم

ماذا: حصلت صفحة التفضيلات على تخطيط تنقل أيسر مع أقسام: عام / تشغيل / مكتبة / ملفات تعريف الجهاز / تشخيصات.

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


إعادة تسمية التجميع + المكون الإضافي (لا يوجد معرف F - ملاحظة التعبئة)

ماذا: يتم تسمية DLL المترجم mb_UPnP_yaiol.dll ويبلغ المكون الإضافي عن نفسه باسم "MusicBee UPnP (yaiol)". يختلف عن mb_Upnp.dll الأصلي.

لماذا: يمكن للمستخدمين تثبيت yaiol جنبًا إلى جنب مع المكون الإضافي الأصلي ومقارنة السلوك جنبًا إلى جنب.


نظام الشارات - إظهار حالة وقت التشغيل (الآلية وراء F40)

ماذا: نمط واجهة مستخدم عام لإظهار ظروف وقت التشغيل المهمة كشارات ملونة مرئية في مربع حوار الإعدادات. الحالات الحالية:

  • ⚠ Max Conn (N04) - يتم تشغيله عندما يتم الوصول إلى حد أقصى للاتصالات مرة واحدة على الأقل منذ بدء تشغيل MusicBee. علامة جلسة لاصقة Plugin.MaxConnectionsHit. يتم تعيينها داخل WaitOnSendBarrier عندما لا تكون هناك فتحة متاحة.
  • ⚠ Restart Required - يتم تشغيله عندما يتطلب إعداد محفوظ إعادة تشغيل MusicBee ليصبح ساري المفعول. علامة جلسة لاصقة Plugin.RestartRequired. يتم تعيينها في معالج حفظ مربع الحوار عندما تختلف القيمة المستمرة الجديدة عن لقطة وقت التشغيل (Plugin.activeMaxConnections، Plugin.activeServerPort، Plugin.activeIpAddress). تقتصر الإعدادات التي تتطلب إعادة تشغيل على تلك التي لا يمكن إعادة تحميلها فعليًا - معلمات ربط خادم HTTP و SemaphoreSlim التي تم إنشاؤها مرة واحدة عند التهيئة.

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

قابلة لإعادة الاستخدام في المستقبل:

  • تم اكتشاف عدم تطابق الملف الشخصي (لم يتطابق وكيل المستخدم للجهاز أبدًا مع أي ملف شخصي، وعاد إلى عام).
  • تم تشغيل تراجع NextURI (F13 - تم تعطيل التشغيل بدون فجوات للجلسة على جهاز غير مستقر).
  • فشل مسح المكتبة / جزئي.
  • فقد اتصال العارض في منتصف الجلسة.
  • أي حالة أخرى حيث "حدث مرة واحدة، يجب أن يعرف المستخدم" أفضل من "تم تسجيله بصمت بين 1000 سطر آخر".

اتفاقيات التنفيذ:

  • تعيش تسميات الشارات على مستوى مربع الحوار (وليس داخل أي لوحة) بحيث تكون مرئية بغض النظر عن القسم الذي يتواجد فيه المستخدم.
  • موضوعة على طول الصف السفلي بالقرب من حفظ/إلغاء (الحالي: y=410 مكدسة أفقيًا).
  • تحتوي كل شارة على علامة جلسة لاصقة مقابلة في Plugin تتحول إلى True عندما يحدث الشرط وتتم إعادة تعيينها فقط عند إعادة تشغيل MusicBee.
  • الموارد: <Condition>Badge (نص التسمية، مسبوقًا بـ ⚠) + <Condition>BadgeTip (تلميح يشرح السبب + العلاج).
  • بالنسبة لشارات "الإعداد المحفوظ يتطلب إعادة تشغيل"، خذ لقطة وقت التشغيل عند Plugin.Initialise() وقارنها بـ Settings.* بعد Settings.SaveSettings() في معالج حفظ مربع الحوار.

N27 - إلغاء يتجاهل تعديلات المسار/القالب

ماذا: يتم الآن تجاهل التعديلات التي تم إجراؤها على المسارات والقوالب داخل مربع حوار الإعدادات عندما ينقر المستخدم على "إلغاء"، بدلاً من البقاء مطبقة بصمت، ويتم إعادة إنشاء أي قالب محجوز تم إزالته خلال الجلسة. (يتم حفظ القوالب بخلاف ذلك مباشرة أثناء تحريرها - لا يوجد زر حفظ منفصل في علامة تبويب المسارات.)

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


N28 - علامات العطف الحرفية في قائمة محدد الحقول

ماذا: يعرض الحقل الذي يحتوي اسمه على "&" - على سبيل المثال "Mood & Context" - علامة العطف حرفيًا في قائمة محدد الحقول بدلاً من ابتلاعها كبادئة Alt-mnemonic.

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


N29 - عنوان نافذة إعدادات ثابت وغير مترجم

ماذا: تم تثبيت عنوان نافذة الإعدادات على سلسلة العلامة التجارية "MusicBee UPnP Plugin" ولم يعد يتغير مع لغة الواجهة؛ تم إسقاط سلسلة DialogTitle لكل لغة من كل حزمة لغة محلية.

لماذا: كان عنوان النافذة الذي يغير صياغته حسب اللغة سطحًا قابلاً للترجمة بدون فائدة - العنوان هو علامة تجارية. تثبيته يحافظ على استقراره واتساقه في كل مكان.

الترجمة

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

N30 - واجهة مستخدم متعددة اللغات (الترجمات قيد الانتظار)

ماذا: آلة الترجمة كاملة ويتم شحنها. يقرأ Localisation.vb اللغة المحددة في MusicBee من MusicBee3Settings.ini (اسم اللغة الذاتي <SystemLanguage>) ويطبق الثقافة المطابقة لـ .NET على الخيط، لذلك يعيد My.Resources.Resources.* السلسلة المترجمة. يتم ربط كل تسمية/زر/رسالة موجهة للمستخدم بمفتاح مورد (عناصر تحكم المصمم عبر ApplyDesignerExtras + sync-en-locale.js؛ سلاسل وقت التشغيل مثل WarnPortInUse مضافة يدويًا). ما لم يتم بعد هو الترجمة الفعلية: توجد حزمة المصدر الإنجليزية فقط (Resources.resx) - يتم إنتاج حزم الأقمار الصناعية للغات الأخرى في دفعة واحدة عندما يكون المكون الإضافي مكتمل الميزات (الترجمة الجزئية بينما لا تزال السلاسل تتغير تهدر الجهد).

اللغات المستهدفة (المجموعة التي يقدمها MusicBee نفسه، مطابقة 1:1 بواسطة endonymToCulture بحيث يتبع المكون الإضافي لغة MusicBee تلقائيًا):

العربية (ar) التشيكية (cs) الألمانية (de) اليونانية (el)
الإسبانية (es) الفرنسية (fr) المجرية (hu) الإيطالية (it)
الكورية (ko) الهولندية (nl) النرويجية (nb) البولندية (pl)
البرتغالية البرازيلية (pt-BR) البرتغالية البرتغالية (pt-PT) السويدية (sv) التركية (tr)
الأوكرانية (uk) الروسية (ru) اليابانية (ja) الصينية المبسطة (zh-CN)
الصينية التقليدية (zh-TW) الإنجليزية (en، المصدر)

سياسة المتغيرات (وفقًا لقاعدة اللغة المحلية لمساحة العمل): يتم تقسيم PT و ZH إلى حزم مميزة لأن المفردات/النصوص تختلف حقًا (pt-BR/pt-PT، zh-CN/zh-TW). EN هي حزمة واحدة - "الإنجليزية (الولايات المتحدة)" في MusicBee (en-US) تعود إلى en عبر سلسلة ثقافة .NET، لذلك لا يتم إنتاج حزمة أمريكية منفصلة. الإسبانية والفرنسية هي أيضًا لغة واحدة.

لماذا: إعدادات مكون UPnP الإضافي ("لا تستخدم PCM الخام"، "فرض PCM ذي الترتيب الصغير"، تحذيرات تراجع المنفذ) غامضة بما يكفي بلغتك الأم. اتباع لغة واجهة مستخدم MusicBee الخاصة - بدلاً من فرض اللغة الإنجليزية - هو الفرق بين أداة يمكن للمستخدم غير الإنجليزي تكوينها وأداة لا يمكنه ذلك. لم يحاول أي من المصدرين الأصليين ذلك.


N31 - رابط المساعدة يفتح بلغة الواجهة الكاملة

ماذا: فتح رابط المساعدة من المكون الإضافي يحترم لغة واجهة المستخدم الكاملة للمستخدم (مثل pt-BR، zh-CN) بدلاً من الانهيار إلى اللغة الأساسية، ويرسل معرف تحقق من التحديث أوضح.

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

إصلاحات وتحسينات على المكون الإضافي الأصلي

البروتوكول الأساسي والتشغيل

F01 - تحديث ملفات تعريف جهاز DLNA الافتراضية

ماذا: يشحن ملفات تعريف افتراضية جديدة لـ PlayStation 4 و Xbox 360/One و BubbleUPnP الحديث، مع علامات قدرة (معدلات العينة، عمق البت، برامج الترميز) تعكس ما تدعمه هذه الأجهزة بالفعل اليوم.

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


F02 - أجهزة التحكم التي تعلن عن MediaRenderer:3

ماذا: يقوم المكون الإضافي بفحص وصف خدمة UPnP للعارض لتحديد ما إذا كان MusicBee يمكنه تشغيله. كان الأصل يطابق فقط urn:schemas-upnp-org:device:MediaRenderer:1. تعلن الأجهزة الحديثة عن :2 أو :3. يوسع F02 المطابقة.

لماذا: بدون هذا، لا تظهر وحدات Sonos / WiiM / Eversolo الحديثة ببساطة كأهداف في قائمة "تشغيل إلى" في MusicBee - على الرغم من أنها تتحدث نفس البروتوكول. إصلاح مطابقة بادئة سلسلة واحدة يفتح جيل الأجهزة الحديث بالكامل.


F03 - خيار "فرض دفق أصلي" لكل ملف تعريف (افتراضيًا تشغيل)

ماذا: عند تحديده، يرسل المكون الإضافي بايتات الملف الأصلي إلى الجهاز بدون تحويل ترميز، بدون معالجة DSP، بدون معالجة ReplayGain مطبقة. فقط الملف الخام الذي اختاره المستخدم، بايتًا ببايت (باستثناء تأطير HTTP).

لماذا: وفقًا لشهادات المنتديات، هذا هو أكبر مكسب في جودة التشغيل. يرغب مستخدمو Hi-Fi الذين يشترون عارضات باهظة الثمن صراحة في إخراج مثالي للبت؛ أي لمسة DSP تلغي الغرض. افتراضيًا تشغيل لأن معظم الأجهزة الحديثة تتعامل مع أي برنامج ترميز يرميه المستخدم عليها، ويجب أن يكون ReplayGain/EQ اختياريًا. إنه لكل ملف تعريف حتى تتمكن من الاحتفاظ بتحويل الترميز لجهاز Xbox قديم أثناء إرسال الأصلي إلى DAC عالي الدقة.


F04 - "فرض تحويل الترميز" لكل ملف تعريف

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

لماذا: سيكون التبديل العالمي الوحيد متناقضًا مع ForceNativeStream لكل ملف تعريف (F03). حالة واقعية: الجهاز A هو DAC عالي الدقة يريد تدفقات أصلية مثالية للبت؛ الجهاز B هو مستقبل AV قديم يتعثر في FLAC. مع تبديل عالمي، يجب على المستخدم الاختيار - على حساب الجهاز الآخر. مع كل ملف تعريف، يحصل كل جهاز على الإجابة الصحيحة.

التنفيذ:

  • StreamingProfile.ForceTranscoding As Boolean = False.
  • تم رفع مخطط الثبات إلى الإصدار 9. تقوم ملفات ما قبل الإصدار 9 بتحميل القيمة العالمية القديمة مرة واحدة ونسخها إلى جميع الملفات الشخصية، مع الحفاظ على السلوك القديم من خلال الترقية.
  • واجهة المستخدم: تمت إزالته من لوحة التشخيصات، وتمت إضافته إلى قسم ملفات تعريف الجهاز بجانب ForceNativeStream. معالجات استبعاد متبادل ثنائية الاتجاه (CheckedChanged على كل منها يلغي اشتراك الآخر قبل التبديل، لتجنب حلقة لا نهائية).
  • موقع القرار: Settings.ForceTranscodingstreamingProfile.ForceTranscoding في WriteAudioFileDIDL.

F05 - "فرض PCM ذي الترتيب الصغير" لكل ملف تعريف

ماذا: تدفقات PCM (أنواع mime L16/L24) هي ذات ترتيب كبير حسب المواصفات. تتوقع بعض الأجهزة بشكل خاطئ ترتيبًا صغيرًا وتشغل ضوضاء بيضاء عند تزويدها ببيانات ذات ترتيب كبير صحيحة. يقوم F05 بتبديل ترتيب البايت لكل ملف تعريف.

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


F06 - "لا تستخدم PCM الخام" لكل ملف تعريف

ماذا: عندما يدعي الجهاز أنه يدعم PCM الخام، يستخدم المكون الإضافي ذلك. بعض الأجهزة تكذب - تقبل مصافحة SOAP ولكنها تشوه بيانات PCM الخام الفعلية، بينما تتعامل بشكل صحيح مع PCM الملفوف في حاوية WAVE. يفرض F06 PCM-over-Wave بغض النظر عما يعلنه الجهاز.

لماذا: بعض موديلات Marantz على وجه التحديد - تعلن عن PCM الخام ولكن WAVE فقط يعمل. بدون هذا، تخرج تدفقات PCM الخام مشوهة، بدون رسالة خطأ للإشارة إليها.


F07 - "طول المحتوى" لكل ملف تعريف

ماذا: ما هي القيمة التي يجب إرسالها في رأس HTTP Content-Length. أربعة خيارات:

  • افتراضي - عدد البايتات الفعلي عند معرفته، يتم حذفه عند عدم معرفته.
  • لا شيء - لا ترسل الرأس أبدًا (ترميز مقطع فقط).
  • PCM فقط - أرسل فقط لـ PCM الخام؛ احذف لكل شيء آخر.
  • ثابت - أرسل UInt32.MaxValue - 8192 (علامة "طول غير معروف ضخم").

لماذا: تختلف أجهزة UPnP/DLNA بشكل كبير في كيفية تفاعلها مع Content-Length. بعضها يحتاج إلى رقم دقيق، وبعضها يكرهه في التدفقات، وبعضها يحتاج إلى قيمة "كبيرة جدًا" للحفاظ على التخزين المؤقت. تم توسيع هذا لاحقًا من PCM فقط إلى جميع تنسيقات الإخراج لأن نفس المشاكل ظهرت في تدفقات MP3/AAC المحولة.


F08 - "لا تمسح NextURI" لكل ملف تعريف

ماذا: عادةً ما يقوم المكون الإضافي بمسح NextURI المجدول للجهاز عندما تفرغ قائمة الانتظار (إرسال SetNextAVTransportURI بعنوان URL فارغ). تفسر بعض الأجهزة (خاصة Denon) NextURI فارغًا على أنه "أوقف كل شيء" وتوقف التشغيل على الفور. يمنع F08 المكون الإضافي من مسحه أبدًا.

لماذا: بدون هذا، يواجه مالكو Denon انقطاع الجهاز في منتصف المسار عندما تفرغ قائمة الانتظار. مع تحديد F08، يحتفظ الجهاز بـ NextURI القديم في الذاكرة (غير ضار - يتم الكتابة فوقه في المرة التالية التي يتم فيها جدولة شيء ما).


F09 - FLAC كتنسيق إخراج للتحويل

ماذا: تعرض قائمة تنسيقات التحويل المنسدلة في ملفات تعريف الجهاز الآن FLAC جنبًا إلى جنب مع PCM 16/24 و MP3 و AAC و Ogg. يؤدي اختياره إلى توجيه مشفر BASS عبر سطر أوامر تحويل FLAC القياسي في MusicBee (نفس الآلية التي يستخدمها MP3/AAC/Ogg بالفعل).

لماذا: بالنسبة للأجهزة التي تتعامل مع FLAC جيدًا ولكن لا يمكنها فك تشفير برنامج الترميز المصدر (على سبيل المثال، Eversolo يتلقى مكتبة WMA الخاصة بـ MusicBee المحولة إلى FLAC)، يحافظ هذا على جودة بدون فقدان حيث سيتخلص MP3/AAC من بيانات الصوت. يفتح N02 (التحكم في خلط 5.1)، والذي لا يمكن معالجته بدون خيار تحويل بدون فقدان.

التنفيذ: إضافة سطر واحد إلى كتلة Select Case Codec في Encoder.StartEncode - ينضم FLAC إلى MP3/AAC/Ogg في الفرع الذي يعمل بسطر الأوامر. تحصل القائمة المنسدلة لواجهة المستخدم على "FLAC" كخيار سادس. يمتد تعيين التحميل/الحفظ في SettingsDialog للتعرف على FileCodec.FlacSelectedIndex = 5. تم توصيل نوع Mime ونوع DLNA وميزة الترميز بالفعل في ItemManager.GetMimes / GetDlnaType / GetEncodeFeature من عمل سابق (F21، F26).


التشغيل بدون فجوات (SetNextAVTransportURI)

F10 - SetNextAVTransportURI / NextURI الأساسية

ماذا: تشغيل حقيقي بدون فجوات. عندما يعلن الجهاز عن دعمه لـ SetNextAVTransportURI في وصف خدمة UPnP الخاص به، يقوم المكون الإضافي بجدولة المسار التالي مسبقًا على الجهاز قبل انتهاء المسار الحالي. ينتقل الجهاز داخليًا بدون فجوة مسموعة بين المسارات - ما تسمعه على مشغل الأقراص المضغوطة. هذا ليس اختراق "التدفق المستمر" (الذي يربط كل شيء في تدفق واحد طويل ويفقد بيانات التعريف لكل مسار).

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

ملاحظات: يتم تقديم الصوت المجدول عبر خادم HTTP الخاص بالمكون الإضافي باستخدام streamHandle=0 (وضع جلب المكتبة)، مما يعني أن محرك الصوت في MusicBee ليس في الحلقة للمسار المجدول. المقايضة: لا تنطبق تأثيرات ReplayGain/DSP/EQ على المسار التالي. مقبول عندما يكون "فرض دفق أصلي" قيد التشغيل (الافتراضي).


F11 - "تعطيل دعم NextURI" لكل ملف تعريف

ماذا: حتى لو أعلن الجهاز عن SetNextAVTransportURI، فإن مربع الاختيار هذا يجبر المكون الإضافي على تجاهل هذا الإعلان والعودة إلى التشغيل مسارًا واحدًا في كل مرة.

لماذا: تعلن بعض الأجهزة عن NextURI ولكن لديها تطبيق معيب (تعطل، انتقالات نصفية، تعليق). بدلاً من الهندسة العكسية لكل جهاز معطل، يحصل المستخدم على تبديل "فقط أوقفه هنا".


F12 - دورة حياة NextURI في قائمة التشغيل الآن

ماذا: عندما يشغل MusicBee NowPlayingListChanged، يعيد المكون الإضافي تقييم ما يجب جدوله للانتقال بدون فجوات. يطلب من MusicBee المسار "التالي" الجديد عبر NowPlayingList_GetNextIndex(1) + NowPlayingList_GetListFileUrl، ويقارن بما هو مجدول حاليًا على الجهاز (يتم تتبعه عبر حقل nextPlaySourceUrl الجديد)، ويعيد الجدولة إذا تغير (أو يمسح قائمة الانتظار إذا قال MusicBee أنه لا يوجد مسار تالي).

لماذا: بدون F12، استمر الجهاز في تشغيل NextURI قديم عندما أزال المستخدم/أعاد ترتيب المسار المجدول. استغرق هذا تاريخيًا عدة تكرارات لأن كل تغيير في القائمة يحتاج إلى معالجة مختلفة - لقد قمنا بالتبسيط من خلال الثقة في NowPlayingList_GetNextIndex (الذي يحترم بالفعل التبديل والتكرار الشامل)، لذلك تمر جميع المتغيرات عبر نفس المقارنة.

التنفيذ:

  • حقل nextPlaySourceUrl جديد يخزن عنوان URL لمكتبة MusicBee لما هو مجدول (عنوان URL للتدفق مع لاحقة المعرف غير قابل للمقارنة بمسار مكتبة).
  • Public Sub RefreshQueuedNextUri() جديد على MediaRendererDevice. ثلاث نتائج: لا يوجد NextURI مجدول ← لا يوجد تأثير؛ مجدول يطابق "التالي" الجديد ← لا يوجد تأثير؛ مجدول يختلف ← استدعاء QueueNext بعنوان URL الجديد (أو QueueNext("") للمسح - الذي يحترم F08 DoNotClearNextUri).
  • موصل في Plugin.ReceiveNotification تحت NotificationType.NowPlayingListChanged.

F13 - تراجع فشل NextURI

ماذا: بعد 4 حالات فشل متتالية لـ SetNextAVTransportURI على نفس الجهاز، يقوم المكون الإضافي بتعطيل التشغيل بدون فجوات لهذا الجهاز حتى يتم إعادة تشغيل MusicBee.

لماذا: إذا كان الجهاز معطلاً بالفعل لـ NextURI (أخطاء SOAP متقطعة، أعطال شبكة)، فإن المكون الإضافي سيستمر في إعادة المحاولة في كل مسار. يوقف F13 الضوضاء ويعود إلى التشغيل مسارًا واحدًا في كل مرة بصمت.


F14 - وضع التكرار + تكامل NextURI

ماذا: ينقسم F14 إلى حالتين يتم التعامل معهما عند كاشف الانتقال F15 في OnAvTransportStatusCheck:

  • تكرار الكل: يمرر MusicBee عنوان URL "الالتفاف" الصحيح (المسار 1 في نهاية القائمة) إلى Plugin.QueueNext نفسه. لا توجد منطق مكون إضافي خاص مطلوب - ينتقل الجهاز إليه ويستدعي كاشف F15 Player_PlayNextTrack كالمعتاد، والذي يعيد فهرس NPL في MusicBee إلى 0.
  • تكرار واحد: يمرر MusicBee نفس عنوان URL للمسار إلى Plugin.QueueNext. ينتقل الجهاز إليه (معرف دفق جديد، نفس المصدر). يستعلم كاشف F15 الآن عن Player_GetRepeat() - إذا كان RepeatMode.One، فإنه يتخطى استدعاء Player_PlayNextTrack حتى لا يتقدم MusicBee فهرس NPL بعيدًا عن المسار المتكرر.

لماذا: بدون تخطي تكرار واحد، فإن استدعاء Player_PlayNextTrack عند الانتقال بدون فجوات سيقدم MusicBee إلى المسار التالي في القائمة (يؤثر تكرار واحد فقط على سلوك التقدم التلقائي في نهاية المسار في واجهة مستخدم المشغل - Next Track يتحرك دائمًا للأمام)، مما يتناقض مع ما يعنيه تكرار واحد.

تحذير عدد التشغيل: في تكرار واحد، يعتمد زيادة عدد التشغيل على ملاحظة MusicBee 3.7.9563+ للتشغيل المتكرر. إصدارات MusicBee الأقدم تشغل التكرار بدون فجوات بشكل صحيح ولكنها تفوت زيادة عدد التشغيل. موثق؛ لا يمنع.


F15 - آلة حالة اكتشاف انتقال المسار

ماذا: عندما ينتقل الجهاز داخليًا من المسار الحالي إلى NextURI، يحتاج المكون الإضافي إلى ملاحظة ذلك وإخبار MusicBee بتقديم فهرس التشغيل الحالي. وإلا فإن MusicBee يعتقد أنه لا يزال على المسار السابق وتتأخر أعداد التشغيل / واجهة المستخدم / scrobbling عن التزامن.

التنفيذ: يستعلم GetPositionInfo.TrackURI عند كل نبضة مؤقت الحالة. عندما يتطابق URI المبلغ عنه مع الذي قمنا بجدولته عبر NextURI، نستدعي Player_PlayNextTrack على MusicBee ونعين suppressNextSoapCall حتى لا يعيد PlayToDevice الناتج إرسال SetAVTransportURI (مما سيقطع التشغيل بدون فجوات).

لماذا: بدون F15، يشغل الجهاز المسار التالي ولكن واجهة مستخدم MusicBee تقول إنه لا يزال على المسار السابق. مربك، يكسر scrobbling، يكسر تتبع عدد التشغيل. يتطلب اكتشاف انتقال المسار تكرارًا طويلاً لكل عارض لأن كل علامة تجارية للعارض لها غرائبها الخاصة في متى تبلغ عن تغيير URI (بعضها يبلغ عن TRANSITIONING أولاً، وبعضها ينتقل مباشرة إلى PLAYING مع URI جديد، وبعضها لديه STOPPED قصير بينهما).

ملاحظات: يعمل قطعنا الأول على عارض BubbleUPnP. تبقى حالات الحافة لكل جهاز في B6.


F16 - إصلاح صوت الفرقعة عند الانتقال بدون فجوات

ماذا: تحدث الفرقعة عندما يختلف تنسيق المصدر (معدل العينة / القنوات / برنامج الترميز) للمسار المجدول عن المسار الذي يتم تشغيله حاليًا، مما يجبر DAC الخاص بالجهاز على إعادة القفل عند الانتقال. يضيف F16 تشخيصًا NextUri:FormatChange يتم تشغيله في وقت الجدولة كلما اختلفت التنسيقات، مع تسمية كلا الجانبين - حتى يتمكن المستخدمون الذين يسمعون الفرقعات من الربط.

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

لماذا تم تأجيل الإصلاح الفعلي للتحويل للمطابقة: يتطلب الإصلاح الهيكلي (تحويل المسار المجدول لمطابقة تنسيق المسار الذي يتم تشغيله) تغييرات في مخطط URL لخادم HTTP الخاص بالمكون الإضافي - حاليًا /encode/{id}0.{ext} يقدم الملف المجدول أصلاً. سيضيف الإصدار 2 المستقبلي من F16 مسارات /encode/{id}0_{rate}_{depth}.{ext} لكل تنسيق ويوصلها عبر المشفر. هذا تغيير معماري أكبر يستحق القيام به إذا أظهر جهاز حقيقي الفرقعة بعد عدم كفاية ForceTranscoding.

التنفيذ اليوم:

  • يتتبع حقل lastSourceUrl عنوان URL للمصدر الذي يتم تشغيله حاليًا.
  • يقرأ QueueNext FilePropertyType.SampleRate/Channels/Kind لكل من المسارات الحالية والمجدولة ويسجل NextUri:FormatChange عند عدم التطابق.

F17 - إعادة مزامنة شريط التقدم بعد البحث

ماذا: استدعت دالة Seek() بالفعل GetPlayPositionInformation() بعد نجاح Seek SOAP، مما أصلح حالة "لا توجد إعادة مزامنة على الإطلاق". يغلق F17 الانحراف المتبقي الذي يصل إلى ثانية واحدة والذي تسببه كمية RelTime لـ UPnP البالغة ثانية واحدة: عندما يتم تقريب الموضع المبلغ عنه للجهاز إلى ثانية واحدة من الهدف المطلوب للمستخدم، يثق المكون الإضافي الآن بقيمة المستخدم الدقيقة بالمللي ثانية بدلاً من اقتطاع الجهاز. فقط عندما يبلغ الجهاز عن شيء مختلف بشكل كبير (>1 ثانية) نستخدم قيمته (وصل البحث إلى مكان آخر غير المطلوب، على سبيل المثال، الانتقال إلى إطار مفتاح على بعض برامج الترميز).

لماذا: بدون هذا، فإن البحث إلى 2:30.500 المرتبط بتقرير الجهاز "2:30" سيجعل شريط التقدم يظهر متأخرًا بحوالي 500 مللي ثانية عن الواقع. بعد F17، يتطابق الشريط مع نية المستخدم لحالة التمرير الشائعة داخل المسار، ولا يزال يحترم تقرير الجهاز للحالة الشاذة للانتقال إلى إطار مفتاح.


F18 - تداخل التدفق المستمر / NextURI

ماذا: يوجد الآن قفلان متداخلان:

  1. وقت التشغيل: QueueNext يعود مبكرًا False عندما يكون Settings.ContinuousOutput قيد التشغيل. التدفق المستمر هو آلية التشغيل بدون فجوات خاصة به (تدفق واحد طويل متسلسل)؛ إرسال SetNextAVTransportURI فوقه يربك الجهاز حول ما إذا كان كل مسار هو URI منفصل أو جزء من التدفق المستمر.
  2. واجهة المستخدم: عندما يحدد المستخدم مربع اختيار التدفق المستمر العالمي، يتم إلغاء تحديد forceNativeStream للملف الشخصي المعروض حاليًا تلقائيًا. التدفق المستمر يقوم دائمًا بالتحويل، لذا فإن فرض الأصلي لا معنى له في هذا المزيج.

لماذا: يمنع المستخدم من تمكين آليتين متضاربتين للتشغيل بدون فجوات في وقت واحد. بدون F18، سيتلقى الجهاز كلاً من URI للتدفق المستمر و NextURI لكل مسار لاحق، مع سلوك غير محدد يعتمد على العارض.


F19 - تجاهل أخطاء NextURI الفارغة

ماذا: عندما يتم استدعاء SetNextAVTransportURI بعنوان URL فارغ (على سبيل المثال، آخر مسار في القائمة)، تعيد بعض الأجهزة خطأ SOAP. يبتلع F19 هذه الأخطاء بصمت - يتم تسجيلها ولكن لا يتم نشرها كأخطاء.

لماذا: حالة "لا يوجد مسار تالي" طبيعية، وليست خطأ. معاملتها على أنها قاتلة تلوث السجل وتؤدي (في بعض التدفقات) إلى عواصف إعادة المحاولة.


أنواع Mime وبيانات تعريف DLNA

F20 - نوع Mime لـ MP3 ← audio/mpeg

ماذا: نوع Mime لـ MP3 المتوافق مع المعايير هو audio/mpeg، وليس audio/mp3. هذا الأخير هو تسمية خاطئة شائعة تتسامح معها معظم الأجهزة، لكن العارضات الأكثر صرامة ترفضها.

لماذا: يصلح التشغيل بصمت على الأجهزة الأكثر صرامة التي تتبع المعيار. كان رمز yaiol لديه هذا صحيحًا بالفعل؛ لا حاجة للتغيير.


F21 - ترتيب أنواع Mime: المتغير غير x- أولاً

ماذا: عندما يعلن جهاز عن audio/flac و audio/x-flac، يعيد المكون الإضافي المتغير غير x- أولاً. نفس الشيء لأي برنامج ترميز يحتوي على أنواع mime قياسية وتجريبية.

لماذا: تشير البادئة x- إلى أنواع mime التجريبية/غير الرسمية. تتصرف بعض العارضات بشكل أفضل مع النموذج القياسي. إعادة ترتيب صغيرة، تأثير واقعي.


F22 - دعم نوع Mime لـ Opus

ماذا: يتعرف على Opus كبرنامج ترميز صوتي قابل للتدفق؛ يرسل نوع mime audio/opus عند تقديم مسارات Opus.

لماذا: Opus شائع الآن (برنامج ترميز تسوية حديث للكلام/الموسيقى). بدون F22، سيرفض المكون الإضافي دفق ملفات Opus حتى للأجهزة التي تتعامل معها.


F23 - دعم ملفات مصدر Monkey Audio (APE)

ماذا: يتعرف على ملفات .ape كبرنامج ترميز مصدر صالح للتدفق/التحويل.

لماذا: APE هو تنسيق بدون فقدان مع قاعدة مستخدمين متخصصة ولكن مخلصة. إضافته تكلف القليل وتفتح المكتبة لهؤلاء المستخدمين.


F24 - تراجع نوع Mime لـ AAC / ALAC

ماذا: إذا كان الجهاز يدعم AAC أو ALAC ولكنه لا يعلن عنهما صراحة في وصف خدمة UPnP الخاص به، فإن المكون الإضافي يقدمهما على أي حال كحل بديل.

لماذا: نسيت العديد من الأجهزة التي تتعامل مع AAC بشكل جيد إدراجها في ملف XML الخاص بقدراتها. بدون F24، لن يحاول المكون الإضافي حتى، مما يفرض التحويل. مع F24، يحاول المكون الإضافي ويسمح للجهاز بالتعامل معه أصلاً إذا كان بإمكانه ذلك.


F25 - علامة نوع DLNA لتدفقات WAV الأصلية + المشفرة

ماذا: يجب أن تتطابق علامة نوع DLNA (معرف ملف تعريف مثل LPCM، WAVE، MP3) مع ما يتلقاه الجهاز. يضمن F25 أن يتم وضع علامة على التدفقات الأصلية وتدفقات WAV المشفرة بشكل صحيح.

لماذا: يؤدي عدم تطابق نوع DLNA إلى رفض بعض الأجهزة للتشغيل تمامًا أو تطبيق برنامج فك التشفير الخاطئ.


F26 - رأس DLNA لملفات FLAC

ماذا: تحصل تدفقات FLAC على معرف ملف تعريف DLNA الصحيح في رؤوسها.

لماذا: بدون ذلك، لا تتعرف بعض الأجهزة التي تدعم FLAC على التدفق على هذا النحو.


F27 - إصلاح حساب معدل البت في بيانات التعريف

ماذا: كان res@bitrate للتدفق المستمر يتم حسابه كـ (sampleRate * channels * bitsPerSample) / 1000 - كيلوبت في الثانية، يختلف بعامل ~125 عن مواصفات UPnP DIDL التي تحدد السمة كـ بايت في الثانية. يقسم الآن على 8 بدلاً من 1000.

لماذا: عرض معدل بت خاطئ على الجهاز - تجميلي على معظم العارضات، لكن بعضها يخصص مخازن مؤقتة للتدفق من القيمة ويتعثر في التدفقات التي تبدو أصغر بحوالي 125 مرة مما هي عليه. كان مسار ملف المصدر غير المستمر لديه هذا صحيحًا بالفعل ((bitrate_kbps * 1000) \ 8 = بايت/ثانية)؛ كان مسار التدفق المستمر فقط خاطئًا.


F28 - إصلاح تنسيق وقت البيانات الوصفية (Marantz)

ماذا: كان res@duration في DIDL منسقًا كـ H:MM:SS (على سبيل المثال 0:03:42). تحدد مواصفات UPnP DIDL التنسيق كـ H+:MM:SS[.F+] - بدقة مع ثواني كسرية اختيارية ولكن موصى بها؛ تتعامل بعض أجهزة Marantz مع النموذج المجرد على أنه غير صالح وتترك عرض مدتها فارغًا. يتم الآن تنسيقه كـ H:MM:SS.fff (على سبيل المثال 0:03:42.000).

لماذا: مشكلة عرض خاصة بعلامة تجارية؛ تنسيق متوافق مع معيار ISO مع ثواني كسرية يصلحها دون التأثير على أي جهاز آخر. مطبق في كلا موقعي إصدار DIDL (مسار ملف المصدر + مسار التدفق المشفر في WriteAudioFileDIDL).

إصلاح إضافي في نفس التمريرة: كان pv:addedTime و pv:lastPlayedTime يستخدمان hh (ساعة 12 ساعة) في سلاسل تنسيق DateTime الخاصة بهما بدلاً من HH (ساعة 24 ساعة). أي مسار تمت إضافته أو تشغيله بين الساعة 13:00 و 23:59 سيتم عرضه بساعة خاطئة (على سبيل المثال 17:42 ← "05:42") على الأجهزة التي تعرض الحقل. يستخدم الآن HH.


F29 - دعم البحث في MP3 المشفر (CBR)

ماذا: تعلن تدفقات MP3 المحولة الآن عن DLNA.ORG_OP=11 (البحث بالبايت والوقت) بدلاً من DLNA.ORG_OP=10 (البحث بالبايت فقط). يمكن للأجهزة التي رفضت سابقًا البحث بالوقت في MP3 المحول الآن تشغيل شريط التقدم/واجهة مستخدم البحث بشكل طبيعي.

لماذا: ينتج محول MusicBee MP3 بمعدل بت ثابت عند الإعداد المسبق HighQuality، لذا فإن تعيين البايت ↔ الوقت خطي - يمكن للجهاز تحويل طلب البحث بالوقت إلى بحث HTTP Range بالبايت بنفسه دون أي دعم من جانب المشفر. الإعلان عن OP=11 يفتح واجهة المستخدم هذه على الجهاز. بدون F29، كان المستخدمون الذين يبحثون داخل MP3 محول إما يتم تجاهل البحث بصمت أو يتم إسقاطهم إلى بداية المسار.

التنفيذ: تمت إعادة هيكلة GetEncodeFeature في ItemManager.vb لكسر If المضمن إلى سلسلة If/ElseIf/Else قابلة للقراءة. يحصل MP3 على OP=11 صراحة؛ تحتفظ برامج الترميز الأخرى غير PCM بـ OP=10. لا يوجد تغيير لـ AAC/FLAC/إلخ. - ستحتاج هذه إلى التحقق الخاص ببرنامج الترميز من CBR-ness الذي لا يضمنه MusicBee.


F30 - معالجة امتداد الملف .mpeg

ماذا: يتم الآن التعرف على الملفات ذات الامتداد .mpeg (والأندر .mpe) كـ FileCodec.Mp3 في GetCodec. قبل F30، كانت تعيد FileCodec.Unknown وتم رفضها بصمت من المكتبة / غير قادرة على أن تكون مصادر تحويل.

لماذا: استخدمت أرشيفات MPEG-1 Layer 3 القديمة أحيانًا .mpeg بدلاً من .mp3 (تسمح المواصفات بكلاهما). عدد قليل من الملفات في مكتبة 300 ألف يكفي للشعور بأن "MusicBee يعرضها ولكن المكون الإضافي لا يفعل" - مربك للمستخدم.


سلوك التشغيل

F31 - تدفقات الراديو تستخدم الوضع المستمر تلقائيًا

ماذا: يقوم WriteAudioFileDIDL الآن بفحص خاصية Kind لعنوان URL المصدر عبر Library_GetFileProperty ويعامل أي ملف ينتهي نوعه بـ "Stream" (يبلغ MusicBee عن "MP3 Stream"، "Internet Stream"، إلخ للراديو) على أنه مستمر بغض النظر عن تبديل Settings.ContinuousOutput العالمي. يتم استخدام فرع DIDL للتدفق المستمر (العنوان: "Continuous Stream"، id="continuousstream"، إخراج PCM/Wave ثابت)؛ يرى الجهاز تدفقًا واحدًا بنمط لا نهائي.

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

النطاق: ينطبق فقط عندما يقوم MusicBee بتشغيل التشغيل (musicBeePlayToMode). مسار جلب المكتبة (عميل UPnP يتصفح) لم يتغير - عناوين URL للراديو هناك نادرة ويجب ألا يتغير سلوك المستخدم دون اختبار صريح.


F32 - تراجع إعلان برنامج الترميز

ماذا: إذا لم يعلن الجهاز عن برامج ترميز معينة (أو لم يتمكن المكون الإضافي من تحليل ملف XML الخاص بقدرات الجهاز)، فإن المكون الإضافي لا يرفض التدفق على الفور. بدلاً من ذلك، يحاول تقديمه ويترك للجهاز اتخاذ القرار.

لماذا: تحتوي العديد من الأجهزة على ملف XML غير مكتمل أو غير قابل للقراءة ولكنها تتعامل مع برنامج الترميز بشكل جيد بالفعل. يتبادل F32 "تخمينًا جيدًا ومحاولة" صغيرة مقابل رفض صريح.


F33 - تحسين مزامنة شريط التقدم

ماذا: يتم بالفعل استقراء الموضع بين الاستطلاعات من مرجع واحد (currentPlayStartTicks)، لذلك يتم تحديث شريط التقدم بسلاسة بمعدل أقل من الثانية. كان مصدر التذبذب المتبقي هو المرجع الأولي لمسار بدأ حديثًا: افترض الرمز السابق position=0 في اللحظة التي لاحظ فيها مؤقت الحالة لأول مرة أن الحالة أصبحت "تشغيل"، ولكن بحلول ذلك الوقت ربما كان الجهاز يعمل لمدة 100-500 مللي ثانية (فاصل زمني واحد للاستطلاع). سيبدأ شريط التقدم في MusicBee عند 0، ثم يقفز للأمام عندما يلحق الواقع.

إصلاح F33: عند الانتقال إلى "تشغيل" لأول مرة على مسار جديد (currentPlayStartTimeEstimated=True)، استدعاء GetPlayPositionInformation() للحصول على الموضع الحالي الفعلي للجهاز، ثم التثبيت على ذلك. يبلغ UPnP عن دقة ثانية واحدة فقط، لذلك لا يزال المرجع مقسمًا، لكنه أقرب بكثير إلى الحقيقة من افتراض 0.

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


F34 - تذبذب شريط التقدم بعد تغيير المسار

ماذا: عند استدعاء PlayToDevice لمسار جديد، كان المكون الإضافي يترك currentPlayPositionMs و currentPlayStartTicks عند قيمهما للمسار السابق لمدة ~100 مللي ثانية بين SOAP-Play وأول استطلاع لمؤقت الحالة يكتشف حالة التشغيل الجديدة. كان شريط التقدم في MusicBee يعرض لفترة وجيزة نهاية المسار السابق، ثم يعود إلى 0، ثم يتسلق. يصفر F34 كلاهما عند دخول PlayToDevice - اللحظة التي نعرف فيها أن تغيير المسار يحدث، قبل أي من عمل SOAP.

لماذا: خلل بصري في حالات الاستخدام السريع للتخطي (التالي اليدوي أو الانتقال بدون فجوات). الآن، يعيد استعلام PlayPositionMs الأول في MusicBee بعد Play 0 بشكل نظيف، ثم يقوم GetPlayPositionInformation في F33 بتحسينه إلى الموضع الفعلي للجهاز عند أول نبضة تغيير حالة.

التنفيذ: أربعة أسطر في الجزء العلوي من PlayToDevice، مقترنة بالتثبيت الدقيق لوقت الانتقال في F33.


F35 - خطأ "فرض تحويل الترميز"

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

  1. الأسبقية مع ForceNativeStream. عندما كان كلاهما True (والذي يمكن أن يحدث عبر ترحيل مخطط أو ملف إعدادات جزئي)، يفوز ForceTranscoding الآن بشكل كامل (If streamingProfile.ForceTranscoding Then forceEncode = True ElseIf streamingProfile.ForceNativeStream Then forceEncode = False). يمنع الاستبعاد المتبادل لواجهة المستخدم المستخدم من تحديد كلاهما، لكن حارس وقت التشغيل يتعامل مع أي حالة تم تحميلها غير متناسقة من القرص.
  2. منطق bypassTranscodeDecision. سابقًا: streamingProfile.ForceNativeStream AndAlso Not Settings.ForceTranscoding. الآن: streamingProfile.ForceNativeStream AndAlso Not streamingProfile.ForceTranscoding - نفس قاعدة الأسبقية ولكن في نفس نطاق كل ملف تعريف.

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


F36 - استثناء إغلاق العارض

ماذا: تم تغليف Plugin.ReceiveNotification في Try/Catch من المستوى الأعلى يسجل أي استثناء غير معالج بدلاً من السماح له بالانتشار مرة أخرى إلى مضخة إشعارات MusicBee.

لماذا: يتم إرسال الإشعارات من MusicBee (PlayStateChanged، VolumeMuteChanged، إلخ) إلى ControlPointManager الذي يتحدث إلى العارض عبر SOAP. تحتوي مواقع الاستدعاء الفردية بالفعل على Try/Catch حول استدعاءات SOAP الخاصة بها، ولكن حالة توقيت غريبة بما فيه الكفاية (على سبيل المثال، موت العارض بين استدعاءين SOAP في نفس معالج الإشعارات) لا يزال من الممكن أن تفلت. الغلاف العلوي هو شبكة الأمان النهائية حتى لا يرى المستخدم أبدًا نافذة منبثقة عامة "TargetInvocationException" من MusicBee.

التنفيذ: تم تغيير اسم الجسم الحالي إلى ReceiveNotificationInternal وتمت إضافة غلاف رفيع ReceiveNotification يقوم بـ Try { ReceiveNotificationInternal(...) } Catch { LogError(...) }. تبقى البنية التحتية Try/Catch الموجودة مسبقًا لكل طريقة داخل ControlPointManager (حول كل استدعاء PostSoapRequest) - F36 هو حزام + حمالات.


F37 - البحث في المسارات الطويلة يؤدي إلى انتقال خاطئ

ماذا: يمكن أن يؤدي البحث داخل مسار طويل إلى دورة قصيرة من Stopped→Playing على بعض العارضات. بدون تمييز، يعامل ProcessNewPlayState.Stopped ذلك على أنه نهاية طبيعية للمسار ويستدعي Player_PlayNextTrack، مما يقدم MusicBee عندما أراد المستخدم فقط التمرير. يختم F37 lastUserInitiatedSeek في Seek() ويضيف حارسًا لمدة 5 ثوانٍ في معالج Stopped (يعكس نافذة lastUserInitiatedStop الموجودة).

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


F38 - تحسين معالجة البحث لبرامج الترميز المعرضة للتعطل

ماذا: كان تعطل BubbleUPnP عند البحث في MP3 هو العرض الكنسي. بعد التدقيق، يقوم رمز البحث الحالي في yaiol بالفعل بالأشياء الصحيحة - المسار الأصلي يتعامل مع HTTP Range بشكل صحيح (206، Content-Range، AcceptRanges)، المسار المشفر يعلن عن X-AvailableSeekRange ويحلل رؤوس timeSeekRange.dlna.org / npt الواردة، تعكس علامات DLNA.ORG_OP قدرات التدفق الفعلية (مع خيار DisablePcmTimeSeek لتعطيل أجهزة Platinum التي بها مشاكل). تم اختباره من قبل المستخدم على BubbleUPnP 4.6.4 الحالي: لم يتم ملاحظة أي تعطل.

لماذا: تم الإبلاغ عن تعطل BubbleUPnP MP3-seek حوالي عام 2024 وقد تلقى التطبيق حوالي 16 شهرًا من الإصلاحات منذ ذلك الحين. كان F29 (MP3 المشفر OP=11) هو المتغير الجديد الذي كان يمكن أن يعيد كشفه؛ لا يفعل ذلك، على الإصدارات المختبرة.

إذا عاد التعطل: سيكون شكل الإصلاح هو تبديل "بحث محدود" لكل ملف تعريف يفرض DLNA.ORG_OP=10 (بايت فقط) على برامج الترميز التي تم وضع علامة عليها - يعكس كيفية عمل DisablePcmTimeSeek بالفعل لـ PCM. أضف ذلك حينئذٍ، وليس بشكل استباقي.


واجهة المستخدم والتسجيل

F39 - زر "إضافة" يحدد الملف الشخصي الجديد

ماذا: يؤدي النقر على "إضافة" في قائمة ملفات تعريف الجهاز إلى إنشاء ملف تعريف جديد وتحديده تلقائيًا حتى يتمكن المستخدم من تحرير الحقول على الفور. يقوم إعادة هيكلة مربع الحوار المقسم لدينا بذلك بالفعل - ينتهي كل من مسار الإضافة المباشر ومسار من القالب بـ Me.activeStreamingProfiles.SelectedIndex = Me.activeStreamingProfiles.Items.Count - 1. أكد الفحص أن فرعنا يتعامل مع هذا بالفعل - لا يوجد شيء لتغييره.

لماذا: مشكلة صغيرة في تجربة المستخدم تبين أنها لم تكن مشكلة هنا بالفعل.


F40 - اتصالات قصوى أكبر + سجل تحذير

ماذا: كان حد التدفق المتزامن للمكون الإضافي (SemaphoreSlim حول Sockets_Stream_File / Sockets_Encoder_Start) ثابتًا عند 4. يجعل F40 قابلاً للتكوين من قبل المستخدم في صفحة الإعدادات العامة (الافتراضي 16، النطاق 1-256)، ويضيف سطر سجل MaxConnections عندما يضطر طلب إلى الانتظار لفتحة، و يعرض شارة ⚠ Max Conn حمراء في أسفل يسار مربع حوار الإعدادات إذا تم الوصول إلى الحد الأقصى مرة واحدة على الأقل منذ بدء تشغيل MusicBee.

لماذا: عندما يطلق جهاز طلبات متوازية (بعض أجهزة Marantz/Linn أثناء مسح الأعمال الفنية، استكشافات بيانات تعريف BubbleUPnP جنبًا إلى جنب مع التشغيل النشط)، يتم حظر الطلبات الإضافية بصمت خلف الإشارة - رأى المستخدم "الجهاز بطيء" بدون سبب مرئي. سطر السجل جيد لتصحيح الأخطاء التقنية ولكن المستخدمين غير التقنيين لا يقرأون السجلات أبدًا. تجعل الشارة المرئية في مربع حوار الإعدادات حالة الوصول إلى الحد الأقصى قابلة للاكتشاف لأي شخص يفتح تفضيلات المكون الإضافي.

التنفيذ:

  • تم مركزة الانتظار في WaitOnSendBarrier(logTag) في MusicBeeUpnp.vb؛ يستخدم كلا موقعي الاستدعاء (MediaServerDevice.GetFile، Encoder.StartEncode) ذلك.
  • Settings.MaxConnections مستمر في الإصدار 8 من مخطط الإعدادات.
  • Plugin.MaxConnectionsHit هي علامة جلسة لاصقة يتم تعيينها داخل WaitOnSendBarrier؛ يتم إعادة تعيينها فقط عند إعادة تشغيل MusicBee.
  • SettingsDialog.maxConnectionsBadge هي تسمية حمراء غامقة عند (16, 410) تظهر فقط عندما يكون Plugin.MaxConnectionsHit صحيحًا. تحتوي على تلميح يشرح السبب والعلاج.
  • يتم تهيئة الإشارة مرة واحدة عند تحميل النوع، لذلك يتطلب تغيير الإعداد إعادة تشغيل MusicBee (ملاحظة في تسمية الحقل).

F41 - سجل "الترميز بسبب ReplayGain/DSP"

ماذا: بدلاً من سطور سجل منفصلة "الترميز لـ RG" / "الترميز لـ DSP"، يتضمن سطر StreamDecision الواحد من F42 MB-DSP/EQ، MB-ReplayGain، Profile-DSP/EQ، Profile-ReplayGain كأسباب متراكمة. نفس القيمة التشخيصية، ضوضاء أقل.

لماذا: يرى المستخدمون جميع الأسباب التي تؤدي إلى تحويل الترميز لمسار معين في سطر سجل واحد، وليس متناثرة. انظر F42 للحصول على التفاصيل الكاملة.


F42 - سجل "العارض لا يدعم برنامج الترميز المصدر"

ماذا: تمت إضافة سطر سجل StreamDecision لكل مسار يتم تشغيله على الجهاز يقول إما "برنامج ترميز أصلي" أو "تحويل ترميز CODEC→CODEC السبب=...". يجمع حقل السبب كل شرط أدى إلى تحويل الترميز: MB-DSP/EQ، MB-ReplayGain، Profile-DSP/EQ، Profile-ReplayGain، WebFile، VirtualFile، ForceTranscoding(global)، SampleRate<min/SampleRate>max، DownmixToStereo، DeviceLacksCodec(X)، BandwidthConstrained.

لماذا: كان المستخدمون مرتبكين بسبب ارتفاعات غير متوقعة في وحدة المعالجة المركزية على الملفات التي توقعوا دفقها أصلاً. يخبرهم سطر سجل واحد لكل مسار بالضبط ما هو الشرط الذي تسبب في تحويل الترميز - وإذا أظهر الحقل DeviceLacksCodec(Flac)، فإنهم يعرفون على الفور أن معلومات بروتوكول الجهاز كانت غير مكتملة وقد يرغبون في تفعيل تراجع F32.

التنفيذ: سلسلة مجمعة واحدة يتم بناؤها بشكل تدريجي عبر سلسلة القرار؛ يتم تسجيلها مرة واحدة في النهاية. يتم التحكم فيها بواسطة Settings.LogDebugInfo لتجنب ضوضاء السجل في الإنتاج.


F43 - سجل SetNextAVTransport يعرض عنوان URL المصدر

ماذا: تتضمن إدخالات سجل QueueNext الآن source=<MusicBee library path> جنبًا إلى جنب مع stream=<HTTP streaming URL>. تم تطبيق نفس التغيير على مسار النجاح ومسار الفشل (QueueNext:Failed).

لماذا: عند تصحيح مشكلة مسار مجدول، يكون عنوان URL للتدفق (/encode/aabbccdd0.flac) مبهمًا بحد ذاته - نفس الشيء لكل مسار. عنوان URL المصدر هو مسار المكتبة القابل للبحث البشري الذي يخبرك بالضبط أي ملف حاول MusicBee جدولته.


F44 - تسجيل أفضل لأخطاء نوع mime

ماذا: إدخالان جديدان في السجل أثناء Activate:

  • Activate:MimeUnverified - يتم تشغيله لكل إدخال مشوه في استجابة GetProtocolInfo للجهاز، مع تسمية الإدخال الذي لم يتمكن من تحليله (حتى يتمكن المستخدم من رؤية على سبيل المثال "أعاد Marantz http-get:*::* لبعض برامج الترميز - القدرة غير مؤكدة، سيتوقع تراجع F32").
  • Activate:NoSinkInfo - يتم تشغيله مرة واحدة إذا لم يرجع الجهاز أي عنصر <Sink> على الإطلاق. يعني أن SupportedMimeTypes يبقى Nothing وتتدهور IsCodecSupported إلى "افترض أن كل شيء يعمل" - سياق مفيد عندما تظهر أخطاء "الجهاز رفض التدفق" لاحقًا.

لماذا: قبل F44، تركت هذه التراجعات الصامتة في القدرات المستخدمين يتساءلون لماذا تم تحويل مساراتهم ضد التوقعات أو رفضها من قبل الجهاز. الآن، يظهر بحث واحد عن Activate: ما إذا كانت معلومات قدرة الجهاز قابلة للاستخدام.


F45 - تسجيل أفضل لأخطاء البيانات الوصفية

ماذا: تم إثراء سجل استثناء Browse في ContentDirectoryService.vb بالفعل في عمل yaiol السابق (جلسة خطأ Alia Vox) بـ ObjectID وتتبع المكدس. يوسع F45 ذلك بشكل أكبر بـ BrowseFlag (بيانات تعريف مقابل أطفال)، Filter (أي السمات التي طلبها العميل)، sortCriteria، و partialResultLength (كم بايت من DIDL تم إنتاجها قبل الفشل - يشير إلى مدى تقدم المسار السيئ في الدفعة).

لماذا: عندما يحدث خطأ ما في منتصف DIDL، تخبرك قيمة الطول الجزئي ما إذا كان الفشل في المسار الأول من الدفعة (جزئي=0) أو في منتصفها (جزئي=N) - بالاشتراك مع startingIndex للدفعة، يمكنك تحديد فهرس المسار المخالف. يشرح Filter و BrowseFlag أي نوع من التصفح أراده العميل؛ أحيانًا يفشل تصفح البيانات الوصفية فقط حيث ينجح تصفح الأطفال لنفس المعرف.


الشبكات

F46 - الوضع التلقائي يعلن فقط على محولات الشبكة الحقيقية

ماذا: في وضع الواجهة التلقائي، كان المكون الإضافي يعلن عن نفسه (SSDP) على كل محول IPv4 عامل. على جهاز يشغل أيضًا نفق VPN (NordLynx) أو مفتاحًا افتراضيًا (Hyper-V / WSL / Docker)، تم الإعلان عن نفس المكتبة على كل من هذه المحولات أيضًا، لذلك اكتشفت نقطة التحكم التي تبث منها الخادم مرتين أو ثلاث مرات وأدرجت المكتبة كنسخ مكررة. يحتفظ الوضع التلقائي الآن فقط بالمحولات التي تحتوي على بوابة افتراضية IPv4 حقيقية (HasIPv4Gateway) - والتي لا تحتوي عليها محولات النفق والمفتاح الافتراضي - لذلك يتم إسقاطها من قائمة الإعلان. لا يزال العنوان المثبت من قبل المستخدم يفوز بشكل كامل (يعلن على تلك الواجهة فقط)، وإذا لم يبلغ أي محول عن بوابة، يعود المحدد إلى كل محول، لذلك لا تكون قائمة العناوين المعلن عنها فارغة أبدًا ولا يمكن أن يصبح المكون الإضافي غير مرئي.

لماذا: لا يحدث التكرار بسبب "الوجود على VPN" - بل يحدث بسبب الإعلان على محول LAN ومحول النفق/الافتراضي في نفس الوقت، لذلك ترى نقطة تحكم واحدة نفس الخادم على عنوانين. نفق VPN للمستهلك (NordVPN/NordLynx) حركة المرور المتجهة إلى الإنترنت فقط؛ يعيش عارض DLNA على LAN وتتجاوز حركة المرور للشبكة الفرعية المحلية النفق، لذلك لا يصل محول النفق أبدًا إلى عارض على أي حال - إسقاطه يزيل نسخة وهمية، وليس مسار عمل أبدًا. اختبار البوابة هو الإشارة الرخيصة والموثوقة التي تفصل محول LAN/Wi-Fi حقيقي عن نفق أو مفتاح افتراضي. يكمل N05 (الذي أصلح كيفية إرسال الإعلانات على هذه الروابط - البث المتعدد بدلاً من البث)؛ يحكم F46 أي المحولات التي يتم الإعلان عنها على الإطلاق.

حد معروف: شبكة VPN شبكية / وصول عن بعد (Tailscale، ZeroTier، WireGuard-to-home) التي تعيش عارضاتها حقًا عبر النفق عادة ما تقدم محولًا بدون بوابة افتراضية، لذلك يسقطها الوضع التلقائي أيضًا. يقوم هؤلاء المستخدمون بتثبيت عنوان VPN بدلاً من ذلك، والذي له الأسبقية على مرشح البوابة.

المحتويات