MusicBee UPnP Plugin Súgó

Újdonságok

2.0.2 - 2026-07-20

  • Egy sablon nem törölhető, amíg bármelyik csomópont követi – a törlés gomb egyszerűen letiltva marad, így egy csomópont soha nem maradhat árván. Minden sablonsor mostantól élő (n) számot mutat a követőiről, ami egy pillantással megmagyarázza a letiltott törlést; egy nem használt sablon törlése mostantól megmarad, ahelyett, hogy a szállított alapértelmezések csendesen újra megjelennének a következő betöltéskor.
  • Egy új tölcsér gomb a Nézet fa mellett pontosan megmutatja, mely csomópontok követnek egy sablont: szűri a fát a kiválasztott sablon követőire, újra szűr, ahogy más sablonokat választ ki, és visszaállítja a teljes fát, amikor kikapcsolja.
  • A Rádió és Podcastok csomópontok mostantól tartósan párosítva vannak kategóriájuk sablonjával – alakítsa át a sablont az Elérési utak lapon, és a csomópont magától követi; nincs mit alkalmazni, így az Alkalmaz gomb le van tiltva számukra. A sablonlista ezt két sávval tükrözi: Standard (ahol minden új sablon létrejön) és Fenntartott (Rádió + Podcastok).

2.0.1 - 2026-07-20

  • Az útvonalsablonok mostantól élőben kapcsolódnak az őket használó csomópontokhoz. Egy sablon alkalmazása a csomópontot követi: később szerkeszti a sablont, és minden azt követő csomópont azonnal átalakul – nem kell megkeresni és csomópontonként újra alkalmazni. A Nézet fa megmutatja, hogy melyik sablont követi az egyes csomópontok közvetlenül a nevük után, az átnevezés azonnal megjelenik ott, és egy sablon törlése először megmondja, hány csomópont követi azt (megtartják aktuális elrendezésüket, és egyszerűen abbahagyják bármi követését).
  • Egy sablon alkalmazása egy rejtett csomópontra ismét láthatóvá teszi azt – az alkalmazás a „mutasd meg ezt, így alakítva” gesztus, míg az elrejtés a Látható jelölőnégyzettel marad. Az ezt felváltó „Rejtett” fenntartott sablon megszűnt.
  • A Nézet fa többé nem veszíti el a helyét: a pipák, a kibontott mappák és a görgetési pozíció mind túlélik a sablonok alkalmazását és más frissítéseket.

2.0.0 - 2026-06-16

Ez a MusicBee UPnP beépülő modul nyílt forráskódú yaiol elágazásának első nyilvános kiadása. Két részből áll: minden, ami új ebben az elágazásban, majd az eredeti beépülő modulon végrehajtott javítások és fejlesztések. Minden tétel megőrzi a projekt belső funkciókatalógusának Mi / Miért formáját, így minden változás mögötti indoklás is megtalálható az oldalon, nem csak maga a változás.

Újdonságok ebben az elágazásban

MediaRenderer - lejátszás MusicBee-re

N01 - MusicBee mint lejátszási cél (renderer)

Mi: normális esetben ez a beépülő modul egyirányúan működik: egy telefon vagy más eszköz böngészi a MusicBee könyvtárát, és saját magán játssza le a zenét. Ez a funkció hozzáadja az ellenkező irányt is – lehetővé teszi, hogy a MusicBee legyen a lejátszó. A telefonján lévő vezérlő alkalmazásból (például a BubbleUPnP-ből) kiválaszthatja az asztali MusicBee-t lejátszási célként, majd onnan vezérelheti: lejátszás, szüneteltetés, leállítás, előre- vagy visszaugrás, ugrás egy pontra a számban, valamint a hangerő módosítása vagy némítás.

Miért: telefonját távirányítóvá alakítja a számítógépén már meglévő zenékhez. Üljön le a kanapéra, böngéssze könyvtárát a telefonján, koppintson egy számra, és az az asztali gépéhez csatlakoztatott hangszórókból szólal meg – teljes vezérléssel onnan, ahol éppen ül. Az eredeti beépülő modul soha nem szállította ezt működő funkcióként.

Bekapcsolás: alapértelmezetten ki van kapcsolva, mert bekapcsolása lehetővé teszi, hogy bármi az otthoni hálózatán elindítsa a lejátszást a számítógépén. A beállítások párbeszédpanel Általános lapján található jelölőnégyzettel engedélyezheti. A beépülő modul három szerepe mindegyikének saját jelölőnégyzete van ott – könyvtáram megosztása (Server), engedélyezze másoknak, hogy rám játsszanak (Renderer), és lejátszás más eszközökre (Control Point) – és a párbeszédpanel csak azokat a beállítási lapokat mutatja, amelyekre az engedélyezett szerepeknek valóban szükségük van, így soha nem szembesül olyan opciókkal, amelyek nem vonatkoznak Önre.

Gépek megkülönböztetése: a renderelőnek bármilyen nevet adhat (alapértelmezetten „MusicBee (yaiol)”). Ez a név jelenik meg a telefonja lejátszási célpontjainak listájában, így ha több számítógépen is fut a MusicBee, meg tudja különböztetni, melyik melyik. A névváltoztatás azonnal életbe lép, újraindítás nélkül.

Legjobb hangminőség, amikor saját magára játszik: amikor a telefonjáról böngészi a MusicBee saját könyvtárát, és egy számot visszaküld ugyanarra a MusicBee-re, a beépülő modul felismeri, hogy a saját fájljainak egyikét kérik lejátszani, és egyszerűen közvetlenül a lemezről játssza le. Az eredmény pontos és azonnali – bit-perfect, a MusicBee saját hangszínszabályzójával és hangerő-kiegyenlítésével alkalmazva – ahelyett, hogy feleslegesen kiküldené a hangot a hálózatra, majd azonnal vissza saját magának.

Privát futtatás: a három szerep függetlenül működik, így bekapcsolhatja a renderelőt, miközben a könyvtármegosztás ki van kapcsolva. Ebben a „csak renderelő” beállításban a könyvtára teljesen rejtve marad a hálózat elől – csak a lejátszási célpont kerül bejelentésre – és a MusicBee soha nem fogja felajánlani, hogy saját magára játsszon.


Lejátszási viselkedés

N02 - 5.1 FLAC nem kerül automatikusan sztereóvá keverésre

Mi: a csatornaszám korlátozása a MediaServerDevice.GetEncodedFile függvényben If StereoOnly OrElse Not isPcmData Then channelCount = 2 volt. A Not isPcmData záradék minden nem-PCM átkódolást (FLAC, MP3, AAC, Ogg) csendesen sztereóvá kevert, függetlenül a forrás csatornaszámától, így a 5.1-képes renderelők nem működtek megfelelően, ha a forrás 5.1 FLAC volt. Most a második záradék kizárja a FLAC-ot: Not isPcmData AndAlso encoder.Codec <> FileCodec.Flac. A FLAC 5.1 átmegy; az MP3/AAC/Ogg továbbra is kényszerített sztereó, mert a MusicBee parancssori kódolói ezekhez a formátumokhoz 2 csatornás bemenetet várnak.

Miért: a 5.1 FLAC forrás FLAC kimenetté történő átkódolásának lényege a többcsatornás keverés megőrzése. A csendes sztereóvá keverés a FLAC átkódolási opciót használhatatlanná tette a térhatású zenehallgatáshoz. Az N02-vel a helyes dolgot teszi.


Architektúra

Az a strukturális változás, amely az elágazást nagy könyvtárakon is életképessé teszi – hiányzott az eredeti beépülő modulból.

N03 - Lusta (igény szerinti) böngészési fa

Mi: az eredeti beépülő modul a MusicBee indításakor építette fel a teljes böngészési fát – minden szám felsorolása, teljes Library_GetFileTags fájlonként, a teljes tároló hierarchia összeállítása – mielőtt megnyitotta volna a HTTP portot. Egy valós könyvtár (50 ezer+ szám, 5400 podcast epizód, több száz rádióállomás) esetén ez percekig tartó hidegindítást jelent, és a fa örökké a RAM-ban marad, beleértve azokat az ágakat is, amelyeket egyetlen kliens sem nyit meg. Ez az elágazás semmit sem épít előre: a gyökér egy L: előtaggal ellátott helyőrzőt tesz közzé végpontonként (L:music, L:podcast, L:filter:…); minden szintet csak akkor számít ki, amikor egy kliens beleböngész (LazyBrowseEnsureLazyEndpointInMemory → szintenkénti gyorsítótárak), és a könyvtárváltozási értesítések törlik a gyorsítótárakat (SetLibraryDirty).

Miért: a hidegindítás lényegében azonnali – a HTTP port nyitva van, mire a MusicBee befejezi a beépülő modul inicializálását – és a memória arányos marad a böngészett tartalommal, nem a könyvtár méretével. Kompromisszum: az első böngészés egy végpontba megfizeti a betöltési költségét; az újbóli belépés gyorsítótárazva van a következő könyvtárváltozásig. Ez az alapja mindennek, ami erre épül. Teljes jegyzetek: FIXES.md.


Hálózat és robusztusság

Az HTTP szerver kötési útvonalának megerősítése. Az eredeti beépülő modul csendesen leáll, ha a portja nem elérhető.

N04 - Öngyógyító HTTP portkötés

Mi: a beépülő modul HTTP szervere többé nem áll le, ha a konfigurált portja nem elérhető. Három kapcsolódó változás:

  1. Automatikus visszalépés kötési hiba esetén. Az HttpServer.Start megpróbálja a konfigurált portot, és SocketException esetén felfelé akár 20 portot is átvizsgál az első szabad portért. A ténylegesen kötött port egy új Plugin.boundServerPort mezőben kerül rögzítésre, és minden, ami a szervert hirdeti – SSDP LOCATION URL-ek (NOTIFY + M-SEARCH válasz), az eszköz URL-je (PrimaryHostUrl), a router porttovábbítása, valamint az SSDP/vezérlőpont önszűrői – mostantól a boundServerPort értéket olvassa a Settings.ServerPort helyett. Az UPnP kliensek az SSDP-n keresztül fedezik fel a valódi portot, így egy áthelyezett port átlátszó a renderelők számára.
  2. Felhasználói értesítés. Ha visszalépés történik (a mentett port nem az, amelyik használatban van), egy lokalizált MessageBox (WarnPortInUse) tájékoztatja a felhasználót, hogy melyik port szolgálja ki valójában, és hogy az eszközök továbbra is megtalálják – mivel a beépülő modul fej nélkül fut, és egy párbeszédpanelen belüli üzenetet csak az látna, aki már gyanított valamilyen problémát.
  3. Újraindítási helyreállítás. A RestartServer (a beállítások mentési újraindítási útvonala) korábban vakon dereferálta a Plugin.controller / Plugin.server objektumokat. Ha a kezdeti Initialise kivételt dobott, mielőtt létrehozta volna őket (pontosan ezt okozta egy sikertelen kötés), a következő beállításmentés NullReferenceException-t eredményezett – egy félig halott beépülő modult hagyva maga után. Mostantól újra létrehozza és elindítja őket, ha Nothing, így egy működő port mentése újraéleszti a beépülő modult teljes MusicBee újraindítás nélkül.

Miért: a kiváltó ok egy valós felhasználói eset volt. A régi alapértelmezett 49382 port a Windows dinamikus tartományában (49152-65535) található, ahol a Hyper-V/WSL2/Docker/WinNAT nagy blokkokat foglal le, amelyek minden rendszerindításkor eltolódnak – így a kötés WSAEACCES („hozzáférés megtagadva”) hibával meghiúsult egy olyan gépen, ahol hónapokig működött. Az alapértelmezett port szabad portra történő módosítása ezután ütközött a Serviio-val (egy külön DLNA szerverrel, amely már az új porton volt), WSAEADDRINUSE hibával meghiúsulva. Minden hiba elnyelődött az Initialise során, csendesen halottá téve a beépülő modult, majd NRE-t okozva a következő beállításmentéskor. Az N04 után a portütközés öngyógyul – a szerver a következő szabad porton fut tovább, a felhasználó értesítést kap, és a kliensek újra felfedezik – ahelyett, hogy az egész beépülő modult leállítaná.

Megvalósítás:

  • Az alapértelmezett port áthelyezve 493829779 (a dinamikus tartomány alatt, így a Windows soha nem foglalja le automatikusan; nem ismert médiaszerver alapértelmezett portja) mindhárom ServerPort deklarációban + a beállítások elemzési hibájának visszalépésében.
  • A Plugin.boundServerPort (új megosztott mező) tárolja az élő figyelő portot; az activeServerPort marad a konfigurált pillanatkép, így az „Újraindítás szükséges” jelvény logikája nem tévesen aktiválódik visszalépés esetén.
  • HttpServer.PortScanRange = 20; a vizsgálat az első sikeres TcpListener.Start() hívásnál leáll, és csak akkor dobja az utolsó kivételt, ha minden kísérlet sikertelen.
  • Új EN erőforráskulcs WarnPortInUse (a fordítások a közzétételi időpont szerinti lokalizációs lépést követik).

N05 - SSDP bejelentések a multicast csoporton keresztül (VPN / pont-pont)

Mi: az SSDP bejelentések az UPnP multicast csoportnak (239.255.255.250) kerülnek elküldésre IP broadcast cím helyett. A szerver újraindításával versengő SSDP keresési válasz esetén naplózott ártalmatlan „cannot access a disposed object” hiba is elnyomásra kerül.

Miért: pont-pont / VPN hálózati adaptereken az IP broadcast nem alkalmazható – a régi broadcast küldés „invalid argument” hibával meghiúsult, és a bejelentések kimaradtak, így a beépülő modul láthatatlan volt az ezeken a linkeken lévő kliensek számára. A megfelelő multicast csoportnak történő bejelentés pontosan ezeken az adaptereken javítja a felfedezést.

Könyvtár navigáció

Ezek ebben az elágazásban kerültek szállításra, és nem szerepelnek az eredeti beépülő modulban. Valós UPnP kliensekből származó, a beépülő modul saját kimenetének tényleges böngészéséből származnak.

N06 - Szűrő alapú könyvtár megjelenítés

Mi: a MusicBee szűrőfülei (a felhasználó MusicBee mappájában található .xautopf fájlok) UPnP gyökérkonténerekké válnak a beépülő modul könyvtárában. Az egyes szűrők számai ezután böngészhetők az AlbumArtistSort → Album → Tracks hierarchiában.

Miért: a gondosan összeállított MusicBee szűrőkkel rendelkező felhasználók (pl. „5 csillagos számok”, „Nemrég hozzáadott”, „Klasszikus → Barokk”) elvárják, hogy megtalálják ezeket, amikor UPnP kliensből böngészik a beépülő modult. Az eredeti beépülő modul csak a nyers könyvtárfát tette közzé.


N07 - SortAlbumArtist mező bekötése

Mi: a beépülő modul mostantól olvassa a MusicBee MetaDataType 165 (Album előadó rendezése) mezőjét, és ezt használja az előadók csoportosítására/rendezésére a böngészési nézetekben.

Miért: a hi-fi böngészők és az audiofilek rendezési előadóneveket („Beethoven, Ludwig van” a „Ludwig van Beethoven” helyett) használnak a könyvtárak rendszerezésére. Ez a komoly zenehallgatók alapvető elvárása. Mindkét upstreamből hiányzott.


N08 - Többértékű AlbumArtist kezelés

Mi: ha egy album AlbumArtist mezője több előadót tartalmaz "; " elválasztóval (pl. „yaiol; Ars Ricercata”), a szám mostantól minden előadó alatt megjelenik a böngészési nézetekben, nem pedig egyetlen, a neveket kombináló Frankenstein előadó alatt.

Miért: az együttműködési albumoknak és válogatásoknak minden közreműködő alatt meg kell jelenniük. Enélkül az album megtalálásához vezető keresési útvonalak fele hibás.


N09 - Albumkonténer borítóképe (upnp:albumArtURI)

Mi: a DIDL böngészési válaszokban az albumkonténer csomópontok mostantól tartalmaznak egy upnp:albumArtURI elemet, amely az album borítójára mutat.

Miért: enélkül minden album egy UPnP kliens böngészési nézetében általános ikont mutat az album borítója helyett. Vizuális támpont a navigációhoz; minden modern hi-fi böngésző elvárja.


N10 - Számok sorrendje a szűrőalbumokon belül

Mi: a szűrővel megjelenített albumon belüli számok mostantól lemezszám, majd számszám szerint vannak rendezve.

Miért: szabványos albumsorrend. Explicit rendezés nélkül a számok abban a sorrendben tértek vissza, ahogyan a szűrő éppen visszaadta őket – általában véletlenszerűnek tűntek.


N11 - Lejátszási lista mappa fa javítása

Mi: a LoadLibraryPlaylists függvény (eredetileg Steven Mayall, ~2014) nem tudott belépni az újonnan létrehozott lejátszási lista mappákba. Minden mappában az első lejátszási lista, plusz az összes almappa, árván maradt a gyökérszinten.

Miért: tizenegy éve jelen volt az eredeti beépülő modulban. Látható volt 30 másodpercen belül, miután megnyitotta a BubbleUPnP-t és rákattintott a Lejátszási listákra. A yaiolban javítva azáltal, hogy a fa felépítése során helyesen rekurzívan belép az újonnan létrehozott mappákba.


N12 - XML-ben illegális vezérlőkarakterek tisztítása

Mi: bármely olyan szám, amelynek címkéje C0 vezérlőkaraktert tartalmazott (pl. 0x19 egy rossz kódolási lépésből – UTF-8 → Latin-1 → visszafelé csonkítva 0x99-et 0x19-re), az egész böngészési válasz Action Failed hibával meghiúsult, amint a hibás szám bekerült egy lapozott kötegbe.

Miért: az XML 1.0 tiltja a legtöbb C0 vezérlőkaraktert, és az XmlWriter kivételt dob, ha ilyet kérnek tőle. Jelen volt az eredeti beépülő modulban. Javítva az érvénytelen karakterek eltávolításával minden Library_GetFileTags kilépési ponton az XmlConvert.IsXmlChar segítségével.


N13 - Rádiólistázás determinisztikus a lapozott böngészés során

Mi: a Rádió konténer böngészése a generikus fájllista ágba esett, amely minden híváskor meghívta a files.Sort(AlbumFileComparer) függvényt. A rádióbejegyzések üres Album/Disc/Track címkékkel rendelkeznek, így minden összehasonlítás 0-t adott vissza – a List(Of T).Sort instabil, minden meghíváskor más sorrendet produkálva. Az UPnP vezérlőpontok lapoznak (a BubbleUPnP 0..15-öt, majd 16..végét tölti be); a két hívás között a lista átrendeződött, így egyes állomások mindkét oldalon megjelentek (duplikátumok), mások pedig egyikben sem (hiányzók) – minden frissítéskor véletlenszerűnek tűntek.

Miért: jelen volt az eredeti beépülő modulban (szerzője soha nem böngészett rádiót UPnP-n keresztül). Itt javítva egy dedikált ContainerCategory.Radio ággal a Browse függvényben, hívásonkénti rendezés nélkül; a radioFiles egyszer rendeződik betöltéskor Cím szerint (stabil). A lapozott böngészés mostantól determinisztikus sorrendet lát; az 1. és 2. oldal diszjunkt.


N14 - UPnP keresés albumosztályra albumkonténereket ad vissza

Mi: az UPnP keresés albumosztályra vonatkozó lekérdezések (upnp:class = "object.container.album.musicAlbum", pl. a BubbleUPnP „Véletlenszerű albumok” funkciója) az albumkonténerek helyett a teljes számlistát adta vissza, így a kliens nulla albumot mutatott. Az eredeti kezelő csak a zárójelezett kritériumokat elemezte, majd az összes számot kiírta, függetlenül a kért osztálytól.

Miért: itt javítva – az albumosztályra vonatkozó lekérdezések mostantól különálló albumokat sorolnak fel (AlbumArtist+Album szerint csoportosítva), és mindegyiket megfelelő musicAlbum konténerként adják ki borítóképpel, a Salb<idx> virtuális azonosító térrel címezhetően, így a kliens belefúrhat egy eredménybe és lejátszhatja azt.


N15 - Működő, hatókör-tudatos UPnP keresés kattintható eredménnyel

Mi: az eredeti nem hirdetett keresési képességeket (GetSearchCapabilities üresen tért vissza), így a kliensek még keresést sem voltak hajlandóak küldeni; a régi backend pedig a musicFiles fájlból olvasott, amely a lusta fa korszakában tartósan üres volt. Ez az elágazás hirdeti a valós kereshető tulajdonságokat, implementálja a számok cím szerinti és az albumok cím szerinti keresését a lusta könyvtár ellen (HandleLazySearch), hatókörbe helyezi a lekérdezést a kliens aktuális ágára, ha valós konténerazonosító kerül elküldésre (ellenkező esetben L:music-ra helyettesít, így a felső sávos keresések nem vonzzák be a podcast/rádió/hangoskönyv zajt), és az album eredményeket kattinthatóvá teszi szintetikus Ssrch_alb_* azonosítókon keresztül, amelyeket egy Browse korai ág visszatérít az album számaihoz. (Az albumosztály-eredmények konténerként való megjelenítése az N14.)

Miért: a BubbleUPnP-ben a keresés a „Könyvtár nem támogatja a keresést” állapotból hasznos, hatókörbe helyezett, lejátszható eredményeket adóvá vált. Teljes tervezés + elutasított megközelítések: SEARCH.md.


N16 - UPnP gyorsítótár érvénytelenítése (SystemUpdateID)

Mi: az eredeti állandó SystemUpdateID=0 értéket adott vissza – az UPnP ContentDirectory gyorsítótár-érvénytelenítési szerződését –, így a specifikációnak megfelelő kliensek (BubbleUPnP) soha nem változóként kezelték a könyvtárat: elavult böngészési eredmények, 404-es miniatűrök URL-séma változás után, és a „kétszer indítsa újra a MusicBee-t a változások megtekintéséhez” tánc. Ez az elágazás a SystemUpdateID-t epoch-másodpercekből inicializálja betöltéskor (így minden újraindítás szigorúan megelőzi az előzőt), és minden könyvtárváltozás és beállításmódosítás esetén növeli (SetLibraryDirty / ResetCacheBumpSystemUpdateId).

Miért: a kliensek megbízhatóan felveszik a szerkesztéseket, új fájlokat és beállításváltozásokat a következő böngészésükkor. Ismert korlát: az előfizetett kliensek nem kapják meg aktívan az új értéket GENA-n keresztül (jövőbeli munkaként parkolva); továbbra is látják a következő böngészésükkor.


N17 - Podcast feliratkozás borítóképe

Mi: a podcast csempék nem mutattak képeket – minden /PodcastThumbnail/ kérés 404-es hibát adott. Két egymásra épülő hiba: a feloldási lánc soha nem ellenőrizte a MusicBee tényleges borítókép gyorsítótárát (%LocalAppData%\MusicBee\InternalCache\Subscriptions\<name>.jpg, ahonnan az asztali felhasználói felület betölt), és a HTTP réteg unescape+kisbetűsítése a feed-URL útvonalkulcsot az utolsó útvonalszegmenséig eltorzította. Ez az elágazás az MB InternalCache-ből oldja fel a borítóképeket, és a kereséseket egy URL-biztos slugon keresztül irányítja, amely sértetlenül túléli a HTTP réteget (PodcastSlug / podcastSubIdBySlug).

Miért: a feliratkozási borítóképek mostantól megjelennek a böngészési nézetekben (mind a 22 korábban 404-es hibát adó kérés feloldódik).


N18 - Hierarchikus (elválasztóval tagolt) címkeböngészés

Mi: bármely mező megjelölhető hierarchikusként a Könyvtárbeállítások lapon, és kaphat egy egykarakteres elválasztót (egy mezőválasztó + elválasztó mező hozzáadással/eltávolítással, amely a beépülő modul beállításaiban megmarad). Állítsa a Csoportosítást /-re, és egy olyan érték, mint a Jazz/Cool Jazz ezután Jazz › Cool Jazz-ként böngészhető egyetlen lapos bejegyzés helyett. A pontosan egy ágon (csak Jazz) címkézett számok saját [Jazz] csomópontot kapnak, így semmi sem rejtőzik el, egyetlen gyermekkel rendelkező ág önmagában összeomlik, és a ; elutasításra kerül elválasztóként, mert az a MusicBee saját többértékű elválasztója.

Miért: a felhasználó által már egyetlen mezőbe kódolt mély címke taxonómiák (műfafák, hangulathierarchiák, „Klasszikus/Barokk/Concerto”) végre a címke által leírt faként böngészhetők, ahelyett, hogy a felhasználónak végig kellene olvasnia a perjelekkel elválasztott karakterláncok lapos falát.


N19 - Egyetlen gyökérútvonal, csoportosító mezője szerint címkézve

Mi: a gyökérben lévő egyetlen böngészési útvonalat a csoportosító mezője (pl. „Műfaj”) címkézi, nem pedig a teljes rövid útvonala, ami megegyezik az összevont első mezőcsoportok elnevezésével.

Miért: a böngészési fa konzisztensen olvasható – egyetlen elnevezési szabály, függetlenül attól, hogy egy gyökérbejegyzés önállóan áll, vagy testvérekkel (N20) összevonásra került – ahelyett, hogy egy magányos gyökérbejegyzés részletes belső útvonalat mutatna, miközben összevont szomszédai tiszta mezőnevet mutatnak.


N20 - Böngészési útvonalak egyesítése, amelyeknek az első mezője megegyezik

Mi: két böngészési útvonal, amelyeknek az első mezője megegyezik – „Műfaj / Album előadó rendezése” és „Műfaj / Podcast személyek” – egyetlen Műfaj gyökérmappába omlanak össze, amely először a műfajértékeket listázza, majd két nézetre oszlik, ahelyett, hogy két majdnem duplikált „Műfaj / …” bejegyzés lenne egymás mellett a gyökérben.

Miért: egy felhasználó, akinek több kapcsolódó nézete volt egy közös mező alá ágyazva, azt látta, hogy a gyökér tele van szinte azonos felső szintű bejegyzésekkel. Az egyesítésük olvashatóvá teszi a gyökeret, és csoportosítja a kapcsolódó nézeteket oda, ahová tartoznak – a közös mezőjük alá.


N21 - Kategória-típusú böngészési útvonalak (Standard / Rádió / Podcast)

Mi: minden böngészési útvonal kategória szerint van típusozva – Standard, Rádió vagy Podcast. A sablonlista ebbe a három szakaszba van csoportosítva, minden sablon mezőválasztója csak azokat a mezőket kínálja, amelyeket az adott kategória adatai ténylegesen szolgáltatni tudnak, és egy sablon csak a Nézet fában lévő megfelelő csomópontokra alkalmazható (az inkompatibilis csomópontok szürkén jelennek meg, és nem jelölhetők be). A fenntartott Rádió és Podcast sablonok nem törölhetők, így kategória szakaszuk soha nem tűnik el.

Miért: a típusozás nélkül a felhasználó olyan elrendezést építhetne, amely csendesen üresen jelenik meg – egy rádióállomásnak nincs „albuma”, egy podcast epizódnak nincs „album előadója” – és csak úgy fedezné fel, ha egy UPnP kliensből egy halott mappába böngészne. A mezőmenü és az alkalmazási célok korlátozása a kategória valós adataira megakadályozza az üres elrendezések létrehozását.


N22 - Podcastok csoportosítása megjelenési év szerint

Mi: minden podcast epizód megjelenési dátuma beolvasásra kerül, így egy Év szinttel rendelkező podcast böngészési útvonal év szerint csoportosítja az epizódokat, ahelyett, hogy egyetlen „Ismeretlen” alá vonná össze őket.

Miért: a nagy podcast feliratkozások év szerint navigálhatóvá válnak, mint a könyvtár többi része, ahelyett, hogy minden epizód egyetlen dátum nélküli halomba kerülne, mert a beépülő modul soha nem nézte meg az epizódonkénti megjelenési dátumot.


N23 - Egyetlen eredményt adó csoportosítási szintek összevonása

Mi: egy olyan csoportosítási szint, amely egyetlen értékre oldódik fel – egy Felvétel típusa szint, amely csak „LP”-t mutat egy olyan előadó számára, aki csak LP-ket készített, vagy egy betűszint egyetlen betűvel – automatikusan átugrásra kerül, egyenesen a tartalmába juttatva a felhasználót.

Miért: egy olyan mappán keresztül böngészni, amely pontosan egy mappát tartalmaz, tiszta súrlódás. Az egyetlen választási szint összevonása eltávolítja a felesleges kattintást anélkül, hogy megváltoztatná, mit érhet el a felhasználó.


N24 - Év szerinti csoportosítás/keresés a MusicBee dátummezője alapján

Mi: az év feltétel többé nem kérdezi le a MusicBee teljes dátum „Év” mezőjét egy csupasz négyjegyű értékkel, és a hardkódolt évmező aliasozás megszűnt, így minden csoportosítási mező mostantól generikusan feloldódik az útvonaldefinícióból.

Miért: azoknál a könyvtáraknál, amelyek Év címkéje teljes dátumot tartalmaz, az év szerinti csoportosítás vagy keresés korábban semmit sem adott vissza – a négyjegyű lekérdezés soha nem egyezett meg a teljes dátum mezővel. A megfelelő mező lekérdezése újra megtalálja a számokat az év szerinti csoportosítás és keresés során.


N25 - Külön „Év” és „Év (éééé)” csoportosítási mezők

Mi: az album csoportosítási és böngészési útvonalai mostantól a MusicBee saját év mezőit is közzéteszik – Év (a teljes dátum címke) és Év (éééé) (csak a négyjegyű év) – így a felhasználó választhat közülük, amikor album csoportosítást vagy böngészési útvonalat definiál.

Miért: a két mező különböző dolgokat jelent a MusicBee-ben, és az összevonásuk elvesztette ezt a különbséget. Mindkettő megjelenítése lehetővé teszi a felhasználó számára, hogy egy év összes kiadását együtt gyűjtse (éééé) vagy megtartsa a pontos dátum szerinti sorrendet (teljes Év címke), ahogy szándékozik.


N32 - A rögzített szűrők és lejátszási listák fajtájuk szerint csoportosítva a gyökérben

Mi: egy rögzített szűrő mostantól közvetlenül a Szűrők mappa alatt jelenik meg a böngészési gyökérben, egy rögzített lejátszási lista pedig közvetlenül a Lejátszási listák mappa alatt, ahelyett, hogy az összes rögzítés egyetlen csomóban gyűlne a gyökér végén. Minden rögzített parancsikon a saját fajtájával együtt áll.

Miért: ahogy egyre több parancsikont rögzítesz, a szűrők és lejátszási listák egyetlen, kevert záró csomója egyre nehezebben áttekinthető, és minden parancsikont elválaszt attól a mappától, amelyhez tartozik. A rögzített elemek saját kategóriájuk alá csoportosítása olvashatóan tartja a gyökeret, és minden parancsikont azok mellett tart, amelyekhez tartozik.

Beállítások párbeszédpanel és csomagolás

N26 - Szakaszokra osztott beállítások párbeszédpanel

Mi: a Beállítások oldal bal oldali navigációs elrendezést kapott szakaszokkal: Általános / Lejátszás / Könyvtár / Eszközprofilok / Diagnosztika.

Miért: az eredeti egyetlen hosszú, lapos lista volt minden beállításról – rendben volt annak a fejlesztőnek, aki építette, de zavaró volt mindenki más számára. A szakaszolás csoportosítja a kapcsolódó opciókat, és a párbeszédpanelt modernebb alkalmazásbeállításokhoz hasonlóvá teszi.


Assembly + beépülő modul átnevezése (nincs F-azonosító – csomagolási megjegyzés)

Mi: a lefordított DLL neve mb_UPnP_yaiol.dll, és a beépülő modul „MusicBee UPnP (yaiol)” néven jelenti magát. Eltér az eredeti mb_Upnp.dll fájltól.

Miért: a felhasználók telepíthetik a yaiol-t az eredeti beépülő modul mellé, és összehasonlíthatják a viselkedést egymás mellett.


Jelvényrendszer – futásidejű állapot megjelenítése (az F40 mögötti mechanizmus)

Mi: egy általános felhasználói felületi minta a fontos futásidejű feltételek látható, színes jelvényekként való megjelenítésére a Beállítások párbeszédpanelen. Jelenlegi példák:

  • ⚠ Max Conn (N04) - akkor aktiválódik, ha a maximális kapcsolatok korlátját legalább egyszer elérték a MusicBee indítása óta. Ragaszkodó munkamenet jelző Plugin.MaxConnectionsHit. Beállítva a WaitOnSendBarrier belsejében, ha nincs szabad hely.
  • ⚠ Újraindítás szükséges - akkor aktiválódik, ha egy mentett beállítás MusicBee újraindítást igényel az érvénybe lépéshez. Ragaszkodó munkamenet jelző Plugin.RestartRequired. Beállítva a párbeszédpanel Mentés kezelőjében, ha az új tartósított érték eltér a futásidejű pillanatképtől (Plugin.activeMaxConnections, Plugin.activeServerPort, Plugin.activeIpAddress). Az újraindítást igénylő beállítások azokra korlátozódnak, amelyek valóban nem tudnak hot-reload-ot – HTTP szerver kötési paraméterek és az egyszer az Initialise-nél felépített SemaphoreSlim.

Miért: a beépülő modul naplófájlja rendben van a technikai felhasználók hibakereséséhez, de egy nem technikai felhasználó, aki „az eszköz rosszul szól” vagy „a lejátszás lassú” problémával szembesül, soha nem fogja megnyitni a Diagnosztika → Napló megtekintése menüpontot. A jelvények rögzítik azokat az eseteket, amikor a felhasználónak tudnia kell, hogy valami történt, és megjelenítik azt, amikor legközelebb megnyitja a beépülő modult – felfedezhető anélkül, hogy bármit is olvasna.

Jövőbeli felhasználásra újrahasznosítható:

  • Profil eltérés észlelve (az eszköz felhasználói ügynöke soha nem egyezett egyetlen profillal sem, visszalépett az Általánosra).
  • NextURI visszalépés aktiválódott (F13 - a réstelen lejátszás letiltva a munkamenetre egy hibás eszközön).
  • Könyvtár szkennelés sikertelen / részleges.
  • Renderelő kapcsolat elveszett a munkamenet közepén.
  • Bármely más feltétel, ahol a „egyszer megtörtént, a felhasználónak tudnia kell” felülírja a „csendesen naplózva 1000 másik sor között” esetet.

Megvalósítási konvenciók:

  • A jelvénycímkék a párbeszédpanel szintjén helyezkednek el (nem bármely panelen belül), így láthatók, függetlenül attól, hogy a felhasználó melyik szakaszon van.
  • Az alsó sorban, a Mentés/Mégse gombok közelében helyezkednek el (jelenleg: y=410 vízszintesen egymásra rakva).
  • Minden jelvénynek van egy megfelelő ragaszkodó munkamenet jelzője a Plugin-ben, amely Igazra vált, ha a feltétel bekövetkezik, és csak a MusicBee újraindításakor áll vissza.
  • Erőforrások: <Condition>Badge (címkeszöveg, előtaggal ⚠) + <Condition>BadgeTip (eszköztipp, amely elmagyarázza az okot + a megoldást).
  • A „mentett beállítás újraindítást igényel” jelvényekhez készítsen futásidejű pillanatképet a Plugin.Initialise()-nél, és hasonlítsa össze a Settings.* értékekkel a Settings.SaveSettings() után a párbeszédpanel Mentés kezelőjében.

N27 - A Mégse gomb elveti az útvonal/sablon szerkesztéseket

Mi: a beállítások párbeszédpanelen az útvonalakon és sablonokon végrehajtott szerkesztések mostantól elvetésre kerülnek, amikor a felhasználó a Mégse gombra kattint, ahelyett, hogy csendesen alkalmazva maradnának, és minden munkamenet során eltávolított fenntartott sablon újra létrehozásra kerül. (A sablonok egyébként élőben mentődnek, ahogy szerkesztik őket – nincs külön Mentés gomb az Útvonalak lapon.)

Miért: a Mégse gombnak azt kellene jelentenie, hogy mégse. Korábban egy felhasználó, aki útvonal/sablon változtatásokkal kísérletezett, és visszalépett, azt tapasztalta, hogy a változtatások már elkötelezettek voltak, és nem volt módja visszavonni őket, hacsak nem tette meg mindegyiket kézzel újra.


N28 - Szó szerinti ampersandok a mezőválasztó menüben

Mi: egy olyan mező, amelynek neve „&” jelet tartalmaz – pl. „Hangulat & Kontextus” – szó szerint jeleníti meg az ampersandot a mezőválasztó menüben, ahelyett, hogy Alt-mnemonikus előtagként elnyelné.

Miért: az ampersandot tartalmazó mezőnevek hibásan jelentek meg (a karakter eltűnt, és a következő betű gyorsbillentyűvé vált), ami megnehezítette a menübejegyzés felismerését.


N29 - Stabil, fordítatlan beállítások ablak címe

Mi: a beállítások ablak címe rögzítve van a „MusicBee UPnP Plugin” márkanevű karakterlánchoz, és többé nem változik az interfész nyelvével; a nyelvenkénti DialogTitle karakterlánc minden területi csomagból el lett távolítva.

Miért: egy ablakcím, amely nyelvenként változott, egy fordítható felület volt, haszon nélkül – a cím egy márkajelzés. A rögzítése stabil és konzisztens marad mindenhol.

Lokalizáció

Az eredeti beépülő modul csak angol nyelvű. Ez az elágazás teljesen lokalizálható – minden felhasználói felületen megjelenő karakterlánc egy erőforráscsomagon keresztül áramlik, és a beépülő modul automatikusan felismeri a MusicBee saját felhasználói felületének nyelvét.

N30 - Többnyelvű felhasználói felület (fordítások függőben)

Mi: a lokalizációs mechanizmus elkészült és szállítva van. A Localisation.vb beolvassa a MusicBee kiválasztott nyelvét a MusicBee3Settings.ini fájlból (<SystemLanguage> endonim) és alkalmazza a megfelelő .NET kultúrát a szálra, így a My.Resources.Resources.* a lokalizált karakterláncot adja vissza. Minden felhasználói felületen megjelenő címke/gomb/üzenet egy erőforráskulcshoz van kötve (tervezői vezérlők az ApplyDesignerExtras + sync-en-locale.js segítségével; futásidejű karakterláncok, mint a WarnPortInUse kézzel hozzáadva). Ami még nem készült el, az a tényleges fordítás: csak az angol forráscsomag (Resources.resx) létezik – a többi nyelvhez tartozó műholdas csomagok egyetlen kötegelt lépésben készülnek el, amikor a beépülő modul funkcionálisan teljes (a részleges fordítás, miközben a karakterláncok még változnak, felesleges erőfeszítés).

Célnyelvek (a MusicBee által kínált készlet, 1:1 arányban illeszkedik az endonymToCulture által, így a beépülő modul automatikusan követi a MusicBee nyelvét):

Arabic (ar) Czech (cs) Deutsch (de) Greek (el)
Español (es) Français (fr) Hungarian (hu) Italiano (it)
Korean (ko) Nederlands (nl) Norsk (nb) Polski (pl)
Português BR (pt-BR) Português PT (pt-PT) Svenska (sv) Turkish (tr)
Ukrainian (uk) Русский (ru) 日本語 (ja) 简体中文 (zh-CN)
繁体中文 (zh-TW) English (en, source)

Változatpolitika (a munkaterület területi szabálya szerint): a PT és a ZH külön csomagokra oszlik, mert a szókincs/írásmód valóban eltér (pt-BR/pt-PT, zh-CN/zh-TW). Az EN egyetlen csomag – a MusicBee „English(US)” (en-US) visszalép en-re a .NET kultúraláncán keresztül, így nem készül külön US csomag. Az ES és FR hasonlóképpen egyetlen területi beállítású.

Miért: egy UPnP beépülő modul beállításai („ne használjon nyers PCM-et”, „kényszerítse a little-endian PCM-et”, port-visszalépési figyelmeztetések) elég rejtélyesek anyanyelven is. A MusicBee saját felhasználói felületének nyelvének követése – ahelyett, hogy angolt kényszerítene – a különbség egy olyan eszköz között, amelyet egy nem angol anyanyelvű felhasználó konfigurálhat, és egy olyan között, amelyet nem. Egyik upstream sem próbálta meg ezt.


N31 - A súgó link a teljes felület nyelvével nyílik meg

Mi: a beépülő modulból megnyitott Súgó link tiszteletben tartja a felhasználó teljes felületnyelvét (pl. pt-BR, zh-CN) az alapnyelvre való összeomlás helyett, és egyértelműbb frissítésellenőrző azonosítót küld.

Miért: egy felhasználó, aki a MusicBee-t regionális változatban (brazil portugál, egyszerűsített kínai) futtatta, az alapnyelvű súgóoldalra került. A teljes kultúra átvitele a pontosan általuk használt nyelven lévő súgóoldalra juttatja őket.

Javítások és fejlesztések az eredeti beépülő modulban

Alapvető protokoll és lejátszás

F01 - Frissített alapértelmezett DLNA eszközprofilok

Mi: friss alapértelmezett profilokat szállít a PlayStation 4, Xbox 360/One és modern BubbleUPnP számára, olyan képességjelzőkkel (mintavételi frekvenciák, bitmélységek, kodekek), amelyek tükrözik, hogy ezek az eszközök valójában mit támogatnak ma.

Miért: az eredeti beépülő modul alapértelmezett beállításai 2014 körül befagytak. A PS4/Xbox/BubbleUPnP azóta hi-res audio támogatást kapott. A dobozból kivéve egy új telepítés a legjobb minőségben játszik ezeken az eszközökön anélkül, hogy a felhasználónak hozzá kellene nyúlnia az eszközprofil beállításaihoz.


F02 - MediaRenderer:3-at hirdető eszközök vezérlése

Mi: a beépülő modul lekérdezi egy renderelő UPnP szolgáltatásleírását, hogy eldöntse, a MusicBee képes-e vezérelni azt. Az eredeti csak az urn:schemas-upnp-org:device:MediaRenderer:1 értékre illeszkedett. A modern eszközök :2 vagy :3 értéket hirdetnek. Az F02 szélesíti az illeszkedést.

Miért: enélkül a legújabb Sonos / WiiM / Eversolo egységek egyszerűen nem jelennek meg célpontként a MusicBee „Lejátszás ide” eszközlistájában – annak ellenére, hogy ugyanazt a protokollt beszélik. Egyetlen karakterlánc-előtag illesztési javítás feloldja a teljes modern eszközgenerációt.


F03 - „Nyers adatfolyam kényszerítése” profil-specifikus opció (alapértelmezés szerint BE)

Mi: bejelölve a beépülő modul az eredeti fájlbájtokat küldi az eszközre átkódolás, DSP és ReplayGain feldolgozás nélkül. Csak a felhasználó által kiválasztott nyers fájl, bájt-bájtonként (HTTP keretezés kivételével).

Miért: fórumbejegyzések szerint ez a legnagyobb lejátszási minőségi nyereség. A drága renderelőket vásárló hi-fi felhasználók kifejezetten bit-perfect kimenetet akarnak; bármilyen DSP beavatkozás értelmetlenné teszi. Alapértelmezés szerint BE, mert a legtöbb modern eszköz kezeli a felhasználó által rájuk dobott kodeket, és a ReplayGain/EQ-nak opt-in-nek kell lennie. Profil-specifikus, így megtarthatja az átkódolást egy régi Xbox számára, miközben natív streamet küld egy hi-fi DAC-nak.


F04 - „Átkódolás kényszerítése” profil-specifikusan

Mi: profil-specifikus felülbírálás, amely minden adatfolyamot ezen az eszközön keresztül kényszerít az átkódolóra, függetlenül a natív kodek támogatásától. Az F03 (Nyers adatfolyam kényszerítése) inverze. Kölcsönösen kizárja egymást az F03-mal – a felhasználói felület automatikusan kikapcsolja a másikat, ha az egyiket bekapcsolják.

Miért: egyetlen globális kapcsoló ellentmondásos lenne a profil-specifikus Nyers adatfolyam kényszerítése (F03) opcióval. Valós eset: az A eszköz egy hi-fi DAC, amely bit-perfect natív adatfolyamokat szeretne; a B eszköz egy régi AV vevő, amely FLAC-on fullad. Globális kapcsolóval a felhasználónak választania kell – a másik eszköz rovására. Profil-specifikusan minden eszköz a helyes választ kapja.

Megvalósítás:

  • StreamingProfile.ForceTranscoding As Boolean = False.
  • A perzisztencia séma v9-re emelve. A v9 előtti fájlok egyszer betöltik a régi globális értéket, és átmásolják az összes profilba, megőrizve a régi viselkedést a frissítés során.
  • UI: eltávolítva a Diagnosztika panelről, hozzáadva az Eszközprofilok szakaszhoz a Nyers adatfolyam kényszerítése mellé. Kétirányú kölcsönös kizárási kezelők (CheckedChanged mindegyiken leiratkoztatja a másikat a váltás előtt, hogy elkerülje a végtelen ciklust).
  • Döntési hely: Settings.ForceTranscodingstreamingProfile.ForceTranscoding a WriteAudioFileDIDL függvényben.

F05 - „Little-endian PCM kényszerítése” profil-specifikusan

Mi: a PCM adatfolyamok (L16/L24 mime típusok) specifikáció szerint big-endianek. Egyes eszközök tévesen little-endiant várnak, és fehér zajt játszanak le, ha megfelelő big-endian adatokat kapnak. Az F05 profil-specifikusan váltja a bájt sorrendet.

Miért: enélkül bizonyos eszközök statikus zajt adnak ki. A tünet drámai, és az ok láthatatlan a PCM kódolás ismerete nélkül – a kapcsoló találgatós javítást biztosít a felhasználóknak.


F06 - „Ne használjon nyers PCM-et” profil-specifikusan

Mi: ha az eszköz azt állítja, hogy támogatja a nyers PCM-et, a beépülő modul azt használja. Egyes eszközök hazudnak – elfogadják a SOAP kézfogást, de eltorzítják a tényleges nyers PCM adatokat, miközben megfelelően kezelik a WAVE konténerbe csomagolt PCM-et. Az F06 kényszeríti a PCM-over-Wave-et, függetlenül attól, hogy az eszköz mit hirdet.

Miért: kifejezetten bizonyos Marantz modellek – nyers PCM-et hirdetnek, de csak a WAVE működik. Enélkül a nyers PCM adatfolyamok torzítva jönnek ki, hibaüzenet nélkül.


F07 - „Tartalom hossza” profil-specifikusan

Mi: milyen értéket küldjön a HTTP Content-Length fejlécben. Négy opció:

  • Alapértelmezett - tényleges bájtmennyiség, ha ismert, kihagyja, ha ismeretlen.
  • Nincs - soha ne küldje el a fejlécet (csak darabolt kódolás).
  • Csak PCM - csak nyers PCM esetén küldje el; minden másnál kihagyja.
  • Rögzített - küldje el a UInt32.MaxValue - 8192 értéket (egy jelző a „hatalmas ismeretlen hosszúságra”).

Miért: az UPnP/DLNA eszközök vadul eltérően reagálnak a Content-Length-re. Egyeseknek pontos számra van szükségük, mások utálják az adatfolyamokon, másoknak egy „nagyon nagy” jelzőértékre van szükségük a pufferelés fenntartásához. Ezt később kiterjesztették csak PCM-ről minden kimeneti formátumra, mert ugyanazok a problémák jelentkeztek az átkódolt MP3/AAC adatfolyamokban.


F08 - „Ne törölje a NextURI-t” profil-specifikusan

Mi: normális esetben a beépülő modul törli az eszköz sorba állított NextURI-jét, amikor a sor kiürül (üres URL-lel küldve a SetNextAVTransportURI-t). Egyes eszközök (különösen a Denon) az üres NextURI-t „mindent leállít” értelmezik, és azonnal leállítják a lejátszást. Az F08 megakadályozza, hogy a beépülő modul valaha is törölje azt.

Miért: enélkül a Denon tulajdonosok azt tapasztalják, hogy az eszköz megszakítja a számot a közepén, amikor a sor kiürül. Az F08 bejelölésével az eszköz a régi NextURI-t a memóriában tartja (ártalmatlan – egyszerűen felülíródik, amikor legközelebb valami sorba kerül).


F09 - FLAC mint átkódolási kimeneti formátum

Mi: az Eszközprofilok átkódolási formátum legördülő menüje mostantól FLAC-ot is kínál a PCM 16/24, MP3, AAC, Ogg mellett. Ennek kiválasztása a BASS kódolót a MusicBee szabványos FLAC konvertáló parancssorán keresztül irányítja (ugyanaz a mechanizmus, amelyet az MP3/AAC/Ogg már használ).

Miért: azoknál az eszközöknél, amelyek jól kezelik a FLAC-ot, de nem tudják dekódolni a forráskodeket (pl. egy Eversolo, amely a MusicBee WMA könyvtárát FLAC-ra konvertálva kapja), ez megőrzi a veszteségmentes minőséget, ahol az MP3/AAC eldobná az audio adatokat. Feloldja az N02-t (5.1 sztereóvá keverés vezérlése), amelyet veszteségmentes átkódolási opció nélkül nem lehetett kezelni.

Megvalósítás: egy soros kiegészítés az Encoder.StartEncode Select Case Codec blokkjához – a FLAC csatlakozik az MP3/AAC/Ogg-hoz a parancssorból vezérelt ágban. Az UI legördülő menüje „FLAC”-ot kap 6. opcióként. A SettingsDialog betöltési/mentési leképezése kiterjed a FileCodec.FlacSelectedIndex = 5 felismerésére. A Mime, DLNA típus és kódolási funkció már be volt kötve az ItemManager.GetMimes / GetDlnaType / GetEncodeFeature függvényekben korábbi munkákból (F21, F26).


Réstelen lejátszás (SetNextAVTransportURI)

F10 - SetNextAVTransportURI / NextURI mag

Mi: valódi réstelen lejátszás. Amikor az eszköz hirdeti a SetNextAVTransportURI támogatását az UPnP szolgáltatásleírásában, a beépülő modul előre sorba állítja a következő számot az eszközön, mielőtt az aktuális véget ér. Az eszköz belsőleg átvált a számok között hallható rés nélkül – amit egy CD-lejátszón hall. Ez nem a „folyamatos adatfolyam” hack (amely mindent egy hosszú adatfolyammá fűz össze, és elveszíti a számonkénti metaadatokat).

Miért: a zászlóshajó Tier-2 funkció. A folyamatos élő előadásként rögzített albumok (élő felvételek, klasszikus tételek, DJ szettek) rosszul szólnak, ha fél másodperces csend van a számok között. Ennek megfelelő megoldása egy zászlóshajó funkció, amely most ebben az elágazásban található.

Megjegyzések: a sorba állított hangot a beépülő modul HTTP szervere szolgálja ki streamHandle=0 (könyvtár-lekérési mód) használatával, ami azt jelenti, hogy a MusicBee audio motorja nem vesz részt a sorba állított szám lejátszásában. Kompromisszum: a ReplayGain/DSP/EQ effektek nem alkalmazhatók a következő számra. Elfogadható, ha a „nyers adatfolyam kényszerítése” be van kapcsolva (az alapértelmezett).


F11 - „NextURI támogatás letiltása” profil-specifikusan

Mi: még ha egy eszköz hirdeti is a SetNextAVTransportURI-t, ez a jelölőnégyzet arra kényszeríti a beépülő modult, hogy figyelmen kívül hagyja ezt a hirdetést, és visszatérjen az egyszerre egy szám lejátszásához.

Miért: egyes eszközök hirdetik a NextURI-t, de hibás implementációval rendelkeznek (összeomlások, félátmenetek, lefagyások). Ahelyett, hogy minden egyes hibás eszközt visszafejtenénk, a felhasználó kap egy „csak kapcsolja ki itt” kapcsolót.


F12 - NextURI életciklus a most játszott listán

Mi: amikor a MusicBee NowPlayingListChanged eseményt vált ki, a beépülő modul újraértékeli, hogy mit kellene sorba állítani a réstelen átmenethez. Lekérdezi a MusicBee-től az új „következő” számot a NowPlayingList_GetNextIndex(1) + NowPlayingList_GetListFileUrl segítségével, összehasonlítja azzal, ami jelenleg sorba van állítva az eszközön (az új nextPlaySourceUrl mezőn keresztül követve), és újra sorba állítja, ha megváltozott (vagy törli a sort, ha a MusicBee azt mondja, hogy nincs következő szám).

Miért: az F12 nélkül az eszköz továbbra is egy elavult NextURI-t játszott le, amikor a felhasználó eltávolította/átrendezte a sorba állított számot. Ez történelmileg több iterációt igényelt, mert minden lista-mutáció más kezelést igényel – mi egyszerűsítettük azáltal, hogy megbíztunk a NowPlayingList_GetNextIndex függvényben (amely már figyelembe veszi a keverést és az összes ismétlés körbefordulását), így minden változat ugyanazon az összehasonlításon keresztül fut.

Megvalósítás:

  • Új nextPlaySourceUrl mező tárolja a sorba állított elem MusicBee könyvtár URL-jét (a stream URL a handle utótaggal nem hasonlítható össze egy könyvtárútvonallal).
  • Új Public Sub RefreshQueuedNextUri() a MediaRendererDevice-en. Három kimenet: nincs sorba állított NextURI → no-op; a sorba állított egyezik az új „következővel” → no-op; a sorba állított eltér → hívja a QueueNext-et az új URL-lel (vagy QueueNext("")-et a törléshez – ami tiszteletben tartja az F08 DoNotClearNextUri-t).
  • Bekötve a Plugin.ReceiveNotification-be a NotificationType.NowPlayingListChanged alatt.

F13 - NextURI hiba visszalépés

Mi: 4 egymást követő SetNextAVTransportURI hiba után ugyanazon az eszközön a beépülő modul letiltja a réstelen lejátszást az adott eszközön a MusicBee újraindításáig.

Miért: ha egy eszköz valóban hibás a NextURI szempontjából (időszakos SOAP hibák, hálózati problémák), a beépülő modul egyébként minden számnál újrapróbálkozna. Az F13 leállítja a zajt, és csendesen visszatér az egyszerre egy szám lejátszásához.


F14 - Ismétlési mód + NextURI integráció

Mi: az F14 két esetre oszlik, amelyeket az F15 átmenetérzékelő kezel az OnAvTransportStatusCheck függvényben:

  • Összes ismétlése: a MusicBee a helyes „körbeforduló” URL-t (1. szám a lista végén) adja át a Plugin.QueueNext függvénynek. Nincs szükség speciális beépülő modul logikára – az eszköz átvált rá, és az F15 érzékelő a szokásos módon meghívja a Player_PlayNextTrack függvényt, amely a MusicBee NPL indexét visszaállítja 0-ra.
  • Egy ismétlése: a MusicBee UGYANAZT a szám URL-t adja át a Plugin.QueueNext függvénynek. Az eszköz átvált rá (új adatfolyam-kezelő, ugyanaz a forrás). Az F15 érzékelő most lekérdezi a Player_GetRepeat() függvényt – ha az RepeatMode.One, akkor kihagyja a Player_PlayNextTrack hívást, így a MusicBee nem lépteti előre az NPL indexet a hurkolt számtól.

Miért: az Egy ismétlése kihagyása nélkül a Player_PlayNextTrack hívása réstelen átmenetkor előre léptetné a MusicBee-t a következő számra a listában (az Egy ismétlése csak a szám végén történő automatikus előrelépési viselkedést érinti a lejátszó felhasználói felületén – a Következő szám mindig előre lép), ami ellentmondana annak, amit az Egy ismétlése jelent.

Lejátszásszám figyelmeztetés: az Egy ismétlése módban a lejátszásszám növekedése attól függ, hogy a MusicBee 3.7.9563+ észreveszi-e a hurkolt lejátszást. Régebbi MusicBee verziók helyesen játsszák le a réstelen ismétlést, de kihagyják a lejátszásszám növelését. Dokumentált; nem blokkoló.


F15 - Számátmenet érzékelő állapotgép

Mi: amikor az eszköz belsőleg átvált az aktuális számról a NextURI-re, a beépülő modulnak észre kell vennie, és szólnia kell a MusicBee-nek, hogy léptesse előre a most játszott indexét. Ellenkező esetben a MusicBee azt hiszi, hogy még mindig az előző számon van, és a lejátszásszámok / felhasználói felület / scrobbling szinkronból kerül.

Megvalósítás: minden állapot-időzítő üteménél lekérdezi a GetPositionInfo.TrackURI-t. Amikor a jelentett URI megegyezik azzal, amit a NextURI-n keresztül sorba állítottunk, meghívjuk a Player_PlayNextTrack-et a MusicBee-n, és beállítjuk a suppressNextSoapCall-t, így az ebből eredő PlayToDevice nem küldi újra a SetAVTransportURI-t (ami megszakítaná a réstelen lejátszást).

Miért: az F15 nélkül az eszköz lejátssza a következő számot, de a MusicBee felhasználói felülete azt mondja, hogy még mindig az előzőn van. Zavaró, megszakítja a scrobblinget, megszakítja a lejátszásszám követést. A számátmenet érzékelése hosszú, renderelőnkénti iterációt igényel, mert minden renderelő márkának megvannak a saját furcsaságai abban, hogy mikor jelenti a URI változást (egyesek először TRANSITIONING-et jelentenek, mások egyenesen PLAYING-re ugranak új URI-val, másoknak van egy rövid STOPPED állapotuk a kettő között).

Megjegyzések: első vázlatunk a BubbleUPnP renderelőn működik. Az eszközönkénti szélső esetek a B6-ban maradnak.


F16 - Pattogás a réstelen átmenetnél javítás

Mi: a pattogás akkor következik be, amikor a sorba állított szám forrásformátuma (mintavételi frekvencia / csatornák / kodek) eltér az éppen lejátszott számtól, ami arra kényszeríti az eszköz DAC-ját, hogy újra rögzítse magát az átmenetnél. Az F16 hozzáad egy NextUri:FormatChange diagnosztikát, amely sorba állításkor aktiválódik, amikor a formátumok eltérnek, megnevezve mindkét oldalt – így a pattogást halló felhasználók korrelálhatnak.

A diagnosztika a megoldásra is rámutat: jelölje be a ForceTranscoding opciót az eszközprofilon. Ez homogenizálja az összes számot egyetlen átkódolási kodek/mintavételi frekvencia/bitmélységre, teljesen kiküszöbölve a forrásformátum különbségét.

Miért halasztották el a tényleges átkódolás-illesztés javítását: a strukturális javítás (a sorba állított szám átkódolása, hogy illeszkedjen a lejátszott szám formátumához) változtatásokat igényel a beépülő modul HTTP szerverének URL-sémájában – jelenleg az /encode/{id}0.{ext} natívan szolgálja ki a sorba állított fájlt. Az F16 jövőbeli v2-je formátumonkénti /encode/{id}0_{rate}_{depth}.{ext} útvonalakat adna hozzá, és bekötné őket a kódolón keresztül. Ez egy nagyobb architekturális változás, amelyet érdemes megtenni, ha egy valós eszköz pattogást mutat, miután a ForceTranscoding nem elegendő.

Jelenlegi megvalósítás:

  • A lastSourceUrl mező követi az éppen lejátszott forrás URL-jét.
  • A QueueNext beolvassa a FilePropertyType.SampleRate/Channels/Kind értékeket mind az aktuális, mind a sorba állított számokhoz, és NextUri:FormatChange üzenetet naplóz eltérés esetén.

F17 - Folyamatjelző sáv újraszinkronizálása keresés után

Mi: a Seek() függvény már meghívta a GetPlayPositionInformation() függvényt egy sikeres Seek SOAP után, ami javítja a „egyáltalán nincs újraszinkronizálás” esetet. Az F17 megszünteti a fennmaradó, akár 1 másodperces eltolódást, amelyet az UPnP 1 másodperces RelTime kvantálása okoz: amikor az eszköz által jelentett pozíció 1 másodpercen belülre kerekedik a felhasználó által kért célhoz képest, a beépülő modul mostantól a felhasználó másodperc alatti pontosságú értékét veszi figyelembe az eszköz csonkítása helyett. Csak akkor használjuk az eszköz értékét, ha az drámaian eltér (>1 másodperc eltérés) (a keresés máshová esett, mint kérték, pl. kulcsképhez igazítás egyes kodekeknél).

Miért: enélkül a 2:30.500-ra történő keresés, az eszköz „2:30” jelentéséhez rögzítve, a folyamatjelző sávot ~500 ms-mal a valóság mögött mutatná. Az F17 után a sáv megfelel a felhasználó szándékának a gyakori számon belüli görgetés esetén, és továbbra is tiszteletben tartja az eszköz jelentését a kulcsképhez igazítás kivételes esetében.


F18 - Folyamatos adatfolyam / NextURI reteszelés

Mi: két reteszelés van érvényben:

  1. Futásidő: A QueueNext korán False értéket ad vissza, ha a Settings.ContinuousOutput be van kapcsolva. A folyamatos adatfolyam saját réstelen mechanizmusa (egy hosszú, összefűzött adatfolyam); a SetNextAVTransportURI küldése ezen felül összezavarja az eszközt abban, hogy az egyes számok különálló URI-k-e, vagy a folyamatos adatfolyam részét képezik.
  2. Felhasználói felület: Amikor a felhasználó bejelöli a globális folyamatos adatfolyam jelölőnégyzetet, az aktuálisan megjelenített profil forceNativeStream automatikusan kikapcsol. A folyamatos adatfolyam mindig átkódol, így a natív kényszerítése értelmetlen kombinációban.

Miért: megakadályozza, hogy a felhasználó két egymásnak ellentmondó réstelen mechanizmust engedélyezzen egyszerre. Az F18 nélkül az eszköz mind folyamatos adatfolyam URI-t, mind NextURI-t kapna minden következő számhoz, meghatározatlan viselkedéssel a renderelőtől függően.


F19 - Üres NextURI hibák figyelmen kívül hagyása

Mi: amikor a SetNextAVTransportURI üres URL-lel kerül meghívásra (pl. a lista utolsó száma), egyes eszközök SOAP hibát adnak vissza. Az F19 csendesen elnyeli ezeket – naplózva, de nem hibaként továbbítva.

Miért: a „nincs következő szám” állapot normális, nem hiba. Halálos hibaként kezelése szennyezi a naplót, és (egyes folyamatokban) újrapróbálkozási viharokat vált ki.


Mime típusok és DLNA metaadatok

F20 - MP3 mime → audio/mpeg

Mi: a szabványoknak megfelelő MP3 mime típus audio/mpeg, nem audio/mp3. Utóbbi gyakori téves elnevezés, amelyet a legtöbb eszköz tolerál, de a szigorúbb renderelők elutasítják.

Miért: csendesen javítja a lejátszást a szigorúbb, szabványt követő eszközökön. A yaiol kódbázisban ez már helyesen szerepelt; nincs szükség változtatásra.


F21 - Mime típus sorrend: nem x- változat először

Mi: amikor egy eszköz audio/flac és audio/x-flac mime típust is hirdet, a beépülő modul először a nem x- változatot adja vissza. Ugyanez vonatkozik minden kodekre, amely szabványos és kísérleti mime típusokkal is rendelkezik.

Miért: az x- előtag kísérleti/nem hivatalos mime típusokat jelöl. Egyes renderelők jobban viselkednek a szabványos formával. Apró átrendezés, valós hatás.


F22 - Opus mime típus támogatás

Mi: felismeri az Opust mint streamelhető audio kodeket; audio/opus mime típust küld Opus számok kiszolgálásakor.

Miért: az Opus ma már elterjedt (modern beszéd/zene kompromisszumos kodek). Az F22 nélkül a beépülő modul megtagadná az Opus fájlok streamelését még azoknak az eszközöknek is, amelyek kezelik őket.


F23 - Monkey Audio (APE) forrásfájl támogatás

Mi: felismeri az .ape fájlokat érvényes forráskodekként streameléshez/átkódoláshoz.

Miért: az APE egy veszteségmentes formátum, amelynek van egy réteg-, de hűséges felhasználói bázisa. Hozzáadása kevés költséggel jár, és feloldja a könyvtárat ezeknek a felhasználóknak.


F24 - AAC / ALAC mime visszalépés

Mi: ha egy eszköz támogatja az AAC-t vagy az ALAC-ot, de nem hirdeti explicit módon az UPnP szolgáltatásleírásában, a beépülő modul akkor is felajánlja őket visszalépésként.

Miért: számos eszköz, amely jól kezeli az AAC-t, elfelejtette felsorolni a képességei XML-jében. Az F24 nélkül a beépülő modul meg sem próbálná, kényszerítve az átkódolást. Az F24-gyel a beépülő modul megpróbálja, és hagyja, hogy az eszköz natívan kezelje, ha tudja.


F25 - DLNA típusjelző natív + kódolt WAV adatfolyamokhoz

Mi: a DLNA típusjelzőnek (egy profilazonosító, mint LPCM, WAVE, MP3) meg kell egyeznie azzal, amit az eszköz kap. Az F25 biztosítja, hogy a natív adatfolyamok és a kódolt WAV adatfolyamok helyesen legyenek jelölve.

Miért: a nem megfelelő DLNA típus miatt egyes eszközök teljesen megtagadják a lejátszást, vagy rossz dekódert alkalmaznak.


F26 - DLNA fejléc FLAC fájlokhoz

Mi: a FLAC adatfolyamok megkapják a megfelelő DLNA profilazonosítót a fejléceikben.

Miért: enélkül egyes FLAC-ot támogató eszközök nem ismerik fel az adatfolyamot FLAC-ként.


F27 - Bitráta számítás javítása a metaadatokban

Mi: a folyamatos adatfolyam res@bitrate értéke (sampleRate * channels * bitsPerSample) / 1000 - kbps - értékkel került kiszámításra, ami körülbelül 125-szörös eltérést mutatott az UPnP DIDL specifikációtól, amely az attribútumot bájtok másodpercenként definiálja. Most 8-cal oszt 1000 helyett.

Miért: hibás bitráta megjelenítés az eszközön – a legtöbb renderelőn kozmetikai, de egyesek az értékből allokálnak adatfolyam puffereket, és akadoznak azokon az adatfolyamokon, amelyek ~125-ször kisebbnek tűnnek, mint amilyenek. A nem folyamatos forrásfájl útvonalon ez már helyesen szerepelt ((bitrate_kbps * 1000) \ 8 = bájt/másodperc); csak a folyamatos adatfolyam útvonal volt hibás.


F28 - Metaadat időformátum javítása (Marantz)

Mi: a DIDL-ben a res@duration H:MM:SS formátumban volt (pl. 0:03:42). Az UPnP DIDL specifikáció a formátumot H+:MM:SS[.F+]-ként definiálja – szigorúan a törtrészes másodpercek opcionálisak, de ajánlottak; egyes Marantz eszközök érvénytelennek tekintik a csupasz formátumot, és üresen hagyják a lejátszási idő kijelzőjét. Mostantól H:MM:SS.fff formátumban (pl. 0:03:42.000).

Miért: egy márkára jellemző megjelenítési probléma; a törtrészes másodperceket tartalmazó, ISO-stílusú formátum javítja anélkül, hogy bármely más eszközt érintene. Mindkét DIDL kibocsátási helyen alkalmazva (forrásfájl útvonal + kódolt adatfolyam útvonal a WriteAudioFileDIDL függvényben).

Bónusz javítás ugyanabban a lépésben: a pv:addedTime és pv:lastPlayedTime hh (12 órás óra) formátumot használt a DateTime formátumkarakterláncaiban HH (24 órás) helyett. Bármely 13:00 és 23:59 között hozzáadott vagy lejátszott szám hibás órával jelenne meg (pl. 17:42 → „05:42”) azokon az eszközökön, amelyek megjelenítik a mezőt. Mostantól HH-t használ.


F29 - Kódolt MP3 keresési támogatás (CBR)

Mi: az átkódolt MP3 adatfolyamok mostantól DLNA.ORG_OP=11 (bájt és idő szerinti keresés is) értéket hirdetnek DLNA.ORG_OP=10 (csak bájt) helyett. Azok az eszközök, amelyek korábban megtagadták az idő szerinti keresést átkódolt MP3-on, mostantól normálisan vezérelhetik a folyamatjelző sávjukat/keresési felhasználói felületüket.

Miért: a MusicBee átkódolója állandó bitrátájú MP3-at állít elő a HighQuality előbeállítással, így a bájt ↔ idő leképezés lineáris – az eszköz maga is átalakíthatja az idő szerinti keresési kérést HTTP Range bájt szerinti kereséssé, bármilyen kódoló oldali támogatás nélkül. Az OP=11 hirdetése feloldja ezt a felhasználói felületet az eszközön. Az F29 nélkül az átkódolt MP3-ban kereső felhasználók vagy csendesen figyelmen kívül hagyták a keresést, vagy a szám elejére kerültek.

Megvalósítás: a GetEncodeFeature függvényt az ItemManager.vb fájlban átstrukturálták, hogy az inline If egy olvasható If/ElseIf/Else láncra bomoljon. Az MP3 explicit módon OP=11 értéket kap; más nem-PCM kodekek megtartják az OP=10 értéket. Nincs változás az AAC/FLAC/stb. esetében – ezekhez kodek-specifikus CBR-ellenőrzésre lenne szükség, amit a MusicBee nem garantál.


F30 - .mpeg fájlkiterjesztés kezelése

Mi: az .mpeg (és a még ritkább .mpe) kiterjesztésű fájlokat mostantól FileCodec.Mp3-ként ismeri fel a GetCodec. Az F30 előtt FileCodec.Unknown értéket adtak vissza, és csendesen elutasították őket a könyvtárból / nem voltak átkódolási források.

Miért: a régi MPEG-1 Layer 3 archívumok néha .mpeg kiterjesztést használtak .mp3 helyett (a specifikáció mindkettőt megengedi). Néhány fájl egy 300 ezres könyvtárban elegendő ahhoz, hogy a felhasználó azt érezze, „a MusicBee mutatja őket, de a beépülő modul nem” – ami zavaró a felhasználó számára.


Lejátszási viselkedés

F31 - Rádió adatfolyamok automatikusan folyamatos módot használnak

Mi: a WriteAudioFileDIDL mostantól lekérdezi a forrás URL Kind tulajdonságát a Library_GetFileProperty segítségével, és minden olyan fájlt, amelynek Kind-je „Stream”-re végződik (a MusicBee „MP3 Stream”, „Internet Stream” stb. jelent a rádióhoz), folyamatosként kezel, függetlenül a globális Settings.ContinuousOutput kapcsolótól. A folyamatos adatfolyam DIDL ág (Cím: „Continuous Stream”, id="continuousstream", rögzített PCM/Wave kimenet) kerül felhasználásra; az eszköz egyetlen, végtelen stílusú adatfolyamot lát.

Miért: a rádió adatfolyamoknak nincsenek számlimitjei, nincs rögzített hossza, nincs keresési lehetősége. A DIDL-ben diszkrét fájlokként való kezelés miatt a beépülő modul olyan bájt tartományokat és időtartamokat hirdetett, amelyek nem léteznek. Az automatikus váltás, amikor a MusicBee már elmondta nekünk, hogy „ez egy adatfolyam”, eltávolít egy olyan hibalehetőséget, amire a felhasználónak nem kellene gondolnia.

Hatókör: csak akkor alkalmazható, ha a MusicBee vezérli a lejátszást (musicBeePlayToMode). A könyvtár-lekérési útvonal (UPnP kliens böngészés) változatlan – a rádió URL-ek ott ritkák, és a felhasználói felület viselkedése nem változhat explicit tesztelés nélkül.


F32 - Kodek-hirdetési visszalépés

Mi: ha egy eszköz nem hirdet bizonyos kodekeket (vagy a beépülő modul nem tudja értelmezni az eszköz képesség XML-jét), a beépülő modul nem utasítja el azonnal az adatfolyamot. Ehelyett megpróbálja kiszolgálni, és hagyja, hogy az eszköz döntsön.

Miért: sok eszköznek hiányos vagy olvashatatlan képesség XML-je van, de valójában jól kezelik a kodeket. Az F32 egy kis „találgatás és próbálkozás” lehetőséget cserél egy egyenes elutasításra.


F33 - Folyamatjelző sáv szinkronizálásának javítása

Mi: a lekérdezések közötti pozíció már falióra-extrapolált egyetlen horgonyból (currentPlayStartTicks), így a folyamatjelző sáv simán frissül másodperc alatti sebességgel. A fennmaradó jitter forrása egy frissen indított szám kezdeti horgonya volt: az előző kód feltételezte, hogy position=0 abban a pillanatban, amikor az állapot-időzítő először észlelte, hogy az állapot Lejátszásra váltott, de addigra az eszköz már 100-500 ms-ig (egy lekérdezési intervallum) játszhatott. A MusicBee folyamatjelző sávja 0-ról indulna, majd előre ugrana, amikor a valóság utolérte.

F33 javítás: amikor egy új számon először vált át Lejátszásra (currentPlayStartTimeEstimated=True), hívja meg a GetPlayPositionInformation() függvényt az eszköz aktuális aktuális pozíciójának lekéréséhez, majd rögzítse azt. Az UPnP csak 1 másodperces felbontást jelent, így a horgony továbbra is kvantált, de sokkal közelebb áll az igazsághoz, mint a 0 feltételezése.

Miért: simább + pontosabb folyamatkijelzés, különösen számváltás után. Az 1 másodperces UPnP jelentési felbontást magát nem lehet megkerülni – ez a specifikáció.


F34 - Folyamatjelző sáv remegése számváltás után

Mi: amikor a PlayToDevice függvényt egy új számra hívták meg, a beépülő modul korábban a currentPlayPositionMs és currentPlayStartTicks értékeket az előző szám értékein hagyta a SOAP-Play és az új Lejátszás állapotot észlelő első állapot-időzítő lekérdezés közötti ~100 ms-os ablakban. A MusicBee folyamatjelző sávja röviden az előző szám végét mutatta, majd visszaállt 0-ra, majd emelkedett. Az F34 mindkettőt nullázza a PlayToDevice belépéskor – abban a pillanatban, amikor tudjuk, hogy számváltás történik, még a SOAP munka előtt.

Miért: vizuális hiba gyors átugrási esetekben (kézi következő vagy réstelen átmenet). Most a MusicBee első PlayPositionMs lekérdezése a Play után tisztán 0-t ad vissza, majd az F33 GetPlayPositionInformation függvénye finomítja azt az eszköz tényleges pozíciójára az első állapotváltozási ütemnél.

Megvalósítás: négy sor a PlayToDevice tetején, párosítva az F33 átmeneti idejű pontos rögzítésével.


F35 - „Átkódolás kényszerítése” hiba

Mi: az átkódolás kényszerítése bizonyos kombinációkban továbbra is kihagyhatta az átkódolást. Az F04 profil-specifikus átdolgozása után két specifikus hiányosságot zártak le:

  1. Prioritás a Nyers adatfolyam kényszerítésével. Amikor mindkettő Igaz volt (ami előfordulhat séma migráció vagy részleges beállításfájl esetén), az Átkódolás kényszerítése mostantól egyértelműen nyer (If streamingProfile.ForceTranscoding Then forceEncode = True ElseIf streamingProfile.ForceNativeStream Then forceEncode = False). A felhasználói felület kölcsönös kizárása megakadályozza, hogy a felhasználó mindkettőt bejelölje, de a futásidejű őr kezeli azokat az állapotokat, amelyek inkonzisztensen töltődtek be a lemezről.
  2. bypassTranscodeDecision logika. Korábban: streamingProfile.ForceNativeStream AndAlso Not Settings.ForceTranscoding. Most: streamingProfile.ForceNativeStream AndAlso Not streamingProfile.ForceTranscoding – ugyanaz a prioritási szabály, de ugyanazon profil-specifikus hatókörben.

Miért: a „kényszerítésnek” kényszerítést kell jelentenie. Ha a felhasználó explicit módon engedélyezte az Átkódolás kényszerítését egy eszközhöz, a beépülő modul soha nem térhet vissza csendesen a natív streameléshez, függetlenül attól, hogy más jelzők hogyan kombinálódnak.


F36 - Renderelő bezárva kivétel

Mi: a Plugin.ReceiveNotification egy felső szintű Try/Catch blokkba került, amely naplózza az összes el nem kapott kivételt, ahelyett, hogy hagyná azt visszaterjedni a MusicBee értesítési pumpájába.

Miért: a MusicBee értesítései (PlayStateChanged, VolumeMuteChanged stb.) a ControlPointManager-be kerülnek, amely SOAP-on keresztül kommunikál a renderelővel. Az egyes hívási helyek már rendelkeztek Try/Catch blokkal a SOAP hívásaik körül, de egy kellően furcsa időzítési eset (pl. a renderelő meghal két SOAP hívás között ugyanabban az értesítési kezelőben) továbbra is elszökhetett. A felső szintű burkoló a végső biztonsági háló, így a felhasználó soha nem lát egy általános „TargetInvocationException” felugró ablakot a MusicBee-től.

Megvalósítás: az existing body átnevezve ReceiveNotificationInternal-re, és hozzáadva egy vékony burkoló ReceiveNotification, amely Try { ReceiveNotificationInternal(...) } Catch { LogError(...) } műveletet végez. A ControlPointManageren belüli már meglévő metódusonkénti Try/Catch infrastruktúra (minden PostSoapRequest hívás körül) megmarad – az F36 egy „öv és nadrágtartó” megoldás.


F37 - Hosszú számban történő keresés hamis átmenetet vált ki

Mi: egy hosszú számban történő keresés rövid Stopped→Playing ciklust eredményezhet egyes renderelőkön. Megkülönböztetés nélkül a ProcessNewPlayState.Stopped ezt a szám természetes végének tekinti, és meghívja a Player_PlayNextTrack-et, előre léptetve a MusicBee-t, amikor a felhasználó csak görgetni akart. Az F37 a lastUserInitiatedSeek időbélyeget helyezi el a Seek() függvényben, és egy 5 másodperces védelmet ad a Stopped kezelőhöz (tükrözve a meglévő lastUserInitiatedStop ablakot).

Miért: a csendes ugrás a következő számra keresés közben egyike azoknak a hibáknak, amelyek okát senki sem tudja kitalálni – a felhasználó azt gondolja, „furcsa, megpróbáltam előre görgetni, és most a következő dalt játssza”. A javítás mechanikus: ugyanaz a minta, mint a már meglévő felhasználói leállítás megkülönböztetés.


F38 - Javított kereséskezelés összeomlásra hajlamos kodekeknél

Mi: a BubbleUPnP összeomlása MP3 kereséskor volt a tipikus tünet. Auditálás után a jelenlegi yaiol keresési kód már a helyes dolgokat teszi – a natív útvonal helyesen kezeli a HTTP Range-et (206, Content-Range, AcceptRanges), a kódolt útvonal hirdeti az X-AvailableSeekRange-et, és elemzi a bejövő timeSeekRange.dlna.org / npt fejléceket, a DLNA.ORG_OP jelzők tükrözik a tényleges adatfolyam képességeit (a DisablePcmTimeSeek opt-out opcióval a problémás Platinum eszközökhöz). Felhasználó által tesztelve a jelenlegi BubbleUPnP 4.6.4-en: nem észleltek összeomlásokat.

Miért: a BubbleUPnP MP3-keresési összeomlását 2024 körül jelentették, és az alkalmazás azóta ~16 hónapnyi javítást kapott. Az F29 (kódolt MP3 OP=11) volt az új változó, amely újra előhozhatta volna; a tesztelt verziókon nem teszi.

Ha egy összeomlás visszatér: a javítás formája egy profil-specifikus „korlátozott keresés” kapcsoló lenne, amely DLNA.ORG_OP=10 (csak bájt) értéket kényszerít a jelölt kodekekre – tükrözve, ahogyan a DisablePcmTimeSeek már működik a PCM esetében. Akkor hozzáadni, nem előre.


Felhasználói felület és naplózás

F39 - „Hozzáadás” gomb kiválasztja az új profilt

Mi: az „Hozzáadás” gombra kattintva az eszközprofilok listájában új profilt hoz létre ÉS automatikusan kiválasztja azt, így a felhasználó azonnal szerkesztheti a mezőket. A szakaszolt párbeszédpanel refaktorálásunk már megteszi ezt – mind a közvetlen Hozzáadás útvonal, mind a sablonból történő útvonal a Me.activeStreamingProfiles.SelectedIndex = Me.activeStreamingProfiles.Items.Count - 1 értékkel végződik. Egy ellenőrzés megerősítette, hogy az elágazásunk már kezeli ezt – nincs mit változtatni.

Miért: apró UX „papírvágás”, amelyről kiderült, hogy itt már nem is az.


F40 - Nagyobb maximális kapcsolatok + figyelmeztető napló

Mi: a beépülő modul egyidejű adatfolyam korlátja (SemaphoreSlim a Sockets_Stream_File / Sockets_Encoder_Start körül) hardkódolt 4 volt. Az F40 felhasználó által konfigurálhatóvá teszi az Általános beállítások oldalon (alapértelmezett 16, tartomány 1-256), hozzáad egy MaxConnections naplóbejegyzést, ha egy kérésnek várnia kell egy helyre, ÉS megjelenít egy piros ⚠ Max Conn jelvényt a beállítások párbeszédpanel bal alsó sarkában, ha a korlátot legalább egyszer elérték a MusicBee indítása óta.

Miért: amikor egy eszköz párhuzamos kéréseket indít (egyes Marantz/Linn eszközök a borítóképek szkennelése során, a BubbleUPnP metaadat lekérdezései az aktív lejátszás mellett), további kérések csendesen blokkolódtak a szemafor mögött – a felhasználó „lassú eszközt” látott látható ok nélkül. A naplóbejegyzés jó a technikai hibakereséshez, de a nem technikai felhasználók soha nem olvassák a naplókat. A beállítások párbeszédpanelen látható jelvény felfedezhetővé teszi a korlát elérésének állapotát bárki számára, aki megnyitja a beépülő modul beállításait.

Megvalósítás:

  • A várakozás központosítva a WaitOnSendBarrier(logTag) függvényben a MusicBeeUpnp.vb fájlban; mindkét hívási hely (MediaServerDevice.GetFile, Encoder.StartEncode) használja.
  • A Settings.MaxConnections a beállítási séma v8-as verziójában került tárolásra.
  • A Plugin.MaxConnectionsHit egy ragaszkodó munkamenet jelző, amely a WaitOnSendBarrier belsejében van beállítva; csak a MusicBee újraindításakor áll vissza.
  • A SettingsDialog.maxConnectionsBadge egy piros, félkövér címke a (16, 410) pozíción, amely csak akkor jelenik meg, ha a Plugin.MaxConnectionsHit Igaz. Tartalmaz egy eszköztippet, amely elmagyarázza az okot és a megoldást.
  • A szemafor egyszer inicializálódik típusbetöltéskor, így a beállítás módosítása MusicBee újraindítást igényel (a mező címkéjében megjegyezve).

F41 - Naplózza az „átkódolás ReplayGain/DSP miatt” üzenetet

Mi: a külön „kódolás RG-hez” / „kódolás DSP-hez” naplósorok helyett az F42-ből származó egyetlen StreamDecision sor tartalmazza az MB-DSP/EQ, MB-ReplayGain, Profile-DSP/EQ, Profile-ReplayGain értékeket mint felhalmozott okokat. Ugyanaz a diagnosztikai érték, kevesebb zaj.

Miért: a felhasználók az összes okot látják, amiért egy adott szám átkódolása történik, egyetlen naplósorban, nem szétszórva. Lásd az F42-t a teljes részletekért.


F42 - Naplózza, hogy „a renderelő nem támogatja a forráskodeket”

Mi: hozzáadott egy StreamDecision naplóbejegyzést minden lejátszási célpontra irányuló számhoz, amely azt mondja, hogy „natív CODEC” vagy „átkódolás CODEC→CODEC ok=…”. Az ok mező felhalmozza az összes feltételt, amely az átkódolást kiváltotta: MB-DSP/EQ, MB-ReplayGain, Profile-DSP/EQ, Profile-ReplayGain, WebFile, VirtualFile, ForceTranscoding(global), SampleRate<min/SampleRate>max, DownmixToStereo, DeviceLacksCodec(X), BandwidthConstrained.

Miért: a felhasználókat összezavarták a váratlan CPU-tüskék olyan fájloknál, amelyeket natívan streamelni vártak. Egy naplósor számonként pontosan megmondja nekik, melyik feltétel okozta az átkódolást – és ha a mező DeviceLacksCodec(Flac)-ot mutat, azonnal tudják, hogy az eszköz protokollinformációja hiányos volt, és esetleg szeretnék, ha az F32 visszalépése bekapcsolódna.

Megvalósítás: egyetlen akkumulátor karakterlánc, amelyet fokozatosan építenek fel a döntési láncon keresztül; egyszer naplózva a végén. A Settings.LogDebugInfo által vezérelve a naplózási zaj elkerülése érdekében éles környezetben.


F43 - SetNextAVTransport napló megjeleníti a forrás URL-t

Mi: a QueueNext naplóbejegyzések mostantól tartalmazzák a source=<MusicBee library path> értéket a stream=<HTTP streaming URL> mellett. Ugyanez a változás vonatkozik a sikeres útvonalra és a hibás útvonalra (QueueNext:Failed) is.

Miért: egy sorba állított szám problémájának hibakeresésekor a streaming URL (/encode/aabbccdd0.flac) önmagában átláthatatlan – minden számra ugyanaz. A forrás URL az ember által kereshető könyvtárútvonal, amely pontosan megmondja, melyik fájlt próbálta a MusicBee sorba állítani.


F44 - Jobb mime-típus hibanaplózás

Mi: két új naplóbejegyzés az Activate során:

  • Activate:MimeUnverified - minden hibás bejegyzésnél aktiválódik az eszköz GetProtocolInfo válaszában, megnevezve, melyik bejegyzést nem sikerült értelmezni (így a felhasználó láthatja pl. „a Marantz http-get:*::* értéket adott vissza valamilyen kodekhez – a képesség ellenőrizetlen, az F32 visszalépése találgatni fog”).
  • Activate:NoSinkInfo - egyszer aktiválódik, ha az eszköz egyáltalán nem adott vissza <Sink> elemet. Ez azt jelenti, hogy a SupportedMimeTypes Nothing marad, és az IsCodecSupported „feltételezzük, hogy minden működik” állapotba kerül – hasznos kontextus, amikor később „az eszköz megtagadta az adatfolyamot” hibák jelennek meg.

Miért: az F44 előtt ezek a csendes képesség-visszalépések a felhasználókat találgatásra kényszerítették, hogy miért kódolták át a számaikat az elvárásokkal ellentétesen, vagy miért utasította el az eszköz. Most egyetlen Activate: keresés megmutatja, hogy az eszköz képességinformációja használható volt-e.


F45 - Jobb metaadat hibanaplózás

Mi: a ContentDirectoryService.vb fájlban található Browse kivétel naplója már korábbi yaiol munkában (az Alia Vox hibajavító munkamenetben) bővült ObjectID-vel és stack trace-szel. Az F45 tovább bővíti BrowseFlag-gel (metaadat vs gyermekek), Filter-rel (mely attribútumokat kérte a kliens), sortCriteria-val és partialResultLength-szel (hány bájt DIDL készült a hiba előtt – ez mutatja, hogy a hibás szám hol helyezkedik el a kötegben).

Miért: ha valami elromlik a DIDL közepén, a részleges hosszúság érték megmondja, hogy a hiba a köteg első számánál (partial=0) vagy a közepén (partial=N) történt-e – a köteg startingIndex-ével kombinálva azonosíthatja a hibás szám indexét. A Filter és a BrowseFlag elmagyarázza, hogy a kliens milyen típusú böngészést akart; néha egy csak metaadat böngészés meghiúsul, ahol ugyanazon azonosítóhoz tartozó gyermek böngészés sikeres.


Hálózat

F46 - Az automatikus mód csak valódi hálózati adaptereken jelenti be magát

Mi: Automatikus interfészmódban a beépülő modul korábban minden működő IPv4-adapteren bejelentette magát (SSDP). Egy olyan gépen, amely VPN-alagutat (NordLynx) vagy virtuális kapcsolót (Hyper-V / WSL / Docker) is futtat, ugyanaz a könyvtár ezeken az adaptereken is bejelentésre került, így a vezérlőpont, ahonnan streamelsz, kétszer-háromszor fedezte fel a servert, és a könyvtárat duplikált másolatokként listázta. Az automatikus mód mostantól csak azokat az adaptereket tartja meg, amelyeknek valódi alapértelmezett IPv4-átjárójuk van (HasIPv4Gateway) - ami az alagút- és virtuáliskapcsoló-adaptereknek nincs -, így azok kikerülnek a bejelentési listából. A felhasználó által rögzített cím továbbra is mindent visz (bejelentés csak azon az interfészen), és ha egyik adapter sem jelez átjárót, a kiválasztó visszatér az összes adapterhez, így a bejelentett címek listája soha nem üres, és a beépülő modul nem válhat láthatatlanná.

Miért: a duplikációt nem az okozza, hogy „VPN-en vagy" - hanem az, hogy a bejelentés egyszerre történik a LAN-adapteren és az alagút-/virtuális adapteren, így egy vezérlőpont ugyanazt a servert két címen látja. Egy fogyasztói VPN (NordVPN/NordLynx) csak az internetre irányuló forgalmat alagutazza; a DLNA-renderer a LAN-on él, és a helyi alhálózati forgalom megkerüli az alagutat, így az alagút-adapter úgysem ér el soha renderert - az eltávolítása egy fantommásolatot szüntet meg, működő útvonalat soha. Az átjáróteszt az az olcsó, megbízható jel, amely a valódi LAN/Wi-Fi adaptert megkülönbözteti egy alagúttól vagy virtuális kapcsolótól. Kiegészíti az N05-öt (amely azt javította, hogyan küldődnek a bejelentések az ilyen kapcsolatokon - multicast broadcast helyett); az F46 azt szabályozza, mely adaptereken történik egyáltalán bejelentés.

Ismert korlát: egy mesh / távoli elérésű VPN (Tailscale, ZeroTier, WireGuard hazafelé), amelynek rendererei valóban az alagút túloldalán élnek, általában alapértelmezett átjáró nélküli adaptert mutat, így az automatikus mód azt is elveti. Ezek a felhasználók ehelyett a VPN-címet rögzítik, amely elsőbbséget élvez az átjárószűrővel szemben.