MusicBee UPnP Plugin Yardım

Yenilikler

2.0.2 - 2026-07-20

  • Bir şablon, herhangi bir düğüm onu takip ederken artık silinemez — silme düğmesi devre dışı kalır, böylece bir düğüm asla yetim kalmaz. Her şablon satırı artık takipçilerinin canlı (n) sayısını gösterir, bu da devre dışı bir silme işlemini bir bakışta açıklar; kullanılmayan bir şablonu silmek de artık kalıcıdır, bir sonraki yüklemede varsayılanların sessizce yeniden görünmesi yerine.
  • Görünüm ağacının yanındaki yeni bir filtre düğmesi, bir şablonu hangi düğümlerin takip ettiğini tam olarak gösterir: ağacı yalnızca seçilen şablonun takipçilerine göre filtreler, siz diğer şablonları seçtikçe yeniden filtreler ve kapatıldığında tam ağacı geri yükler.
  • Radyo ve Podcast'ler düğümleri artık kategorilerinin şablonuyla kalıcı olarak eşleştirilmiştir — Yollar sekmesinde şablonu yeniden şekillendirin ve düğüm kendiliğinden takip eder; uygulanacak hiçbir şey yoktur, bu nedenle Uygula düğmesi onlar için devre dışıdır. Şablon listesi bunu iki bantla yansıtır: Standart (tüm yeni şablonların oluşturulduğu yer) ve Ayrılmış (Radyo + Podcast'ler).

2.0.1 - 2026-07-20

  • Yol şablonları artık onları kullanan düğümlere canlı olarak bağlıdır. Bir şablonu uygulamak, düğümün onu takip etmesini sağlar: şablonu daha sonra düzenlediğinizde, onu takip eden her düğüm anında yeniden şekillenir — tek tek düğümleri bulup yeniden uygulamanıza gerek kalmaz. Görünüm ağacı, her düğümün adının hemen ardından hangi şablonu takip ettiğini gösterir, bir yeniden adlandırma anında orada görünür ve bir şablonu silmek size önce kaç düğümün onu takip ettiğini söyler (mevcut düzenlerini korurlar ve sadece hiçbir şeyi takip etmeyi bırakırlar).
  • Gizli bir düğüme şablon uygulamak, onu tekrar görünür hale getirir — uygulamak "bunu bana böyle şekillendirilmiş göster" hareketidir, gizlemek ise Görünür onay kutusuyla kalır. Bunun yerini alan ayrılmış "Gizli" şablonu kaldırılmıştır.
  • Görünüm ağacı artık yerinizi kaybetmiyor: işaretler, genişletilmiş klasörler ve kaydırma konumu, şablonları uygulamadan ve diğer yenilemelerden sonra da korunur.

2.0.0 - 2026-06-16

MusicBee UPnP eklentisinin açık kaynaklı yaiol çatalının ilk genel sürümüdür. İki bölüm halinde sunulmuştur: bu çatal için yeni olan her şey, ardından orijinal eklentide yapılan düzeltmeler ve iyileştirmeler. Her öğe, projenin dahili özellik kataloğunun Ne / Neden biçimini korur, böylece her değişikliğin arkasındaki mantık, sadece değişiklik değil, sayfada yer alır.

Bu çatalda yeni

MediaRenderer - MusicBee'ye oynat

N01 - MusicBee, oynatma hedefi olarak

Ne: normalde bu eklenti tek yönlü çalışır: bir telefon veya başka bir cihaz MusicBee'nin kitaplığına göz atar ve müziği kendi üzerinde çalar. Bu özellik ters yönü ekler - MusicBee'nin oynatıcı olmasını sağlar. Telefonunuzdaki bir kontrol uygulamasından (BubbleUPnP gibi) masaüstü MusicBee'nizi oynatacak şey olarak seçebilir, ardından elinizden kontrol edebilirsiniz: oynat, duraklat, durdur, ileri veya geri atla, parçanın bir noktasına atla ve sesi değiştir veya sessize al.

Neden: telefonunuzu PC'nizdeki müziğin bir uzaktan kumandasına dönüştürür. Kanepede oturun, telefonunuzdan kitaplığınıza göz atın, bir parçaya dokunun ve masaüstünüze bağlı hoparlörlerden gelir - oturduğunuz yerden tam kontrolle. Orijinal eklenti bunu hiçbir zaman çalışan bir özellik olarak sunmadı.

Açma: varsayılan olarak kapalıdır, çünkü açmak, ev ağınızdaki herhangi bir şeyin PC'nizde oynatmaya başlamasına izin verir. Ayarlar iletişim kutusunun Genel sekmesindeki bir onay kutusuyla etkinleştirirsiniz. Eklentinin üç rolünün her birinin orada kendi onay kutusu vardır - kitaplığımı paylaş (Sunucu), başkalarının bana oynatmasına izin ver (Oynatıcı) ve diğer cihazlara oynat (Kontrol Noktası) - ve iletişim kutusu yalnızca açtığınız rollerin gerçekten ihtiyaç duyduğu ayar sekmelerini gösterir, bu nedenle size uygulanmayan seçeneklerle asla karşılaşmazsınız.

Makinelerinizi ayırt etme: oynatıcıya istediğiniz adı verebilirsiniz (varsayılan olarak "MusicBee (yaiol)" olarak başlar). Bu ad, telefonunuzun oynatma hedefleri listesinde görünür, böylece birden fazla PC MusicBee çalıştırıyorsa hangisinin hangisi olduğunu anlayabilirsiniz. Bir ad değişikliği hemen, yeniden başlatmaya gerek kalmadan yürürlüğe girer.

Kendi kendine oynatırken mümkün olan en iyi ses: telefonunuzdan MusicBee'nin kendi kitaplığına göz attığınızda ve bir parçayı aynı MusicBee'ye geri gönderdiğinizde, eklenti kendi dosyalarından birini çalmasının istendiğini tanır ve doğrudan diskinizden çalar. Sonuç, sesi gereksiz yere ağa ve doğrudan kendine geri itmek yerine, MusicBee'nin kendi ekolayzırı ve ses seviyesi dengelemesi uygulanmış, tam ve anlıktır - bit-perfect.

Özel olarak çalıştırma: üç rol bağımsız çalışır, bu nedenle kitaplık paylaşımını kapalı bırakırken oynatıcıyı açabilirsiniz. Bu "yalnızca oynatıcı" kurulumunda kitaplığınız ağdan tamamen gizli kalır - yalnızca oynatma hedefi duyurulur - ve MusicBee asla kendi kendine oynatmayı teklif etmez.


Oynatma davranışı

N02 - 5.1 FLAC otomatik olarak downmix edilmedi

Ne: MediaServerDevice.GetEncodedFile içindeki kanal sayısı kısıtlaması If StereoOnly OrElse Not isPcmData Then channelCount = 2 idi. Not isPcmData maddesi, kaynak kanal sayısından bağımsız olarak her PCM olmayan dönüştürmeyi (FLAC, MP3, AAC, Ogg) sessizce stereo'ya downmix ediyordu, kaynak 5.1 FLAC olduğunda 5.1 özellikli oynatıcıları etkisiz hale getiriyordu. Şimdi ikinci madde FLAC'ı hariç tutuyor: Not isPcmData AndAlso encoder.Codec <> FileCodec.Flac. FLAC 5.1 geçiyor; MP3/AAC/Ogg hala stereo'ya zorlanıyor çünkü MusicBee'nin bu formatlar için komut satırı kodlayıcıları 2 kanallı giriş bekliyor.

Neden: 5.1 FLAC kaynağını FLAC çıktısına dönüştürmenin tüm amacı, çok kanallı karışımı korumaktır. Sessiz downmix, FLAC dönüştürme seçeneğini surround dinleme için işe yaramaz hale getiriyordu. N02 ile doğru şeyi yapıyor.


Mimari

Çatalı büyük bir kitaplıkta uygulanabilir kılan yapısal değişiklik - orijinal eklentide yoktu.

N03 - Tembel (isteğe bağlı) göz atma ağacı

Ne: orijinal eklenti, HTTP portunu açmadan önce MusicBee başlangıcında tüm göz atma ağacını oluşturuyordu - her parçayı numaralandır, dosya başına tam Library_GetFileTags, tüm kapsayıcı hiyerarşisini birleştir. Gerçek bir kitaplıkta (50 binden fazla parça, 5400 podcast bölümü, yüzlerce istasyon) bu, dakikalarca süren soğuk başlangıç demektir ve ağaç, hiçbir istemcinin asla açmadığı dallar dahil olmak üzere sonsuza kadar RAM'de kalır. Bu çatal önceden hiçbir şey oluşturmaz: kök, uç nokta başına bir L: ön ekli yer tutucu (L:music, L:podcast, L:filter:…) gösterir; her seviye yalnızca bir istemci ona göz attığında hesaplanır (LazyBrowseEnsureLazyEndpointInMemory → seviye başına önbellekler) ve kitaplık değişikliği bildirimleri önbellekleri temizler (SetLibraryDirty).

Neden: soğuk başlangıç esasen anlıktır - MusicBee eklenti başlatmayı bitirdiğinde HTTP portu açıktır - ve bellek, kitaplık boyutuna değil, göz atılanlara orantılı kalır. Takas: bir uç noktaya ilk göz atma yük maliyetini öder; yeniden giriş, bir sonraki kitaplık değişikliğine kadar önbelleğe alınır. Bu, diğer her şeyin bağlı olduğu temeldir. Tam notlar: FIXES.md.


Ağ ve sağlamlık

HTTP sunucusunun bağlama yolunu güçlendirme. Orijinal eklenti, portu kullanılamadığında sessizce ölür.

N04 - Kendini onaran HTTP portu bağlama

Ne: eklentinin HTTP sunucusu, yapılandırılmış portu kullanılamadığında artık ölmez. Üç bağlantılı değişiklik:

  1. Bağlama hatasında otomatik geri dönüş. HttpServer.Start, yapılandırılmış portu dener ve SocketException durumunda, ilk boş portu bulmak için 20 porta kadar yukarı doğru tarar. Gerçek bağlı port yeni bir Plugin.boundServerPort içinde kaydedilir ve sunucuyu duyuran her şey - SSDP LOCATION URL'leri (NOTIFY + M-SEARCH yanıtı), cihaz URL'si (PrimaryHostUrl), yönlendirici port yönlendirmesi ve SSDP/kontrol noktası kendi kendine filtreleri - artık Settings.ServerPort yerine boundServerPort okur. UPnP istemcileri SSDP aracılığıyla gerçek portu keşfeder, bu nedenle taşınan bir port oynatıcılar için şeffaftır.
  2. Kullanıcı bildirimi. Bir geri dönüş olduğunda (kaydedilen port kullanılan port değilse), yerelleştirilmiş bir MessageBox (WarnPortInUse), kullanıcıya hangi portun gerçekten hizmet verdiğini ve cihazların hala onu bulacağını söyler - çünkü eklenti başsız çalışır ve iletişim kutusu içi bir mesaj yalnızca zaten bir sorundan şüphelenen biri tarafından görülürdü.
  3. Yeniden başlatma kurtarma. RestartServer (ayarlar kaydetme yeniden başlatma yolu), Plugin.controller / Plugin.server'ı körü körüne referanssızlaştırıyordu. Başlangıç Initialise onları oluşturmadan önce bir hata attıysa (başarısız bir bağlamanın tam olarak neden olduğu şey), bir sonraki ayarlar kaydetme bir NullReferenceException ile karşılaşıyordu - yarı ölü bir eklenti bırakıyordu. Şimdi Nothing olduğunda onları yeniden oluşturur ve başlatır, böylece çalışan bir portu kaydetmek, tam bir MusicBee yeniden başlatması olmadan eklentiyi canlandırır.

Neden: tetikleyici gerçek bir kullanıcı olayıydı. Eski varsayılan port 49382, Windows'un dinamik aralığında (49152-65535) yer alır; burada Hyper-V/WSL2/Docker/WinNAT, her önyüklemede değişen büyük bloklar ayırır - bu nedenle aylarca çalıştığı bir makinede WSAEACCES ("erişim yasak") ile bağlama başarısız oldu. Varsayılanı boş bir porta değiştirmek daha sonra Serviio (yeni portta zaten ayrı bir DLNA sunucusu) ile çakıştı ve WSAEADDRINUSE ile başarısız oldu. Her hata Initialise içinde yutuldu, eklentiyi sessizce ölü bıraktı ve ardından bir sonraki ayarlar kaydetmede NRE'ye neden oldu. N04'ten sonra bir port çakışması kendini onarır - sunucu bir sonraki boş portta çalışmaya devam eder, kullanıcıya bildirilir ve istemciler onu yeniden keşfeder - tüm eklentiyi çökertmek yerine.

Uygulama:

  • Varsayılan port 493829779 (dinamik aralığın altında, bu nedenle Windows asla otomatik olarak ayırmaz; bilinen bir medya sunucusu varsayılanı değil) üç ServerPort bildiriminde + ayarlar ayrıştırma hatası geri dönüşünde taşındı.
  • Plugin.boundServerPort (yeni paylaşılan alan) canlı dinleme portunu tutar; activeServerPort, "Yeniden Başlatma Gerekli" rozet mantığının bir geri dönüşte yanlış tetiklenmemesi için yapılandırılmış anlık görüntüyü tutar.
  • HttpServer.PortScanRange = 20; tarama, ilk başarılı TcpListener.Start() çağrısında durur ve tüm denemeler başarısız olursa yalnızca son istisnayı atar.
  • Yeni EN kaynak anahtarı WarnPortInUse (çeviriler yayın zamanı yerel ayar geçişini takip eder).

N05 - Çok noktaya yayın grubu üzerinden SSDP duyuruları (VPN / noktadan noktaya)

Ne: SSDP duyuruları, bir IP yayın adresine değil, UPnP çok noktaya yayın grubuna (239.255.255.250) gönderilir. Bir SSDP arama yanıtı bir sunucu yeniden başlatmasıyla çakıştığında günlüğe kaydedilen zararsız "atılmış bir nesneye erişilemiyor" hatası da bastırılır.

Neden: noktadan noktaya / VPN ağ bağdaştırıcılarında, IP yayını geçerli değildir - eski yayın gönderme "geçersiz argüman" ile başarısız oldu ve duyurular kaçırıldı, bu nedenle eklenti bu bağlantılardaki istemciler için görünmezdi. Doğru çok noktaya yayın grubuna duyuru yapmak, tam olarak bu bağdaştırıcılarda keşfi düzeltir.

Kitaplık navigasyonu

Bunlar bu çatalda gönderildi ve orijinal eklentide yok. Gerçek UPnP istemcilerinden eklentinin kendi çıktısına göz atarak ortaya çıktılar.

N06 - Filtre tabanlı kitaplık gösterimi

Ne: MusicBee'nin filtre sekmeleri (kullanıcının MusicBee klasöründeki .xautopf dosyaları), eklentinin kitaplığında UPnP kök kapsayıcıları haline gelir. Her filtrenin parçaları daha sonra AlbumArtistSort → Album → Tracks hiyerarşisinde göz atılabilir.

Neden: düzenlenmiş MusicBee filtreleri olan kullanıcılar (örn. "5 yıldızlı parçalar", "Son eklenenler", "Klasik → Barok"), bir UPnP istemcisinden eklentiye göz atarken bunları bulmayı beklerler. Orijinal eklenti yalnızca ham kitaplık ağacını gösteriyordu.


N07 - SortAlbumArtist alanı kablolaması

Ne: eklenti artık MusicBee'nin MetaDataType 165 (Albüm Sanatçısı Sıralama) okur ve göz atma görünümlerinde sanatçıları gruplamak/sıralamak için kullanır.

Neden: hi-fi tarayıcılar ve odyofiller, kitaplıkları düzenlemek için sıralama sanatçı adlarını ("Ludwig van Beethoven" yerine "Beethoven, Ludwig van") kullanır. Ciddi dinleyiciler için standart beklenti. Her iki yukarı akışta da eksik.


N08 - Çok değerli Albüm Sanatçısı işleme

Ne: bir albümün AlbumArtist alanı "; " ile ayrılmış birden fazla sanatçı içerdiğinde (örn. "yaiol; Ars Ricercata"), parça artık adları birleştiren tek bir Frankenstein sanatçısı altında değil, göz atma görünümlerinde her sanatçı altında görünür.

Neden: işbirliği albümleri ve derlemeler, her işbirlikçi altında yüzeye çıkmalıdır. Bu olmadan, albümü bulmak için arama yollarının yarısı bozuktur.


N09 - Albüm kapsayıcı resmi (upnp:albumArtURI)

Ne: DIDL Göz At yanıtlarındaki albüm kapsayıcı düğümleri artık albüm kapağını işaret eden bir upnp:albumArtURI öğesi içerir.

Neden: bu olmadan, bir UPnP istemcisinin göz atma görünümündeki her albüm, albüm kapağı yerine genel bir simge gösterir. Navigasyon için görsel ipucu; her modern hi-fi tarayıcı tarafından beklenir.


N10 - Filtre albümleri içindeki parça sıralaması

Ne: filtreyle gösterilen bir albüm içindeki parçalar artık Disk Numarasına, ardından Parça Numarasına göre sıralanır.

Neden: standart albüm sırası. Açık sıralama olmadan, parçalar filtrenin onları döndürdüğü herhangi bir sırada geri geliyordu - genellikle rastgele görünüyordu.


N11 - Çalma listesi klasör ağacı düzeltmesi

Ne: LoadLibraryPlaylists işlevi (başlangıçta Steven Mayall tarafından, ~2014), yeni oluşturulan çalma listesi klasörlerine inemiyordu. Her klasördeki ilk çalma listesi, artı herhangi bir alt klasör, kök seviyesinde yetim kalıyordu.

Neden: orijinal eklentide on bir yıldır mevcuttu. BubbleUPnP'yi açıp Çalma Listeleri'ne tıkladıktan sonra 30 saniye içinde görünür. Ağaç oluşturma sırasında yeni oluşturulan klasörlere doğru şekilde özyinelemeli olarak inerek yaiol'da düzeltildi.


N12 - XML-yasadışı kontrol karakteri temizliği

Ne: C0 kontrol karakteri (örn. kötü bir kodlama geçişinden 0x19 - UTF-8 → Latin-1 → 0x99'u 0x19'a geri kesme) içeren bir etikete sahip herhangi bir parça, kötü parça sayfalandırılmış bir partiye girdiğinde tüm Göz At yanıtının Action Failed ile başarısız olmasına neden oluyordu.

Neden: XML 1.0 çoğu C0 kontrol karakterini yasaklar ve XmlWriter herhangi birini yazması istendiğinde hata verir. Orijinal eklentide mevcuttu. XmlConvert.IsXmlChar aracılığıyla her Library_GetFileTags çıkış noktasında geçersiz karakterleri kaldırarak düzeltildi.


N13 - Sayfalandırılmış Göz At'ta radyo listeleme deterministik

Ne: Radyo kapsayıcısı için Göz At, her çağrıda files.Sort(AlbumFileComparer) çağrısı yapan genel dosya listesi dalına düşüyordu. Radyo girişlerinin boş Albüm/Disk/Parça etiketleri vardır, bu nedenle her karşılaştırma 0 döndürüyordu - List(Of T).Sort kararsızdır, her çağrıda farklı bir sıra üretir. UPnP kontrol noktaları sayfalandırır (BubbleUPnP 0..15'i sonra 16..sonu getirir); iki çağrı arasında liste yeniden düzenleniyordu, bu nedenle bazı istasyonlar her iki sayfada da görünüyordu (yinelenenler) ve bazıları hiçbirinde görünmüyordu (eksik) - her yenilemede rastgele görünüyordu.

Neden: orijinal eklentide mevcuttu (yazarı UPnP aracılığıyla radyoya asla göz atmaz). Burada Browse içinde özel bir ContainerCategory.Radio dalı ile düzeltildi, çağrı başına sıralama yok; radioFiles yükleme zamanında Başlığa göre bir kez sıralanır (kararlı). Sayfalandırılmış göz atma artık deterministik bir sıra görür; sayfa 1 ve sayfa 2 ayrılmıştır.


N14 - UPnP Arama albüm sınıfı albüm kapsayıcılarını döndürür

Ne: albüm sınıfı sorguları için UPnP Arama (upnp:class = "object.container.album.musicAlbum", örn. BubbleUPnP'nin "Rastgele Albümler") albüm kapsayıcıları yerine tam parça listesini döndürüyordu, bu nedenle istemci sıfır albüm gösteriyordu. Orijinal işleyici yalnızca parantez içindeki kriterleri ayrıştırıyor, ardından istenen sınıftan bağımsız olarak tüm parçaları boşaltıyordu.

Neden: burada düzeltildi - albüm sınıfı sorguları artık farklı albümleri numaralandırır (Albüm Sanatçısı+Albüm'e göre gruplandırılmış) ve her birini kapak resmiyle uygun bir musicAlbum kapsayıcısı olarak yayar, Salb<idx> sanal kimlik alanı aracılığıyla adreslenebilir, böylece istemci bir sonuca inebilir ve oynatabilir.


N15 - Tıklanabilir, kapsam duyarlı UPnP araması

Ne: orijinal, arama yetenekleri reklamı yapmıyordu (GetSearchCapabilities boş döndürüyordu), bu nedenle istemciler arama bile göndermeyi reddediyordu; ve eski arka uç, tembel ağaç çağında kalıcı olarak boş olan musicFiles'tan okuyordu. Bu çatal, gerçek aranabilir özellikleri duyurur, tembel kitaplığa karşı başlığa göre parçaları ve başlığa göre albümleri uygular (HandleLazySearch), gerçek bir kapsayıcı kimliği gönderildiğinde sorguyu istemcinin mevcut dalına sınırlar (aksi takdirde L:music yerine geçer, böylece üst çubuk aramaları podcast/radyo/sesli kitap gürültüsünü içeri çekmez) ve bir Browse erken dalının albümün parçalarına geri eşlediği sentetik Ssrch_alb_* kimlikleri aracılığıyla albüm sonuçlarını tıklanabilir hale getirir. (Albüm sınıfı sonuçlarının kapsayıcı olarak gösterilmesi N14'tür.)

Neden: BubbleUPnP'deki arama, "Kitaplık aramayı desteklemiyor" durumundan, kullanışlı, kapsamlı, oynatılabilir sonuçlar döndürmeye geçti. Tam tasarım + reddedilen yaklaşımlar: SEARCH.md.


N16 - UPnP önbellek geçersiz kılma (SystemUpdateID)

Ne: orijinal, sabit bir SystemUpdateID=0 döndürüyordu - UPnP ContentDirectory önbellek geçersiz kılma sözleşmesi - bu nedenle spesifikasyona uygun istemciler (BubbleUPnP) kitaplığı hiç değişmeyen olarak ele alıyordu: eski göz atma sonuçları, URL şeması değişikliğinden sonra 404 küçük resimler ve "değişiklikleri görmek için MusicBee'yi iki kez yeniden başlat" dansı. Bu çatal, yüklemede SystemUpdateID'yi epoch-saniyelerinden besler (böylece her yeniden başlatma kesinlikle sonuncusunun önündedir) ve her kitaplık mutasyonu ve ayar değişikliğinde onu artırır (SetLibraryDirty / ResetCacheBumpSystemUpdateId).

Neden: istemciler, bir sonraki göz atmalarında düzenlemeleri, yeni dosyaları ve ayar değişikliklerini güvenilir bir şekilde alır. Bilinen sınırlama: abone olan istemcilere GENA aracılığıyla yeni değer aktif olarak yeniden itilmez (gelecekteki çalışma olarak park edildi); yine de bir sonraki göz atmalarında görürler.


N17 - Podcast abonelik resmi

Ne: podcast kutucukları resim göstermiyordu - her /PodcastThumbnail/ isteği 404 hatası veriyordu. İki yığılmış hata: çözüm zinciri MusicBee'nin gerçek resim önbelleğini (%LocalAppData%\MusicBee\InternalCache\Subscriptions\<name>.jpg, masaüstü UI'nin yüklendiği yer) asla kontrol etmiyordu ve HTTP katmanının unescape+küçük harf işlemi, besleme URL'si rota anahtarını son yol segmentine kadar bozuyordu. Bu çatal, MB'nin InternalCache'inden resimleri çözer ve HTTP katmanını sağlam bir şekilde atlatan URL güvenli bir slug aracılığıyla aramaları yönlendirir (PodcastSlug / podcastSubIdBySlug).

Neden: abonelik resmi artık göz atma görünümlerinde işleniyor (önceden 404 hatası veren 22 isteğin tümü çözülüyor).


N18 - Hiyerarşik (sınırlı) etiket taraması

Ne: herhangi bir alan Kitaplık Seçenekleri sekmesinde hiyerarşik olarak işaretlenebilir ve tek karakterli bir sınırlayıcı verilebilir (ekle/kaldır ile bir alan seçici + sınırlayıcı kutusu, eklenti ayarlarında kalıcı). Gruplandırma/ ve Jazz/Cool Jazz gibi bir değer ayarlayın, ardından tek bir düz giriş yerine Jazz › Cool Jazz olarak göz atılır. Tam olarak bir dalda etiketlenmiş parçalar (sadece Jazz) kendi [Jazz] düğümünü alır, böylece hiçbir şey gizlenmez, tek bir çocuğu olan bir dal kendi kendine çöker ve ; sınırlayıcı olarak reddedilir çünkü MusicBee'nin kendi çok değerli ayırıcısıdır.

Neden: bir kullanıcının tek bir alana zaten kodladığı derin etiket taksonomileri (tür ağaçları, ruh hali hiyerarşileri, "Klasik/Barok/Konçerto") nihayet etiketin tanımladığı ağaç olarak göz atılır, kullanıcının baştan sona okuması gereken düz bir eğik çizgiyle ayrılmış dizeler duvarı yerine.


N19 - Gruplandırma alanına göre etiketlenmiş tek kök yolu

Ne: kökteki tek bir göz atma yolu, tam kısa yolu yerine gruplandırma alanına göre (örn. "Tür") etiketlenir, birleştirilmiş ilk alan gruplarının adlandırılma şekliyle eşleşir.

Neden: göz atma ağacı tutarlı bir şekilde okunur - bir kök girişinin tek başına durup durmadığı veya kardeşleriyle birleştirilip birleştirilmediği fark etmeksizin tek bir adlandırma kuralı (N20) - birleştirilmiş komşuları temiz bir alan adı gösterirken, yalnız bir kök girişinin ayrıntılı bir dahili yol göstermesi yerine.


N20 - İlk alanı paylaşan göz atma yollarını birleştir

Ne: aynı ilk alanı paylaşan iki göz atma yolu - "Tür / Albüm Sanatçısı Sıralama" ve "Tür / Podcast Kişileri" - tür değerlerini önce listeleyen ve ardından iki görünüme ayrılan tek bir Tür kök klasörüne çöker, kökte yan yana iki neredeyse aynı "Tür / ..." girişi yerine.

Neden: ortak bir alan altında iç içe geçmiş birkaç ilgili görünümü olan bir kullanıcı, kökün neredeyse aynı üst düzey girişlerle dolu olduğunu görüyordu. Bunları birleştirmek, kökü okunabilir tutar ve ilgili görünümleri ait oldukları yere - paylaşılan alanlarının altına - gruplandırır.


N21 - Kategoriye göre göz atma yolları (Standart / Radyo / Podcast)

Ne: her göz atma yolu kategoriye göre yazılır - Standart, Radyo veya Podcast. Şablon listesi bu üç bölüme ayrılır, her şablonun alan seçicisi yalnızca o kategorinin verilerinin gerçekten sağlayabileceği alanları sunar ve bir şablon yalnızca Görünüm ağacındaki eşleşen düğümlere uygulanabilir (uyumsuz düğümler grileşir ve işaretlenemez). Ayrılmış Radyo ve Podcast şablonları silinemez, bu nedenle kategori bölümleri asla kaybolmaz.

Neden: yazma olmadan bir kullanıcı sessizce boş çıkan bir düzen oluşturabilirdi - bir radyo istasyonunun "albümü" yoktur, bir podcast bölümünün "albüm sanatçısı" yoktur - ve bunu yalnızca bir UPnP istemcisinden ölü bir klasöre göz atarak keşfederdi. Alan menüsünü ve uygulama hedeflerini kategorinin gerçek verileriyle sınırlamak, boş düzenlerin oluşturulmasını engeller.


N22 - Podcast'leri yayın yılına göre gruplandır

Ne: her podcast bölümünün yayın tarihi okunur, böylece Yıl seviyesi olan bir podcast göz atma yolu, bölümleri tek bir "Bilinmeyen" altında toplamak yerine yıla göre gruplandırır.

Neden: büyük podcast abonelikleri, eklenti bölüm başına yayın tarihine hiç bakmadığı için her bölümün tek bir tarihsiz yığına düşmesi yerine, kitaplığın geri kalanı gibi yıla göre gezilebilir hale gelir.


N23 - Tek sonuçlu gruplandırma seviyelerini daralt

Ne: tek bir değere çözülen bir gruplandırma seviyesi - yalnızca LP'ler yapan bir sanatçı için yalnızca "LP" gösteren bir Kayıt Türü seviyesi veya tek bir harf içeren bir harf seviyesi - otomatik olarak atlanır ve kullanıcıyı doğrudan içeriğine düşürür.

Neden: tam olarak bir klasör içeren bir klasöre göz atmak tamamen sürtünmedir. Tek seçenekli seviyeyi daraltmak, kullanıcının ulaşabileceği şeyi değiştirmeden ölü tıklamayı ortadan kaldırır.


N24 - MusicBee'nin tarih alanına göre yıl gruplandırma/arama

Ne: yıl koşulu artık MusicBee'nin tam tarih "Yıl" alanını çıplak dört haneli bir değerle sorgulamıyor ve sabit kodlu yıl alanı takma adı kaldırıldı, böylece her gruplandırma alanı artık yol tanımından genel olarak çözülüyor.

Neden: Yıl etiketi tam bir tarih içeren kitaplıklar için, yıla göre gruplandırma veya arama daha önce hiçbir şey döndürmüyordu - dört haneli sorgu tam tarih alanıyla asla eşleşmiyordu. Doğru alanı sorgulamak, yıl gruplandırmasının ve aramasının parçaları tekrar bulmasını sağlar.


N25 - Ayrı "Yıl" ve "Yıl (yyyy)" gruplandırma alanları

Ne: albüm gruplandırma ve göz atma yolları artık MusicBee'nin kendi yıl alanlarının her ikisini de gösterir - Yıl (tam tarih etiketi) ve Yıl (yyyy) (sadece dört haneli yıl) - böylece kullanıcı bir albüm gruplandırması veya göz atma yolu tanımlarken ikisinden birini seçebilir.

Neden: iki alan MusicBee'de farklı şeyler ifade eder ve bunları birleştirmek bu ayrımı kaybettiriyordu. Her ikisini de göstermek, bir kullanıcının bir yılın her sürümünü bir araya getirmesine (yyyy) veya tam tarih sıralamasını (tam Yıl etiketi) korumasına olanak tanır.


N32 - Sabitlenmiş filtreler ve çalma listeleri kök dizinde türlerine göre gruplandı

Ne: sabitlenmiş bir filtre artık göz atma kök dizininde doğrudan Filtreler klasörünün altında, sabitlenmiş bir çalma listesi ise doğrudan Çalma Listeleri klasörünün altında görünür; tüm sabitlemelerin kök dizinin sonunda tek bir küme halinde toplanması yerine. Sabitlenmiş her kısayol kendi türüyle birlikte durur.

Neden: kullanıcı daha fazla kısayol sabitledikçe, filtrelerin ve çalma listelerinin karıştığı tek bir son küme taranması gitgide zorlaşır ve her kısayolu ait olduğu klasörden ayırır. Sabitlenmiş öğeleri kendi kategorileri altında gruplamak kök dizini okunabilir tutar ve her kısayolu ait olduğu şeylerin yanında bırakır.

Ayarlar iletişim kutusu ve paketleme

N26 - Bölümlere ayrılmış ayarlar iletişim kutusu

Ne: Tercihler sayfası, Genel / Oynatma / Kitaplık / Cihaz Profilleri / Tanılama bölümleriyle sol gezinme düzenine sahip oldu.

Neden: orijinal, her ayarın tek, uzun, düz bir listesiydi - onu inşa eden geliştirici için iyi, diğer herkes için şaşırtıcı. Bölümlere ayırma, ilgili seçenekleri gruplandırır ve iletişim kutusunun modern uygulama ayarlarına daha çok benzemesini sağlar.


Derleme + eklenti yeniden adlandırma (F-id yok - paketleme notu)

Ne: derlenmiş DLL mb_UPnP_yaiol.dll olarak adlandırılır ve eklenti kendini "MusicBee UPnP (yaiol)" olarak bildirir. Orijinal mb_Upnp.dll'den farklıdır.

Neden: kullanıcılar yaiol'u orijinal eklentiyle birlikte kurabilir ve davranışı yan yana karşılaştırabilir.


Rozet sistemi - çalışma zamanı durumunu gösterme (F40'ın arkasındaki mekanizma)

Ne: önemli çalışma zamanı koşullarını Ayarlar iletişim kutusunda görünür renkli rozetler olarak göstermek için genel bir UI deseni. Mevcut örnekler:

  • ⚠ Maks Bağlantı (N04) - MusicBee başladığından beri maksimum bağlantı sınırına en az bir kez ulaşıldığında tetiklenir. Yapışkan oturum bayrağı Plugin.MaxConnectionsHit. WaitOnSendBarrier içinde boş yuva olmadığında ayarlanır.
  • ⚠ Yeniden Başlatma Gerekli - kaydedilen bir ayarın etkili olması için MusicBee yeniden başlatması gerektiğinde tetiklenir. Yapışkan oturum bayrağı Plugin.RestartRequired. Yeni kalıcı değer çalışma zamanı anlık görüntüsünden (Plugin.activeMaxConnections, Plugin.activeServerPort, Plugin.activeIpAddress) farklı olduğunda iletişim kutusunun Kaydet işleyicisinde ayarlanır. Yeniden başlatma gerektiren ayarlar, gerçekten sıcak yeniden yüklenemeyenlerle sınırlıdır - HTTP sunucusu bağlama parametreleri ve Başlatma'da bir kez oluşturulan SemaphoreSlim.

Neden: eklentinin günlük dosyası, hata ayıklayan teknik kullanıcılar için iyidir, ancak "cihaz sesi yanlış" veya "oynatma yavaş" diyen teknik olmayan bir kullanıcı asla Tanılama → Günlüğü görüntüle'yi açmaz. Rozetler, kullanıcının bir şey olduğunu bilmesi gereken durumları yakalar ve eklentiyi bir sonraki açışında gösterir - hiçbir şey okumadan keşfedilebilir.

Gelecek için yeniden kullanılabilir:

  • Profil uyuşmazlığı algılandı (cihaz kullanıcı aracısı hiçbir profille eşleşmedi, Genel'e geri döndü).
  • NextURI geri çekilmesi tetiklendi (F13 - aralıksız oynatma, sorunlu bir cihazda oturum için devre dışı bırakıldı).
  • Kitaplık taraması başarısız / kısmi.
  • Oynatıcı bağlantısı oturum ortasında kesildi.
  • "Bir kez oldu, kullanıcı bilmeli"nin "1000 diğer satır arasında sessizce günlüğe kaydedildi"yi yendiği diğer herhangi bir durum.

Uygulama kuralları:

  • Rozet etiketleri iletişim kutusu seviyesinde (herhangi bir panelin içinde değil) bulunur, böylece kullanıcı hangi bölümde olursa olsun görünürler.
  • Kaydet/İptal yakınındaki alt satır boyunca konumlandırılmıştır (mevcut: y=410 yatay olarak yığılmış).
  • Her rozetin, durum oluştuğunda Doğru olan ve yalnızca MusicBee yeniden başlatıldığında sıfırlanan Plugin içinde karşılık gelen bir yapışkan oturum bayrağı vardır.
  • Kaynaklar: <Condition>Badge (etiket metni, ⚠ ile ön ekle) + <Condition>BadgeTip (nedeni + çözümü açıklayan araç ipucu).
  • "Kaydedilen ayar yeniden başlatma gerektiriyor" rozetleri için, Plugin.Initialise()'da bir çalışma zamanı anlık görüntüsü alın ve iletişim kutusu Kaydet işleyicisinde Settings.SaveSettings()'den sonra Settings.* ile karşılaştırın.

N27 - İptal, yol/şablon düzenlemelerini atar

Ne: ayarlar iletişim kutusunda yollara ve şablonlara yapılan düzenlemeler, artık kullanıcı İptal'e tıkladığında sessizce uygulanmış kalmak yerine atılır ve oturum sırasında kaldırılan herhangi bir ayrılmış şablon yeniden oluşturulur. (Şablonlar aksi takdirde düzenlendikçe canlı olarak kaydedilir - Yollar sekmesinde ayrı bir Kaydet düğmesi yoktur.)

Neden: İptal, iptal anlamına gelmelidir. Daha önce, yol/şablon değişiklikleriyle deney yapan ve geri çekilen bir kullanıcı, değişikliklerin zaten işlendiğini ve her birini elle yeniden yapmak dışında geri almanın bir yolu olmadığını görüyordu.


N28 - Alan seçici menüsünde değişmez ve işaretler

Ne: adı "&" içeren bir alan - örn. "Ruh Hali & Bağlam" - alan seçici menüsünde ampersandı Alt-kısayol ön eki olarak yutmak yerine değişmez olarak işler.

Neden: ampersand içeren alan adları yanlış görüntüleniyordu (karakter kayboluyordu ve bir sonraki harf bir hızlandırıcı haline geliyordu), menü girişini tanımayı zorlaştırıyordu.


N29 - Kararlı, çevrilmemiş ayarlar penceresi başlığı

Ne: ayarlar penceresi başlığı "MusicBee UPnP Eklentisi" marka dizesine sabitlenmiştir ve artık arayüz diliyle değişmez; dil başına DialogTitle dizesi her yerel ayar paketinden çıkarılmıştır.

Neden: dil başına değişen bir pencere başlığı, hiçbir faydası olmayan çevrilebilir bir yüzeydi - başlık bir marka işaretidir. Sabitlemek, her yerde kararlı ve tutarlı kalmasını sağlar.

Yerelleştirme

Orijinal eklenti yalnızca İngilizce'dir. Bu çatal tamamen yerelleştirilebilir - her kullanıcıya yönelik dize bir kaynak paketi aracılığıyla akar ve eklenti MusicBee'nin kendi UI dilini otomatik olarak algılar.

N30 - Çok dilli UI (çeviriler beklemede)

Ne: yerelleştirme mekanizması tamamlandı ve gönderiliyor. Localisation.vb, MusicBee'nin seçilen dilini MusicBee3Settings.ini'den (<SystemLanguage> endonimi) okur ve eşleşen .NET kültürünü iş parçacığına uygular, böylece My.Resources.Resources.* yerelleştirilmiş dizeyi döndürür. Her kullanıcıya yönelik etiket/düğme/mesaj bir kaynak anahtarına bağlanır (tasarımcı kontrolleri ApplyDesignerExtras + sync-en-locale.js aracılığıyla; WarnPortInUse gibi çalışma zamanı dizeleri elle eklenir). Henüz yapılmayan şey, gerçek çeviridir: yalnızca İngilizce kaynak paketi (Resources.resx) mevcuttur - diğer diller için uydu paketleri, eklenti özellik açısından tamamlandığında tek bir toplu geçişte üretilir (dizeler hala değişirken parça parça çeviri çabayı boşa harcar).

Hedef diller (MusicBee'nin kendisinin sunduğu, endonymToCulture tarafından 1:1 eşleşen, böylece eklenti MusicBee'nin dilini otomatik olarak takip eder):

Arapça (ar) Çekçe (cs) Almanca (de) Yunanca (el)
İspanyolca (es) Fransızca (fr) Macarca (hu) İtalyanca (it)
Korece (ko) Hollandaca (nl) Norveççe (nb) Lehçe (pl)
Portekizce BR (pt-BR) Portekizce PT (pt-PT) İsveççe (sv) Türkçe (tr)
Ukraynaca (uk) Rusça (ru) Japonca (ja) Basitleştirilmiş Çince (zh-CN)
Geleneksel Çince (zh-TW) İngilizce (en, kaynak)

Varyant politikası (çalışma alanı yerel ayar kuralına göre): PT ve ZH, kelime dağarcığı/yazı gerçekten farklılaştığı için ayrı paketlere ayrılır (pt-BR/pt-PT, zh-CN/zh-TW). EN tek bir pakettir - MusicBee'nin "English(US)" (en-US), .NET'in kültür zinciri aracılığıyla en'e geri döner, bu nedenle ayrı bir US paketi üretilmez. ES ve FR da benzer şekilde tek yerel ayardır.

Neden: bir UPnP eklentisinin ayarları ("ham PCM kullanma", "küçük endian PCM'yi zorla", port geri dönüş uyarıları) kişinin ana dilinde bile yeterince şifrelidir. İngilizce'yi zorlamak yerine MusicBee'nin kendi UI dilini takip etmek, İngilizce olmayan bir kullanıcının yapılandırabileceği bir araç ile yapılandıramayacağı bir araç arasındaki farktır. Hiçbir yukarı akış bunu denemedi.


N31 - Yardım bağlantısı tam arayüz dilinde açılır

Ne: eklentiden Yardım bağlantısını açmak, temel dile çökmek yerine kullanıcının tam arayüz dilini (örn. pt-BR, zh-CN) dikkate alır ve daha net bir güncelleme kontrol tanımlayıcısı gönderir.

Neden: bölgesel bir varyantta (Brezilya Portekizcesi, Basitleştirilmiş Çince) MusicBee çalıştıran bir kullanıcı, temel dil yardım sayfasına gönderiliyordu. Tam kültürü taşımak, onları kullandıkları tam dildeki yardım sayfasına yönlendirir.

Orijinal eklentideki düzeltmeler ve iyileştirmeler

Çekirdek protokol ve oynatma

F01 - Güncellenmiş varsayılan DLNA cihaz profilleri

Ne: PlayStation 4, Xbox 360/One ve modern BubbleUPnP için, bu cihazların bugün gerçekten desteklediği yetenek bayraklarını (örnekleme hızları, bit derinlikleri, kodekler) yansıtan yeni varsayılan profiller gönderir.

Neden: orijinal eklentinin varsayılanları yaklaşık 2014'te donmuştu. PS4/Xbox/BubbleUPnP o zamandan beri yüksek çözünürlüklü ses desteği kazandı. Kutudan çıktığı gibi, yeni bir kurulum, kullanıcının cihaz profili ayarlarını değiştirmesine gerek kalmadan bu cihazlarda sınıfının en iyisi şekilde oynatır.


F02 - MediaRenderer:3 reklamı yapan cihazları kontrol et

Ne: eklenti, MusicBee'nin onu sürüp süremeyeceğine karar vermek için bir oynatıcının UPnP hizmet açıklamasını sorgular. Orijinal yalnızca urn:schemas-upnp-org:device:MediaRenderer:1 ile eşleşiyordu. Modern cihazlar :2 veya :3 reklamı yapar. F02 eşleşmeyi genişletir.

Neden: bu olmadan, yeni Sonos / WiiM / Eversolo üniteleri, aynı protokolü konuşsalar bile MusicBee'nin "Oynat" cihaz listesinde hedef olarak görünmezler. Tek bir dize ön ek eşleşme düzeltmesi, tüm modern cihaz neslini açar.


F03 - "Yerel akışı zorla" profil başına seçenek (varsayılan AÇIK)

Ne: işaretlendiğinde, eklenti orijinal dosya baytlarını cihaza dönüştürme, DSP, ReplayGain işleme uygulamadan gönderir. Kullanıcının seçtiği ham dosya, bayt bayt (HTTP çerçeveleme hariç).

Neden: forum tanıklığına göre bu, tek başına en büyük oynatma kalitesi kazancıdır. Pahalı oynatıcılar satın alan hi-fi kullanıcıları açıkça bit-perfect çıktı ister; herhangi bir DSP dokunuşu amacı bozar. Çoğu modern cihaz kullanıcının onlara attığı her kodeği işlediği ve ReplayGain/EQ'nun isteğe bağlı olması gerektiği için varsayılan olarak AÇIK'tır. Profil başına olduğu için eski bir Xbox için dönüştürmeyi sürdürürken hi-fi bir DAC'ye yerel akış gönderebilirsiniz.


F04 - "Dönüştürmeyi zorla" profil başına

Ne: yerel kodek desteğinden bağımsız olarak her akışı bu cihaza dönüştürücüden geçmeye zorlayan profil başına geçersiz kılma. F03'ün tersi (ForceNativeStream). F03 ile karşılıklı olarak dışlayıcıdır - UI, biri açıldığında diğerini otomatik olarak işaretini kaldırır.

Neden: tek bir küresel geçiş, profil başına ForceNativeStream (F03) ile çelişkili olurdu. Gerçek dünya durumu: cihaz A, bit-perfect yerel akışlar isteyen bir hi-fi DAC'dir; cihaz B, FLAC'ta tıkanan eski bir AV alıcısıdır. Küresel bir geçişle kullanıcının diğer cihazın maliyetiyle seçim yapması gerekir. Profil başına her cihaz doğru yanıtı alır.

Uygulama:

  • StreamingProfile.ForceTranscoding As Boolean = False.
  • Kalıcılık şeması v9'a yükseltildi. v9 öncesi dosyalar eski küresel değeri bir kez yükler ve yükseltme boyunca eski davranışı koruyarak tüm profillere kopyalar.
  • UI: Tanılama panelinden kaldırıldı, Cihaz Profilleri bölümüne ForceNativeStream'in yanına eklendi. İki yönlü karşılıklı dışlama işleyicileri (her birindeki CheckedChanged, sonsuz döngüyü önlemek için diğerini çevirmeden önce aboneliğini iptal eder).
  • Karar yeri: Settings.ForceTranscodingstreamingProfile.ForceTranscoding içinde WriteAudioFileDIDL.

F05 - "Küçük endian PCM'yi zorla" profil başına

Ne: PCM akışları (L16/L24 mime türleri) spesifikasyona göre büyük endian'dır. Bazı cihazlar yanlışlıkla küçük endian bekler ve uygun büyük endian verileri verildiğinde beyaz gürültü çalar. F05, bayt sırasını profil başına değiştirir.

Neden: bu olmadan, belirli cihazlar bir statik duvarı çıkarır. Semptom dramatiktir ve neden PCM kodlaması bilgisi olmadan görünmezdir - geçiş, kullanıcılara bir tahmin ve kontrol düzeltmesi verir.


F06 - "Ham PCM kullanma" profil başına

Ne: cihaz ham PCM'yi desteklediğini iddia ettiğinde, eklenti bunu kullanır. Bazı cihazlar yalan söyler - SOAP el sıkışmasını kabul ederler ancak gerçek ham PCM verilerini bozar, WAVE kapsayıcısına sarılmış PCM'yi düzgün bir şekilde işlerken. F06, cihazın ne reklam yaptığına bakılmaksızın PCM-over-Wave'i zorlar.

Neden: özellikle belirli Marantz modelleri - ham PCM reklamı yaparlar ancak yalnızca WAVE çalışır. Bu olmadan, ham PCM akışları bozuk çıkar, işaret edecek bir hata mesajı olmadan.


F07 - "İçerik uzunluğu" profil başına

Ne: HTTP Content-Length başlığında hangi değeri göndereceği. Dört seçenek:

  • Varsayılan - bilindiğinde gerçek bayt sayısı, bilinmediğinde atla.
  • Yok - başlığı asla gönderme (yalnızca parçalı kodlama).
  • Yalnızca PCM - yalnızca ham PCM için gönder; diğer her şey için atla.
  • Sabit - UInt32.MaxValue - 8192 gönder ("büyük bilinmeyen uzunluk" için bir işaretçi).

Neden: UPnP/DLNA cihazları, Content-Length'e nasıl tepki verdikleri konusunda büyük farklılıklar gösterir. Bazıları tam bir sayıya ihtiyaç duyar, bazıları akışlarda ondan nefret eder, bazıları arabelleğe almaya devam etmek için bir işaretçi "gerçekten büyük" değere ihtiyaç duyar. bu daha sonra yalnızca PCM'den tüm çıktı formatlarına genişletildi çünkü aynı sorunlar dönüştürülmüş MP3/AAC akışlarında da ortaya çıktı.


F08 - "NextURI'yi temizleme" profil başına

Ne: normalde eklenti, kuyruk boşaldığında cihazın kuyruğa alınmış NextURI'sini temizler (boş bir URL ile SetNextAVTransportURI göndererek). Bazı cihazlar (özellikle Denon) boş bir NextURI'yi "her şeyi durdur" olarak yorumlar ve oynatmayı hemen durdurur. F08, eklentinin onu asla temizlemesini engeller.

Neden: bu olmadan, Denon sahipleri kuyruk boşaldığında cihazın parça ortasında kesildiğini deneyimler. F08 işaretlendiğinde, cihaz eski NextURI'yi bellekte tutar (zararsızdır - bir dahaki sefere bir şey kuyruğa alındığında üzerine yazılır).


F09 - Dönüştürme çıktı formatı olarak FLAC

Ne: Cihaz Profilleri'ndeki dönüştürme formatı açılır menüsü artık PCM 16/24, MP3, AAC, Ogg'un yanı sıra FLAC'ı da sunar. Bunu seçmek, BASS kodlayıcısını MusicBee'nin standart FLAC dönüştürme komut satırı aracılığıyla yönlendirir (MP3/AAC/Ogg'un zaten kullandığı aynı mekanizma).

Neden: FLAC'ı iyi işleyen ancak kaynak kodeği çözemeyen cihazlar için (örn. MusicBee'nin WMA kitaplığını FLAC'a dönüştürülmüş olarak alan bir Eversolo), bu, MP3/AAC'nin ses verilerini atacağı durumlarda kayıpsız kaliteyi korur. Kayıpsız bir dönüştürme seçeneği olmadan ele alınamayan N02'yi (5.1 downmix kontrolü) engeller.

Uygulama: Encoder.StartEncode'nin Select Case Codec bloğuna tek satırlık ekleme - FLAC, komut satırı odaklı dalda MP3/AAC/Ogg'a katılır. UI açılır menüsü 6. seçenek olarak "FLAC" alır. SettingsDialog'daki yükleme/kaydetme eşlemesi, FileCodec.FlacSelectedIndex = 5'i tanımak için genişler. Mime, DLNA türü ve kodlama özelliği, önceki çalışmalardan (F21, F26) ItemManager.GetMimes / GetDlnaType / GetEncodeFeature içinde zaten kablolanmıştı.


Aralıksız (SetNextAVTransportURI)

F10 - SetNextAVTransportURI / NextURI çekirdeği

Ne: gerçek aralıksız oynatma. Cihaz, UPnP hizmet açıklamasında SetNextAVTransportURI desteği reklamı yaptığında, eklenti mevcut parça bitmeden önce bir sonraki parçayı cihazda önceden kuyruğa alır. Cihaz, parçalar arasında duyulabilir bir boşluk olmadan dahili olarak geçiş yapar - bir CD çalarda duyduğunuz şey. Bu, "sürekli akış" hilesi değildir (her şeyi tek bir uzun akışta birleştiren ve parça başına meta verileri kaybeden).

Neden: amiral gemisi Tier-2 özelliği. Sürekli canlı performans olarak kaydedilen albümler (canlı kayıtlar, klasik hareketler, DJ setleri), parçalar arasında yarım saniyelik bir sessizlik olduğunda yanlış ses çıkarır. Bunu düzgün bir şekilde çözmek, bu çatalda bulunan amiral gemisi bir özelliktir.

Notlar: kuyruğa alınmış ses, eklentinin HTTP sunucusu aracılığıyla streamHandle=0 (kitaplık getirme modu) kullanılarak sunulur, bu da MusicBee'nin ses motorunun kuyruğa alınmış parça için döngüde olmadığı anlamına gelir. Takas: ReplayGain/DSP/EQ efektleri bir sonraki parçaya uygulanmaz. "Yerel akışı zorla" açık olduğunda (varsayılan) kabul edilebilir.


F11 - "NextURI desteğini devre dışı bırak" profil başına

Ne: bir cihaz SetNextAVTransportURI reklamı yapsa bile, bu onay kutusu eklentiyi bu reklamı yok saymaya ve tek seferde bir parça oynatmaya geri dönmeye zorlar.

Neden: bazı cihazlar NextURI reklamı yapar ancak hatalı bir uygulamaya sahiptir (çökmeler, yarım geçişler, takılmalar). Her bozuk cihazı tersine mühendislik yapmak yerine, kullanıcıya "sadece burada kapat" geçişi verilir.


F12 - Şimdi oynatılan listede NextURI yaşam döngüsü

Ne: MusicBee NowPlayingListChanged tetiklediğinde, eklenti aralıksız geçiş için neyin kuyruğa alınması gerektiğini yeniden değerlendirir. MusicBee'den NowPlayingList_GetNextIndex(1) + NowPlayingList_GetListFileUrl aracılığıyla yeni "sonraki" parçayı ister, cihazda şu anda kuyruğa alınmış olanla karşılaştırır (yeni nextPlaySourceUrl alanı aracılığıyla izlenir) ve değiştiyse yeniden kuyruğa alır (veya MusicBee bir sonraki parça olmadığını söylerse kuyruğu temizler).

Neden: F12 olmadan, kullanıcı kuyruğa alınmış parçayı kaldırdığında/yeniden sıraladığında cihaz eski bir NextURI'yi çalmaya devam ediyordu. Bu tarihsel olarak birkaç yineleme gerektirdi çünkü her liste mutasyonu farklı işlem gerektirir - biz NowPlayingList_GetNextIndex'e güvenerek basitleştirdik (bu zaten karıştırma ve tümünü tekrarla sarmalamayı dikkate alır), bu nedenle tüm varyantlar aynı karşılaştırma aracılığıyla yönlendirilir.

Uygulama:

  • Yeni nextPlaySourceUrl alanı, kuyruğa alınmış olanın MusicBee kitaplık URL'sini depolar (işleyici son ekli akış URL'si bir kitaplık yoluyla karşılaştırılamaz).
  • MediaRendererDevice üzerinde yeni Public Sub RefreshQueuedNextUri(). Üç sonuç: kuyruğa alınmış NextURI yok → no-op; kuyruğa alınmış yeni "sonraki" ile eşleşiyor → no-op; kuyruğa alınmış farklı → yeni URL ile QueueNext çağrısı yap (veya temizlemek için QueueNext("") - bu F08 DoNotClearNextUri'yi dikkate alır).
  • NotificationType.NowPlayingListChanged altında Plugin.ReceiveNotification içinde kablolanmıştır.

F13 - NextURI hatası geri çekilmesi

Ne: aynı cihazda art arda 4 SetNextAVTransportURI hatasından sonra, eklenti MusicBee yeniden başlatılana kadar o cihaz için aralıksız oynatmayı devre dışı bırakır.

Neden: bir cihaz NextURI için gerçekten bozuksa (aralıklı SOAP hataları, ağ aksaklıkları), eklenti aksi takdirde her parçada yeniden denemeye devam ederdi. F13 gürültüyü durdurur ve sessizce tek seferde bir parçaya geri döner.


F14 - Tekrar modu + NextURI entegrasyonu

Ne: F14, OnAvTransportStatusCheck içindeki F15 geçiş dedektöründe ele alınan iki duruma ayrılır:

  • Tümünü Tekrarla: MusicBee, doğru "sarma" URL'sini (listenin sonundaki parça 1) Plugin.QueueNext'e kendisi iletir. Özel eklenti mantığına gerek yoktur - cihaz ona geçiş yapar ve F15 dedektörü her zamanki gibi Player_PlayNextTrack çağrısı yapar, bu da MusicBee'nin NPL dizinini 0'a geri sarar.
  • Birini Tekrarla: MusicBee, AYNI parça URL'sini Plugin.QueueNext'e iletir. Cihaz ona geçiş yapar (yeni akış işleyicisi, aynı kaynak). F15 dedektörü şimdi Player_GetRepeat() sorgular - eğer RepeatMode.One ise, Player_PlayNextTrack çağrısını atlayarak MusicBee'nin NPL dizinini döngüdeki parçadan uzaklaştırmamasını sağlar.

Neden: Tekrarla-Bir atlaması olmadan, aralıksız geçişte Player_PlayNextTrack çağrısı, MusicBee'yi listedeki bir sonraki parçaya ilerletirdi (Tekrarla-Bir yalnızca oynatıcının UI'sında parça sonu otomatik ilerleme davranışını etkiler - Sonraki Parça her zaman ileri gider), Tekrarla-Bir'in ne anlama geldiğiyle çelişirdi.

Oynatma sayısı uyarısı: Tekrarla-Bir'de, oynatma sayısı artışı, MusicBee 3.7.9563+'ın döngüsel oynatmayı fark etmesine bağlıdır. Eski MusicBee sürümleri aralıksız tekrarı doğru şekilde oynatır ancak oynatma sayısı artışını kaçırır. Belgelenmiştir; engellemiyor.


F15 - Parça geçiş algılama durum makinesi

Ne: cihaz dahili olarak mevcut parçadan NextURI'ye geçiş yaptığında, eklentinin bunu fark etmesi ve MusicBee'ye şimdi oynatılan dizinini ilerletmesini söylemesi gerekir. Aksi takdirde MusicBee hala önceki parçada olduğunu düşünür ve oynatma sayıları / UI / scrobbling senkronizasyon dışına çıkar.

Uygulama: her durum zamanlayıcısı tikinde GetPositionInfo.TrackURI'yi yoklar. Bildirilen URI, NextURI aracılığıyla kuyruğa aldığımız URI ile eşleştiğinde, MusicBee'de Player_PlayNextTrack çağrısı yaparız ve suppressNextSoapCall ayarlarız, böylece ortaya çıkan PlayToDevice SetAVTransportURI'yi yeniden göndermez (bu, aralıksız oynatmayı kesintiye uğratırdı).

Neden: F15 olmadan cihaz bir sonraki parçayı çalar ancak MusicBee'nin UI'si hala önceki parçada olduğunu söyler. Kafa karıştırıcıdır, scrobbling'i bozar, oynatma sayısı takibini bozar. Parça geçiş algılama, her oynatıcı markasının URI değişikliğini ne zaman bildirdiği konusunda kendi tuhaflıkları olduğu için uzun, oynatıcı başına yineleme gerektirir (bazıları önce GEÇİŞ yapıyor bildirir, bazıları yeni URI ile doğrudan OYNATMA'ya atlar, bazıları arada kısa bir DURDURULDU durumuna sahiptir).

Notlar: ilk denememiz BubbleUPnP oynatıcısında çalışır. Cihaz başına uç durumlar B6'da kalır.


F16 - Aralıksız geçişte patlama düzeltmesi

Ne: patlama, kuyruğa alınmış parçanın kaynak formatı (örnekleme hızı / kanallar / kodek) şu anda çalınan parçadan farklı olduğunda meydana gelir ve cihazın DAC'sini geçişte yeniden kilitlemeye zorlar. F16, formatlar farklı olduğunda kuyruğa alma sırasında tetiklenen, her iki tarafı da adlandıran bir NextUri:FormatChange tanılama ekler - böylece patlama duyan kullanıcılar ilişkilendirebilir.

Tanılama ayrıca hafifletmeyi de işaret eder: cihaz profilinde Dönüştürmeyi Zorla'yı işaretleyin. Bu, her parçayı tek bir dönüştürme kodeği/örnekleme hızı/bit derinliğine homojenleştirir ve kaynak format farkını tamamen ortadan kaldırır.

Gerçek dönüştürme-eşleştirme düzeltmesi için neden ertelendi: yapısal düzeltme (kuyruğa alınmış parçayı çalınan parçanın formatıyla eşleşecek şekilde dönüştürme), eklentinin HTTP sunucusu URL şemasında değişiklikler gerektirir - şu anda /encode/{id}0.{ext} kuyruğa alınmış dosyayı yerel olarak sunar. F16'nın gelecekteki bir v2'si, format başına /encode/{id}0_{rate}_{depth}.{ext} rotaları ekler ve bunları kodlayıcı aracılığıyla kablolar. Bu, ForceTranscoding yeterli olmadığında gerçek bir cihaz patlamayı gösterirse yapmaya değer daha büyük bir mimari değişikliktir.

Bugünkü uygulama:

  • lastSourceUrl alanı, şu anda çalınan kaynak URL'sini izler.
  • QueueNext, hem mevcut hem de kuyruğa alınmış parçalar için FilePropertyType.SampleRate/Channels/Kind okur ve uyuşmazlık durumunda NextUri:FormatChange günlüğe kaydeder.

F17 - Arama sonrası ilerleme çubuğu yeniden senkronizasyonu

Ne: Seek() işlevi, başarılı bir Seek SOAP'tan sonra zaten GetPlayPositionInformation() çağrısı yapıyordu, bu da "hiç yeniden senkronizasyon yok" durumunu düzeltiyordu. F17, UPnP'nin 1 saniyelik RelTime nicelemesinden kaynaklanan kalan 1 saniyeye kadar kaymayı kapatır: cihazın bildirilen konumu kullanıcının istenen hedefine 1 saniye içinde yuvarlandığında, eklenti artık cihazın kesmesini değil, kullanıcının saniye altı doğru değerini güvenir. Yalnızca cihaz dramatik olarak farklı bir şey bildirdiğinde (>1s kapalı) değerini kullanırız (arama istenenden başka bir yere indi, örn. bazı kodeklerde ana kareye yapışma).

Neden: bu olmadan, cihazın "2:30" raporuna karşı 2:30.500'e arama yapmak, ilerleme çubuğunun gerçekliğin ~500ms gerisinde görünmesine neden olurdu. F17'den sonra çubuk, yaygın parça içi kaydırma durumu için kullanıcının amacına uyar ve ana kareye yapışma aykırı değeri için cihazın raporuna hala saygı duyar.


F18 - Sürekli akış / NextURI kilidi

Ne: şimdi iki kilit mevcuttur:

  1. Çalışma zamanı: Settings.ContinuousOutput açık olduğunda QueueNext erken False döndürür. Sürekli akış kendi aralıksız mekanizmasıdır (tek uzun birleştirilmiş akış); üzerine SetNextAVTransportURI göndermek, cihazı her parçanın ayrı bir URI mi yoksa sürekli akışın bir parçası mı olduğu konusunda karıştırır.
  2. UI: kullanıcı küresel sürekli akış onay kutusunu işaretlediğinde, şu anda görüntülenen profilin forceNativeStream otomatik olarak işaretini kaldırır. Sürekli akış her zaman dönüştürür, bu nedenle zorla yerel, kombinasyonda anlamsızdır.

Neden: kullanıcının iki çakışan aralıksız mekanizmayı aynı anda etkinleştirmesini önler. F18 olmadan, cihaz hem sürekli bir akış URI'si hem de her sonraki parça için bir NextURI alırdı, oynatıcıya bağlı olarak tanımsız davranışla.


F19 - Boş NextURI hataları yok sayıldı

Ne: SetNextAVTransportURI boş bir URL ile çağrıldığında (örn. listedeki son parça), bazı cihazlar bir SOAP hatası döndürür. F19 bunları sessizce yutar - günlüğe kaydedilir ancak hata olarak yayılmaz.

Neden: "sonraki parça yok" durumu normaldir, hata değildir. Bunu ölümcül olarak ele almak günlüğü kirletir ve (bazı akışlarda) yeniden deneme fırtınalarını tetikler.


Mime türleri ve DLNA meta verileri

F20 - MP3 mime → audio/mpeg

Ne: standartlara uygun MP3 mime türü audio/mpeg'dir, audio/mp3 değil. İkincisi, çoğu cihazın tolere ettiği yaygın bir yanlış adlandırmadır, ancak daha katı oynatıcılar bunu reddeder.

Neden: standardı takip eden daha katı cihazlarda oynatmayı sessizce düzeltir. Yaiol kod tabanı bunu zaten doğru bir şekilde içeriyordu; değişiklik gerekmedi.


F21 - Mime türü sırası: x- olmayan varyant önce

Ne: bir cihaz hem audio/flac hem de audio/x-flac reklamı yaptığında, eklenti x- olmayan varyantı önce döndürür. Hem standart hem de deneysel mime'lara sahip herhangi bir kodek için aynı.

Neden: x- ön eki deneysel/resmi olmayan mime'ları işaretler. Bazı oynatıcılar standart formla daha iyi davranır. Küçük yeniden sıralama, gerçek dünya etkisi.


F22 - Opus mime türü desteği

Ne: Opus'u akışa uygun bir ses kodeği olarak tanır; Opus parçalarını sunarken audio/opus mime gönderir.

Neden: Opus artık yaygın (modern konuşma/müzik uzlaşma kodeği). F22 olmadan eklenti, Opus dosyalarını onları işleyen cihazlara bile akış yapmayı reddederdi.


F23 - Monkey Audio (APE) kaynak dosyası desteği

Ne: .ape dosyalarını akış/dönüştürme için geçerli bir kaynak kodeği olarak tanır.

Neden: APE, niş ama sadık bir kullanıcı tabanına sahip kayıpsız bir formattır. Eklemek az maliyetlidir ve bu kullanıcılar için kitaplığı açar.


F24 - AAC / ALAC mime geri dönüşü

Ne: bir cihaz AAC veya ALAC'ı destekliyorsa ancak UPnP hizmet açıklamasında bunları açıkça reklamı yapmıyorsa, eklenti yine de bunları bir geri dönüş olarak sunar.

Neden: AAC'yi iyi işleyen birkaç cihaz, yetenek XML'lerinde bunu listelemeyi unuttu. F24 olmadan eklenti denemez bile, dönüştürmeyi zorlar. F24 ile eklenti dener ve cihaz yapabiliyorsa yerel olarak işlemesine izin verir.


F25 - Yerel + kodlanmış WAV akışları için DLNA tür bayrağı

Ne: DLNA tür bayrağı (LPCM, WAVE, MP3 gibi bir profil tanımlayıcı), cihazın aldığıyla eşleşmelidir. F25, yerel akışların ve kodlanmış WAV akışlarının doğru şekilde işaretlenmesini sağlar.

Neden: yanlış DLNA türü, bazı cihazların oynatmayı tamamen reddetmesine veya yanlış kod çözücüyü uygulamasına neden olur.


F26 - FLAC dosyaları için DLNA başlığı

Ne: FLAC akışları, başlıklarında uygun DLNA profil tanımlayıcısını alır.

Neden: bu olmadan, FLAC'ı destekleyen bazı cihazlar akışı bu şekilde tanımaz.


F27 - Meta verilerde bit hızı hesaplama düzeltmesi

Ne: sürekli akış res@bitrate, (sampleRate * channels * bitsPerSample) / 1000 olarak hesaplanıyordu - kbps, özniteliği saniye başına bayt olarak tanımlayan UPnP DIDL spesifikasyonundan ~125 faktör kadar farklı. Şimdi 1000 yerine 8'e bölünür.

Neden: cihazda yanlış bit hızı gösterimi - çoğu oynatıcıda kozmetik, ancak bazıları akış arabelleklerini değerden ayırır ve olduğundan ~125 kat daha küçük görünen akışlarda takılır. Sürekli olmayan kaynak dosya yolu bunu zaten doğru bir şekilde içeriyordu ((bitrate_kbps * 1000) \ 8 = bayt/sn); yalnızca sürekli akış yolu yanlıştı.


F28 - Meta veri zaman formatı düzeltmesi (Marantz)

Ne: DIDL'deki res@duration, H:MM:SS olarak biçimlendirilmişti (örn. 0:03:42). UPnP DIDL spesifikasyonu formatı H+:MM:SS[.F+] olarak tanımlar - kesinlikle kesirli saniyeler isteğe bağlı ancak önerilir; bazı Marantz cihazları çıplak formu geçersiz olarak kabul eder ve süre gösterimlerini boş bırakır. Şimdi H:MM:SS.fff olarak biçimlendirilmiştir (örn. 0:03:42.000).

Neden: bir markaya özgü görüntüleme sorunu; kesirli saniyelerle uyumlu ISO tarzı format, başka hiçbir cihazı etkilemeden düzeltir. Her iki DIDL yayım sitesinde de uygulandı (kaynak dosya yolu + WriteAudioFileDIDL içindeki kodlanmış akış yolu).

Aynı geçişte bonus düzeltme: pv:addedTime ve pv:lastPlayedTime, DateTime format dizelerinde HH (24 saat) yerine hh (12 saat) kullanıyordu. 13:00 ile 23:59 arasında eklenen veya çalınan herhangi bir parça, alanı gösteren cihazlarda yanlış bir saatle (örn. 17:42 → "05:42") işlenirdi. Şimdi HH kullanır.


F29 - Kodlanmış MP3 arama desteği (CBR)

Ne: dönüştürülmüş MP3 akışları artık DLNA.ORG_OP=10 (yalnızca bayt) yerine DLNA.ORG_OP=11 (hem bayt hem de zaman arama) reklamı yapar. Daha önce dönüştürülmüş MP3'te zaman aramasını reddeden cihazlar artık ilerleme çubuklarını/arama UI'lerini normal şekilde sürebilir.

Neden: MusicBee'nin dönüştürücüsü HighQuality ön ayarında sabit bit hızlı MP3 üretir, bu nedenle bayt ↔ zaman eşlemesi doğrusaldır - cihaz, herhangi bir kodlayıcı tarafı desteği olmadan bir zaman arama isteğini bir HTTP Range bayt aramasına kendisi dönüştürebilir. OP=11 reklamı yapmak, cihazdaki bu UI'yi açar. F29 olmadan, dönüştürülmüş bir MP3 içinde arama yapan kullanıcılar, aramanın sessizce yok sayıldığını veya parçanın başına düştüğünü görüyordu.

Uygulama: ItemManager.vb içindeki GetEncodeFeature yeniden yapılandırıldı, satır içi If'i okunabilir bir If/ElseIf/Else zincirine ayırdı. MP3 açıkça OP=11 alır; diğer PCM olmayan kodekler OP=10'u korur. AAC/FLAC/vb. için değişiklik yok - bunlar MusicBee'nin garanti etmediği kodeğe özgü CBR-ness doğrulaması gerektirir.


F30 - .mpeg dosya uzantısı işlendi

Ne: .mpeg (ve hatta daha nadir .mpe) uzantılı dosyalar artık GetCodec içinde FileCodec.Mp3 olarak tanınır. F30'dan önce FileCodec.Unknown döndürüyorlardı ve kitaplıktan sessizce reddediliyorlardı / dönüştürme kaynakları olamıyorlardı.

Neden: eski MPEG-1 Katman 3 arşivleri bazen .mp3 yerine .mpeg kullanıyordu (spesifikasyon her ikisine de izin verir). 300 binlik bir kitaplıkta birkaç dosya, "MusicBee onları gösteriyor ama eklenti göstermiyor" hissini yaratmak için yeterlidir - kullanıcı için kafa karıştırıcıdır.


Oynatma davranışı

F31 - Radyo akışları otomatik olarak sürekli modu kullanır

Ne: WriteAudioFileDIDL artık kaynak URL'sinin Kind özelliğini Library_GetFileProperty aracılığıyla sorgular ve Kind'ı "Stream" ile biten herhangi bir dosyayı (MusicBee radyo için "MP3 Stream", "Internet Stream" vb. bildirir) küresel Settings.ContinuousOutput geçişinden bağımsız olarak sürekli olarak ele alır. Sürekli akış DIDL dalı (Başlık: "Sürekli Akış", id="continuousstream", sabit PCM/Wave çıktısı) kullanılır; cihaz tek bir sonsuz tarzı akış görür.

Neden: radyo akışlarının parça sınırları, sabit uzunluğu, arama özelliği yoktur. Onları DIDL'de ayrı dosyalar gibi ele almak, eklentinin var olmayan bayt aralıkları ve süreleri reklamı yapmasına neden oluyordu. MusicBee bize zaten "bu bir Akış" dediğinde otomatik geçiş yapmak, kullanıcının düşünmek zorunda kalmaması gereken bir ayak tabancasını ortadan kaldırır.

Kapsam: yalnızca MusicBee oynatmayı sürdürdüğünde geçerlidir (musicBeePlayToMode). Kitaplık getirme yolu (UPnP istemcisi göz atma) değişmeden kalır - radyo URL'leri orada nadirdir ve kullanıcıya yönelik davranış açık test olmadan değişmemelidir.


F32 - Kodek reklamı geri dönüşü

Ne: bir cihaz belirli kodekleri reklamı yapmazsa (veya eklenti cihazın yetenek XML'ini ayrıştıramazsa), eklenti akışı hemen reddetmez. Bunun yerine, onu sunmaya çalışır ve cihazın karar vermesine izin verir.

Neden: birçok cihazın eksik veya okunaksız yetenek XML'i vardır ancak kodeği aslında iyi işler. F32, doğrudan bir reddetme yerine küçük bir "en iyi tahmin ve dene" takası yapar.


F33 - İlerleme çubuğu senkronizasyon iyileştirmesi

Ne: anketler arasındaki konum, tek bir çapa (currentPlayStartTicks) üzerinden zaten duvar saatiyle ekstrapole edilmiştir, bu nedenle ilerleme çubuğu saniye altı hızda sorunsuz bir şekilde güncellenir. Kalan titreme kaynağı, yeni başlayan bir parça için başlangıç çapası idi: önceki kod, durumun Oynatılıyor'a geçtiğini durum zamanlayıcısının ilk fark ettiği anda position=0 olduğunu varsayıyordu, ancak o zamana kadar cihaz 100-500ms (bir anket aralığı) çalıyor olabilirdi. MusicBee'nin ilerleme çubuğu 0'dan başlar, sonra gerçeklik yakaladığında ileri atlardı.

F33 düzeltmesi: yeni bir parçada ilk kez Oynatılıyor'a geçiş yaparken (currentPlayStartTimeEstimated=True), cihazın gerçek mevcut konumunu almak için GetPlayPositionInformation() çağrısı yapın, ardından buna göre çapa atın. UPnP yalnızca 1 saniyelik çözünürlük bildirir, bu nedenle çapa hala nicelenmiştir, ancak 0 varsaymaktan çok daha gerçeğe yakındır.

Neden: özellikle parça değişikliğinden hemen sonra daha pürüzsüz + daha doğru ilerleme gösterimi. 1 saniyelik UPnP raporlama çözünürlüğünün kendisinden kaçış yok - bu spesifikasyon.


F34 - Parça değişikliğinden sonra ilerleme çubuğu titremesi

Ne: yeni bir parça için PlayToDevice çağrıldığında, eklenti currentPlayPositionMs ve currentPlayStartTicks'i SOAP-Play ile yeni Oynatılıyor durumunu algılayan ilk durum zamanlayıcısı anketi arasındaki ~100ms'lik pencere için önceki parça değerlerinde bırakırdı. MusicBee'nin ilerleme çubuğu kısaca önceki parçanın sonunu gösterir, sonra 0'a geri döner, sonra tırmanırdı. F34, PlayToDevice girişinde her ikisini de sıfırlar - bir parça değişikliğinin gerçekleştiğini bildiğimiz anda, herhangi bir SOAP çalışmasından önce.

Neden: hızlı atlama kullanım durumlarında (manuel sonraki veya aralıksız geçiş) görsel aksaklık. Artık MusicBee'nin Play sonrası ilk PlayPositionMs sorgusu temiz bir şekilde 0 döndürür, ardından F33'ün GetPlayPositionInformation'ı ilk durum değişikliği tikinde cihazın gerçek konumuna göre onu iyileştirir.

Uygulama: PlayToDevice'ın üst kısmında dört satır, F33'ün geçiş zamanı doğru çapalamasıyla eşleştirildi.


F35 - "Dönüştürmeyi zorla" hatası

Ne: dönüştürmeyi zorlama, belirli kombinasyonlarda hala dönüştürmeyi atlayabilirdi. F04 profil başına yeniden çalışmasından sonra, iki özel boşluk kapatıldı:

  1. ForceNativeStream ile öncelik. Her ikisi de Doğru olduğunda (bir şema geçişi veya kısmi bir ayarlar dosyası aracılığıyla olabilir), ForceTranscoding artık doğrudan kazanır (If streamingProfile.ForceTranscoding Then forceEncode = True ElseIf streamingProfile.ForceNativeStream Then forceEncode = False). UI karşılıklı dışlama, kullanıcının her ikisini de işaretlemesini engeller, ancak çalışma zamanı koruması, diskten tutarsız yüklenen herhangi bir durumu ele alır.
  2. bypassTranscodeDecision mantığı. Daha önce: streamingProfile.ForceNativeStream AndAlso Not Settings.ForceTranscoding. Şimdi: streamingProfile.ForceNativeStream AndAlso Not streamingProfile.ForceTranscoding - aynı öncelik kuralı ancak aynı profil başına kapsamda.

Neden: "zorla" zorla anlamına gelmelidir. Kullanıcı bir cihaz için ForceTranscoding'i açıkça etkinleştirdiyse, eklenti, diğer bayrakların nasıl birleştiğine bakılmaksızın asla sessizce yerel akışa düşmemelidir.


F36 - Oynatıcı kapalı istisnası

Ne: Plugin.ReceiveNotification'ı, yakalanmayan herhangi bir istisnayı MusicBee'nin bildirim pompasına geri yaymasına izin vermek yerine günlüğe kaydeden üst düzey bir Try/Catch içine sardı.

Neden: MusicBee'den gelen bildirimler (PlayStateChanged, VolumeMuteChanged vb.), SOAP üzerinden oynatıcıyla konuşan ControlPointManager'a gönderilir. Bireysel çağrı sitelerinde SOAP çağrılarının etrafında zaten Try/Catch vardı, ancak yeterince tuhaf bir zamanlama durumu (örn. aynı bildirim işleyicisinde iki SOAP çağrısı arasında oynatıcının ölmesi) yine de kaçabilirdi. Üst düzey sarmalayıcı, kullanıcının MusicBee'den asla genel bir "TargetInvocationException" açılır penceresi görmemesi için son güvenlik ağıdır.

Uygulama: mevcut gövde ReceiveNotificationInternal olarak yeniden adlandırıldı ve Try { ReceiveNotificationInternal(...) } Catch { LogError(...) } yapan ince bir sarmalayıcı ReceiveNotification eklendi. ControlPointManager içindeki önceden var olan yöntem başına Try/Catch altyapısı (her PostSoapRequest çağrısının etrafında) kalır - F36 kemer + askıdır.


F37 - Uzun parça arama yanlış geçişi tetikliyor

Ne: uzun bir parçanın içinde arama yapmak, bazı oynatıcılarda kısa bir Durduruldu→Oynatılıyor döngüsü üretebilir. Ayrımcılık olmadan, ProcessNewPlayState.Stopped bunu parçanın doğal sonu olarak ele alır ve Player_PlayNextTrack çağrısı yapar, kullanıcı sadece kaydırmak istediğinde MusicBee'yi ilerletir. F37, Seek() içinde lastUserInitiatedSeek damgalar ve Durduruldu işleyicisine 5 saniyelik bir koruma ekler (mevcut lastUserInitiatedStop penceresini yansıtır).

Neden: arama sırasında sessizce bir sonraki parçaya atlama, kimsenin nedenini tahmin edemeyeceği hatalardan biridir - kullanıcı "garip, ileri kaydırmaya çalıştım ve şimdi bir sonraki şarkıyı çalıyor" diye düşünür. Düzeltme mekaniktir: zaten mevcut olan kullanıcı durdurma ayrımcılığıyla aynı desen.


F38 - Çökme eğilimli kodekler için geliştirilmiş arama işleme

Ne: MP3 aramasında BubbleUPnP'nin çökmesi kanonik semptomdu. Denetimden sonra, mevcut yaiol arama kodu zaten doğru şeyleri yapıyor - yerel yol HTTP Range'i doğru şekilde işler (206, Content-Range, AcceptRanges), kodlanmış yol X-AvailableSeekRange reklamı yapar ve gelen timeSeekRange.dlna.org / npt başlıklarını ayrıştırır, DLNA.ORG_OP bayrakları gerçek akış yeteneklerini yansıtır (sorunlu Platinum cihazlar için DisablePcmTimeSeek devre dışı bırakma seçeneğiyle). Mevcut BubbleUPnP 4.6.4 üzerinde kullanıcı test edildi: çökme gözlenmedi.

Neden: BubbleUPnP MP3-arama çökmesi yaklaşık 2024'te rapor edildi ve uygulama o zamandan beri ~16 aylık düzeltmeler aldı. F29 (kodlanmış MP3 OP=11), onu yeniden ortaya çıkarabilecek yeni değişkendi; test edilen sürümlerde yapmıyor.

Bir çökme geri dönerse: düzeltme şekli, işaretli kodeklerde DLNA.ORG_OP=10 (yalnızca bayt) zorlayan profil başına "sınırlı arama" geçişi olurdu - DisablePcmTimeSeek'in PCM için zaten nasıl çalıştığını yansıtır. O zaman ekle, önleyici olarak değil.


UI ve günlük kaydı

F39 - "Ekle" düğmesi yeni profili seçer

Ne: cihaz profilleri listesinde "Ekle"ye tıklamak yeni bir profil oluşturur VE otomatik olarak seçer, böylece kullanıcı alanları hemen düzenleyebilir. Bölümlere ayrılmış iletişim kutusu yeniden düzenlememiz bunu zaten yapıyor - hem doğrudan Ekle yolu hem de şablondan yolu Me.activeStreamingProfiles.SelectedIndex = Me.activeStreamingProfiles.Items.Count - 1 ile biter. Bir kontrol, çatalımızın bunu zaten ele aldığını doğruladı - değiştirilecek bir şey yok.

Neden: küçük UX kağıt kesiği, burada zaten kağıt kesiği olmadığı ortaya çıktı.


F40 - Daha büyük maksimum bağlantılar + uyarı günlüğü

Ne: eklentinin eşzamanlı akış sınırı (Sockets_Stream_File / Sockets_Encoder_Start etrafındaki SemaphoreSlim) sabit kodlu 4 idi. F40, Genel ayarlar sayfasında kullanıcı tarafından yapılandırılabilir hale getirir (varsayılan 16, aralık 1-256), bir isteğin bir yuva beklemesi gerektiğinde bir MaxConnections günlük satırı ekler VE MusicBee başladığından beri sınıra en az bir kez ulaşıldıysa ayarlar iletişim kutusunun sol altında kırmızı ⚠ Maks Bağlantı rozeti gösterir.

Neden: bir cihaz paralel istekler ateşlediğinde (bazı Marantz/Linn resim taramaları sırasında, BubbleUPnP'nin aktif oynatmanın yanı sıra meta veri sorguları), ek istekler semaforun arkasında sessizce engelleniyordu - kullanıcı görünür bir neden olmadan "cihaz yavaş" görüyordu. Günlük satırı teknik hata ayıklama için iyidir ancak teknik olmayan kullanıcılar günlükleri asla okumaz. Ayarlar iletişim kutusundaki görünür rozet, sınıra ulaşma durumunu eklentinin tercihlerini açan herkes için keşfedilebilir hale getirir.

Uygulama:

  • MusicBeeUpnp.vb içindeki WaitOnSendBarrier(logTag) içinde bekleme merkezileştirildi; her iki çağrı sitesi (MediaServerDevice.GetFile, Encoder.StartEncode) onu kullanır.
  • Settings.MaxConnections, ayarlar şemasının v8'inde kalıcı hale getirildi.
  • Plugin.MaxConnectionsHit, WaitOnSendBarrier içinde ayarlanan yapışkan bir oturum bayrağıdır; yalnızca MusicBee yeniden başlatıldığında sıfırlanır.
  • SettingsDialog.maxConnectionsBadge, (16, 410) konumunda, yalnızca Plugin.MaxConnectionsHit Doğru olduğunda görünen kırmızı kalın bir etikettir. Nedeni ve çözümü açıklayan bir araç ipucuna sahiptir.
  • Semafor, tür yüklemesinde bir kez başlatılır, bu nedenle ayarı değiştirmek bir MusicBee yeniden başlatması gerektirir (alan etiketinde belirtilmiştir).

F41 - "ReplayGain/DSP nedeniyle kodlama" günlüğe kaydet

Ne: ayrı "RG için kodlama" / "DSP için kodlama" günlük satırları yerine, F42'den gelen tek StreamDecision satırı, birikmiş nedenler olarak MB-DSP/EQ, MB-ReplayGain, Profile-DSP/EQ, Profile-ReplayGain içerir. Aynı tanılama değeri, daha az gürültü.

Neden: kullanıcılar, belirli bir parça için dönüştürmenin neden gerçekleştiğine dair tüm nedenleri tek bir günlük satırında görür, dağınık değil. Tam ayrıntılar için F42'ye bakın.


F42 - "Oynatıcı kaynak kodeği desteklemiyor" günlüğe kaydet

Ne: oynatma hedefi başına "yerel CODEC" veya "dönüştürme CODEC→CODEC neden=…" diyen bir StreamDecision günlük satırı eklendi. Neden alanı, dönüştürmeyi tetikleyen her koşulu biriktirir: MB-DSP/EQ, MB-ReplayGain, Profile-DSP/EQ, Profile-ReplayGain, WebFile, VirtualFile, ForceTranscoding(global), SampleRate<min/SampleRate>max, DownmixToStereo, DeviceLacksCodec(X), BandwidthConstrained.

Neden: kullanıcılar, yerel olarak akış yapmayı bekledikleri dosyalarda beklenmedik CPU artışları nedeniyle kafaları karışıyordu. Parça başına bir günlük satırı, onlara dönüştürmeyi tam olarak hangi koşulun tetiklediğini söyler - ve alan DeviceLacksCodec(Flac) gösteriyorsa, cihazın protokol bilgisinin eksik olduğunu ve F32'nin geri dönüşünün devreye girmesini isteyebileceklerini hemen anlarlar.

Uygulama: karar zinciri boyunca artımlı olarak oluşturulan tek bir biriktirici dize; sonunda bir kez günlüğe kaydedilir. Üretimde günlük gürültüsünü önlemek için Settings.LogDebugInfo ile korunur.


F43 - SetNextAVTransport günlüğü kaynak URL'sini gösterir

Ne: QueueNext günlük girişleri artık stream=<HTTP akış URL'si> ile birlikte source=<MusicBee kitaplık yolu> içerir. Aynı değişiklik başarı yoluna ve hata yoluna (QueueNext:Failed) uygulandı.

Neden: kuyruğa alınmış bir parça sorununu hata ayıklarken, akış URL'si (/encode/aabbccdd0.flac) kendi başına opaktır - her parça için aynıdır. Kaynak URL'si, MusicBee'nin tam olarak hangi dosyayı kuyruğa almaya çalıştığını söyleyen insan tarafından aranabilir kitaplık yoludur.


F44 - Daha iyi mime-türü hata günlüğü

Ne: Activate sırasında iki yeni günlük girişi:

  • Activate:MimeUnverified - cihazın GetProtocolInfo yanıtındaki bozuk giriş başına tetiklenir, hangi girişin ayrıştırılamadığını adlandırır (böylece kullanıcı örn. "Marantz, bazı kodekler için http-get:*::* döndürdü - yetenek doğrulanmadı, F32'nin geri dönüşü tahmin edecek" görebilir).
  • Activate:NoSinkInfo - cihaz hiç <Sink> öğesi döndürmezse bir kez tetiklenir. SupportedMimeTypes'ın Hiçbir şey kalması ve IsCodecSupported'ın "her şeyin çalıştığını varsay"a düşmesi anlamına gelir - daha sonra "cihaz akışı reddetti" hataları göründüğünde yararlı bağlam.

Neden: F44'ten önce bu sessiz yetenek düşüşleri, kullanıcıların parçalarının neden beklentilerin aksine dönüştürüldüğünü veya cihaz tarafından reddedildiğini tahmin etmelerine neden oluyordu. Artık Activate: için tek bir arama, cihazın yetenek bilgisinin kullanılabilir olup olmadığını gösterir.


F45 - Daha iyi meta veri hata günlüğü

Ne: ContentDirectoryService.vb içindeki Browse istisna günlüğü, önceki yaiol çalışmasında (Alia Vox hata oturumu) ObjectID ve yığın izi ile zaten zenginleştirilmişti. F45, BrowseFlag (meta veri vs çocuklar), Filter (istemcinin hangi öznitelikleri istediği), sortCriteria ve partialResultLength (başarısızlıktan önce kaç bayt DIDL üretildiği - kötü parçanın partide ne kadar ileride olduğunu gösterir) ile daha da genişletir.

Neden: DIDL ortasında bir şeyler ters gittiğinde, kısmi uzunluk değeri, hatanın partinin ilk parçasında mı (kısmi=0) yoksa ortasında mı (kısmi=N) olduğunu söyler - partinin startingIndex'i ile birleştirildiğinde, suçlu parça dizinini tanımlayabilirsiniz. Filtre ve BrowseFlag, istemcinin hangi tür göz atma istediğini açıklar; bazen meta veri odaklı bir göz atma, aynı kimlik için bir çocuk göz atma başarılı olduğunda başarısız olur.


F46 - Otomatik mod yalnızca gerçek ağ bağdaştırıcılarında duyuru yapar

Ne: Otomatik arabirim modunda eklenti daha önce çalışır durumdaki her IPv4 bağdaştırıcısında kendini duyururdu (SSDP). Aynı zamanda bir VPN tüneli (NordLynx) veya sanal anahtar (Hyper-V / WSL / Docker) çalıştıran bir makinede, aynı kitaplık bu bağdaştırıcıların her birinde de duyuruluyordu; bu yüzden yayın yaptığınız kontrol noktası sunucuyu iki veya üç kez keşfediyor ve kitaplığı yinelenen kopyalar olarak listeliyordu. Otomatik mod artık yalnızca gerçek bir IPv4 varsayılan ağ geçidine sahip bağdaştırıcıları tutar (HasIPv4Gateway) - tünel ve sanal anahtar bağdaştırıcılarında bu yoktur - bu yüzden onlar duyuru listesinden çıkarılır. Kullanıcının sabitlediği bir adres yine de her zaman kazanır (yalnızca o arabirimde duyuru yapılır) ve hiçbir bağdaştırıcı bir ağ geçidi bildirmezse seçici tüm bağdaştırıcılara geri döner; böylece duyurulan adres listesi asla boş kalmaz ve eklenti görünmez hale gelemez.

Neden: yinelenme "VPN kullanıyor olmaktan" kaynaklanmaz - LAN bağdaştırıcısında ve tünel/sanal bağdaştırıcıda aynı anda duyuru yapılmasından kaynaklanır; böylece tek bir kontrol noktası aynı sunucuyu iki adreste görür. Tüketici VPN'leri (NordVPN/NordLynx) yalnızca internete giden trafiği tüneller; DLNA oynatıcısı LAN üzerinde yaşar ve yerel alt ağ trafiği tüneli atlar, bu yüzden tünel bağdaştırıcısı zaten hiçbir zaman bir oynatıcıya ulaşmaz - onu çıkarmak hayalet bir kopyayı kaldırır, asla çalışan bir yolu değil. Ağ geçidi testi, gerçek bir LAN/Wi-Fi bağdaştırıcısını bir tünelden veya sanal anahtardan ayıran ucuz ve güvenilir sinyaldir. N05'i tamamlar (bu tür bağlantılarda duyuruların nasıl gönderildiğini düzeltmişti - broadcast yerine multicast); F46 ise en başta hangi bağdaştırıcılarda duyuru yapılacağını belirler.

Bilinen sınırlama: oynatıcıları gerçekten tünelin öbür tarafında yaşayan bir mesh / uzaktan erişim VPN'i (Tailscale, ZeroTier, eve WireGuard) genellikle varsayılan ağ geçidi olmayan bir bağdaştırıcı sunar, bu yüzden Otomatik mod onu da eler. Bu kullanıcılar bunun yerine VPN adresini sabitler; sabitlenen adres ağ geçidi filtresine göre önceliklidir.