storaid

フォーラムへの返信

100件の投稿を表示中 - 1 - 100件目 (全348件中)
  • 投稿者
    投稿
  • storaid
    参加者

    Hi, Tiki,
    I finally realized why you were questioning the ‘event-preferred mode’ in the phrase:
    “– offer an optional lower fixed polling rate / event-preferred mode for users on embedded DMR platforms.”
    That is an internal term we use at our company!

    For us, ‘event-preferred mode’ means the system tries to establish an event subscription first, and only falls back to polling if the subscription fails.
    In this case, that is completely wrong.

    Please feel free to ignore it.
    I just realized it’s will be confusing and mistake.

    My apologies!

    storaid
    参加者

    Thanks for clarifying. Just to avoid any misunderstanding.

    I meant keeping GetPositionInfo as a fallback, but letting polling frequency adapt to playback state, with local time interpolation handling the seekbar in between.

    In any case, I appreciate that you’re considering improving the polling interval in a future release.

    storaid
    参加者

    Hello, Tiki

    I understand your concern about unreliable TransportState notifications, and I agree that GetPositionInfo must remain as a reliable fallback.

    What I’m trying to distinguish is not the existence of polling, but the frequency and role of polling.

    In practice, a fixed 1 Hz GetPositionInfo loop can become a significant burden for many DMRs, especially embedded or ARM-based renderers, as I observed during my tests.

    Without maintaining a local state timer on the control point side, aggressive polling can introduce side effects such as:
    – Interrupt pressure: even a 1 Hz SOAP request forces network soft-IRQs and context switches that interrupt the audio playback path.
    – Cache locality impact: repeated UPnP request handling can disturb instruction/data cache locality and introduce subtle timing jitter.

    Frequent GetPositionInfo calls also imply additional overhead:
    – TCP connection handling (depending on implementation details).
    – SOAP/XML processing cost, since each response requires constructing and serializing a formatted XML document containing TransportState, TrackDuration, and RelTime.

    In my tests, this constant polling correlated strongly with the odd behaviors I described earlier (see #17443), and I attempted to explain the underlying mechanism in #17444.

    To be clear, I’m not suggesting removing GetPositionInfo polling, but questioning whether a fixed 1 Hz rate is always necessary once playback is stable.

    Thank you

    storaid
    参加者

    Hello,

    Setting a longer polling interval is fine. What I don’t understand is what you mean by “event-preferred mode.”

    Sorry if my wording was unclear — I didn’t mean a new “event mode” or a different event mechanism.

    Since TuneBrowser already correctly implements GENA subscription and renewal, what I was suggesting is simply a more state-aware polling behavior that takes advantage of the existing events.

    – PLAYING
    Use GetPositionInfo at a lower rate (e.g. every 5–10 seconds, like “foobar2000”) mainly as a synchronization point, while letting the seek bar advance based on the local clock between polls.

    – PAUSED
    Greatly reduce polling frequency (e.g. every 30 seconds or not at all), or rely purely on event notifications, since the playback position is not expected to change.

    – STOPPED
    Suspend GetPositionInfo polling entirely, as there is no active playback and no new information to retrieve.

    So the idea is not to replace polling with events, but to let events drive state changes, and use polling only when it actually provides new information.

    This is just a refinement suggestion, given that eventing is already available.

    Thank you!

    storaid
    参加者

    Hello,

    Thanks for clarifying.

    I agree. That’s why TuneBrowser supports GetPositionInfo. Are you talking about some other means?

    The “other means” I was referring to is local time interpolation on the control point side.

    In most UPnP implementations, GetPositionInfo is typically used as a synchronization or correction mechanism, not as the primary clock source. Once the DMR reports a stable PLAYING state, the control point can estimate playback progress locally using its own clock, and only query the renderer periodically to re-align or correct drift.

    On MPD-based and other embedded DMRs, GetPositionInfo itself works correctly, but polling it at a fixed 1 Hz for the entire track duration creates continuous control-plane activity during playback and, more importantly, during pause/resume transitions when the renderer is already busy.

    from Stackoveflow

    This is also what I’ve mentioned many times before (#17442).

    This is why some long-standing UPnP implementations (for example foobar2000) rely on a combination of local interpolation and lower-frequency polling, rather than constant per-second queries (#17440, #17441).

    From my perspective, the issue is not that GetPositionInfo exists, but that it becomes the primary timing mechanism instead of a secondary correction mechanism in environments where position events are intentionally sparse.

    That’s why I’m wondering whether TuneBrowser could either:
    – rely more on local interpolation between GetPositionInfo updates, or
    – offer an optional lower fixed polling rate / event-preferred mode for users on embedded DMR platforms (#17442).

    Thank you!

    storaid
    参加者

    Hello, Tiki

    If it’s not LastChange::RelativeTimePosition, which event are you talking about?

    I mean..

    if my guess is right for what you mean “LastChange::RelativeTimePosition” event detection…

    What I’m trying to clarify is that if TuneBrowser relies on LastChange::RelativeTimePosition as the key signal for event-based detection, then in normal real-world scenarios this condition becomes almost impossible to satisfy.

    In my observations, as soon as playback starts, TuneBrowser immediately falls back to 1 Hz GetPositionInfo polling. As a concrete example, after playing a single 10:37 track, Wireshark captured a total of 640 GetPositionInfo requests before any meaningful LastChange activity could be observed.

    Given this behavior, doesn’t it effectively mean that most DMR implementations can never meet the required event-detection threshold? In practice, the vast majority of real-world DMRs are simply not designed to emit frequent RelativeTimePosition events.

    There are several practical reasons for this:

    1) Network layer: XML bloat and notification storms

    UPnP event notifications are not lightweight numeric updates. Each NOTIFY message is wrapped in HTTP headers, a SOAP envelope, and a verbose XML LastChange payload.

    This creates a packet amplification effect: to report a simple value such as “1:23”, the DMR must construct and transmit a full HTTP/SOAP/XML message.

    Moreover, GENA notifications are sent to all active subscribers. In a typical home setup (for example, two phones running control apps plus a PC running TuneBrowser), the DMR would need to send multiple independent TCP/XML notifications every second.

    At that frequency, XML parsing and transmission pressure can keep the network constantly busy, which is precisely why most implementations avoid eventing playback position continuously.

    2) Hardware layer: CPU load and jitter on DMRs

    On platforms such as Raspberry Pi 4 or embedded processors used in devices like Denon, emitting NOTIFY events every second can be more expensive than responding to occasional incoming requests.

    Each notification requires context switching: the CPU must temporarily leave the audio decoding/data plane, enter kernel space to process the network stack, construct the XML payload, and then return to user space. Even at 1 Hz, this introduces periodic CPU load fluctuations.

    3) Transport layer: TCP congestion and retransmission risk
    UPnP NOTIFY messages are transported over HTTP/TCP. Each notification requires acknowledgment from the control point.

    At a sustained 1 Hz rate, even minor network jitter (for example on Wi-Fi) can cause packet queuing. When frequent NOTIFY events collide with ongoing GetPositionInfo requests, the DMR’s communication buffers can become saturated, increasing latency and the likelihood of delayed or stale responses.

    Taken together, these factors explain why most DMR implementations deliberately avoid emitting frequent LastChange::RelativeTimePosition events.

    Thank you!

    storaid
    参加者

    Hello,

    The event is LastChange::RelativeTimePosition.

    Thanks for your answer

    But…I mean…

    It is very…very…… difficult!….

    In practice, LastChange::RelativeTimePosition is typically non-evented during normal playback. Emitting per-second position updates via GENA would flood the network with XML notifications, so most DMR implementations intentionally avoid this. Instead, they only include RelativeTimePosition in LastChange on state transitions (play/pause/seek/track change), and expect control points to interpolate playback progress locally between events.

    This seems to be the case for Volumio, Moode (MPD/upmpdcli), Denon (GStreamer-based), and also other long-standing implementations.

    Given this, the absence of frequent RelativeTimePosition events is not a renderer limitation, but rather the expected and correct behavior in the AVTransport ecosystem. As a result, TuneBrowser’s current event-detection criterion may never be satisfied on a large class of real-world DMRs, causing the 1 Hz polling fallback to become the steady-state behavior.

    Thank you

    storaid
    参加者

    Hello,
    Based on further packet captures,

    On Volumio (MPD/upmpdcli), playing a single 10:37 track resulted in 640 GetPositionInfo calls captured in Wireshark — effectively sustained 1 Hz polling for the entire playback duration. I have not been able to observe any reduction in polling frequency in this scenario.

    Given this real-world behavior, could you advise what conditions would actually allow TuneBrowser to reduce the polling rate in practice?

    Specifically:
    – Is there anything a user or renderer can realistically do to help TuneBrowser reach the “event-driven feasible” state?
    – Or is sustained 1 Hz polling the expected behavior on MPD-based DMRs?

    From a DMR perspective, especially on ARM-based devices, 1 Hz SOAP polling for the entire track duration represents a non-trivial control-plane load. I’m trying to understand whether there is a practical way to avoid this.

    Thank you!

    storaid
    参加者

    I’ve done fairly extensive testing across several common DMR platforms — Volumio (MPD), Moode (MPD), and Denon (GStreamer/libsoup3) — using both audiophile-oriented and enterprise-grade network setups.

    Across all of these environments, I consistently observed that TuneBrowser remains in 1 Hz polling mode, even after long, stable playback sessions. In practice, I haven’t yet seen a case where the polling frequency is reduced based on event detection alone.

    This makes me wonder whether the current event-detection criteria might be difficult to satisfy for many real-world DMR implementations, especially around pause/resume and other state transitions.

    When fallback polling stays at 1 Hz, it can have some unintended side effects on ARM-based renderers (e.g. Raspberry Pi), such as increased control-plane load during already busy state changes, and delayed or batched responses that surface as seek bar jumps.

    storaid
    参加者

    Hello,

    TuneBrowser prioritizes events. Once a certain number of events detected, it determines that event-driven operation is feasible and reduces the polling frequency. Otherwise, it performs polling every second.

    Thanks for explaining the adaptive logic.

    Could you clarify which specific events (and roughly how many) TuneBrowser expects to observe before it considers event-driven operation reliable enough to reduce polling? In my tests with Volumio and Moode, as I mentioned before, even after extended playback (e.g. 10 minutes), the polling frequency remained at 1 Hz.

    One thing I’m wondering about is whether, during pause/resume or other state transitions, the fallback polling itself could make event delivery appear less reliable. On platforms like the Raspberry Pi, frequent SOAP requests can consume CPU interrupts while the renderer is already busy, which might delay or batch GENA notifications.

    This could potentially make it harder for TuneBrowser to reach the threshold where it trusts event-driven operation, effectively keeping it in polling mode longer than intended.

    Would you consider exposing an optional manual mode, such as “low-frequency polling” or “event-preferred” operation, for users who are confident in their renderer behavior? This could be useful on embedded or audiophile-oriented systems where minimizing control-plane activity is desirable, even if the automatic detection remains conservative by default.

    As an additional reference point, I also observed how foobar2000’s UPnP implementation behaves in similar scenarios.

    From packet captures, foobar2000 appears to poll GetPositionInfo at a much lower and fixed interval (around once every 5-10 seconds), and relies heavily on local time tracking between updates rather than frequent polling to drive the seek bar.

    I mention this only as a real-world reference, in case it’s useful when considering trade-offs between adaptive polling and event-driven behavior on some poor-resource renderers.

    Thank you!

    storaid
    参加者

    After further observation on both Volumio and Moode (running on Raspberry Pi 4 and RK3328 platforms), I noticed several recurring behaviors when TuneBrowser continues polling GetPositionInfo once per second:

    1. State desynchronization:
      Sometimes, after pressing PAUSE or STOP, TuneBrowser stops calling
      GetPositionInfo as expected. But other times, even though the DMR is
      clearly in PAUSED/STOPPED state, TuneBrowser continues polling at 1 Hz.
      From packet observation, it looks like the state transition (PLAYING → PAUSED) sometimes arrives late through eventing, especially when the renderer is likely busy with a pause/play pipeline transition.
    2. Non‑linear seek bar jumps:
      During pause → resume transitions, the DMR often becomes momentarily overloaded.
      This results in delayed or out‑of‑order GetPositionInfo responses, which appear as sudden jumps or “irregular movement” in the seek bar.
    3. Fallback values such as 00:00:00:
      Under higher load, some DMRs temporarily return TrackDuration = 0:00:00, even though playback is actually progressing correctly.
      This causes the seek bar in TuneBrowser to reset unexpectedly.

    Even though the Raspberry Pi 4 is quite powerful, it still uses a GIC‑400 interrupt controller and a lightweight network stack.
    Because of this, a 1 Hz SOAP/HTTP/XML request loop can impose more load than expected—especially during pause/play transitions where the audio pipeline is already busy.

    These are just observations from real devices that may help refine the behavior further.
    TuneBrowser is excellent software, and I appreciate the ongoing development.
    I hope this feedback is helpful.

    Thank you!

    storaid
    参加者

    Hello,

    I would like to report the current situation.

    I have tested two mainstream DMR platforms, Volumio and Moode, on different hardware platforms—one based on RK3328-JD4 and the other on Raspberry Pi 4 (8 GB). Both exhibit very similar behavior.

    Network topology:

    PC (2.5 GbE)
    → UniFi UDM Pro SE (business-grade router/NGFW)
    → iFi-audio OMNI LAN switch (audiophile network switch)
    → Volumio / Moode DMR

    Volumio:
    After pressing PAUSE and waiting for some time, then resuming playback, the seek bar starts to behave abnormally.

    Moode:
    I do not believe the situation is any better. Under the same test conditions, the seek bar behavior is even more erratic. I restarted Moode and repeated the test, but the issue remained—the seek bar still shows non-linear jumps. When I checked Moode’s own web UI, playback time appears to be calculated correctly, so I am not sure where the discrepancy originates.

    Initially, I suspected the OMNI LAN switch might be causing the issue, so I powered it off and restarted it. However, the behavior remained unchanged, so this factor can likely be ruled out.

    I also used several UPnP development tools to manually invoke GetPositionInfo, and did not observe any abnormal responses.

    Under continuous playback without pausing, this issue does not seem to occur (at least not obviously). However, pausing playback for a period of time or skipping to the next track are very common usage scenarios when listening to music, so this behavior is difficult to ignore.

    Thanks

    storaid
    参加者

    Now GENA event subscription and renewal mechanism is already correctly implemented.

    Given that eventing is available, I was wondering whether a state-aware polling approach could be considered as a small refinement.

    For example:

    PLAYING: Poll GetPositionInfo at a lower rate (e.g. every 5–10 seconds) and use it mainly as a synchronization point, while the seek bar progresses based on a local clock.

    PAUSED: Greatly reduce the polling frequency (e.g. every 30 seconds), or rely on event notifications only, since the playback position is not expected to change.

    STOPPED: Suspend GetPositionInfo polling entirely, as there is no active playback state and no additional information to be gained.

    Of course, this is just a design suggestion, but I thought it might be worth considering given that event subscription is already in place.

    Thanks again for your work on TuneBrowser.

    storaid
    参加者

    Some DMR implementations may continue advancing their internal playback clock while paused, for example due to buffered data or internal pipeline behavior. When playback is resumed, the first value reported by GetPositionInfo may reflect a predicted playback position rather than the actual current position.

    Some control points do not rely solely on periodic polling (e.g., once per second) to move the seek bar, as that would result in visibly stepped movement. Instead, they treat the values returned by GetPositionInfo as synchronization points, and interpolate the seek position between calls using a local clock on the control point side.

    From packet capture, it can be observed that even when the transport state is PAUSED or STOPPED, TuneBrowser continues to invoke GetPositionInfo at a fixed rate (approximately once per second).

    While this behavior is permitted by the UPnP specification, have you considered reducing or suspending polling in non-playing states, or using a lower polling frequency combined with local time tracking? Some control points adopt this approach to reduce unnecessary control-plane traffic and renderer load, particularly on embedded DMR platforms.

    If this issue were raised with Volumio, the response would likely be that this behavior is primarily under the control point’s responsibility, as the frequency of GetPositionInfo calls is unusually high.

     

    Without maintaining an internal state timer, excessive polling may lead to the following conditions:

    • Interrupt pressure: Even at one request per second, network soft-IRQs can force the CPU to frequently switch from the audio playback path into kernel space to process network traffic.
    • Cache locality effects: Repeated UPnP request handling may disturb instruction and data cache locality, potentially introducing subtle timing jitter.

    A high rate of GetPositionInfo calls also implies additional overhead such as:

    • TCP connection handling: Each poll may involve connection setup and teardown, depending on the implementation.
    • XML parsing cost: UPnP is SOAP-based, so each response requires the renderer to construct and serialize a formatted XML document containing fields such as TransportState, TrackDuration, and RelTime, which consumes CPU cycles.

    My hypothesis is that after pausing playback for some time and then resuming, the observed non-linear seek bar jumps may be caused by TCP retransmissions or SOAP timeouts. During pause/resume boundary conditions, some DMR UPnP stacks may temporarily stall.

    If GetPositionInfo requests overlap or time out during this period, the renderer may delay responses. Once its internal buffers are cleared, it may suddenly report a much later playback position (for example, jumping from 0:03 directly to 0:10), causing the seek bar to visibly jump in a non-linear manner.

    Thanks

    storaid
    参加者

    AFAIK…

    There are existing control points (e.g. BubbleUPnP, JPLAY) that intentionally avoid high-frequency GetPositionInfo polling.

    The motivation is usually not sound quality per se, but reducing control-plane traffic, CPU wakeups, and dependency on renderer timing behavior—especially on embedded platforms.

     

    * For some Audiophiles viewpoint:

    In audiophile theory, this is often categorized as an issue of “electrical noise” and “CPU load jitter.”

    Network and CPU load:
    Issuing a GetPositionInfo call once per second causes the renderer (the receiving device) to continuously process network packets at the NIC level, while the CPU must periodically divert execution from the audio playback path to handle UPnP stack requests. This activity can introduce small fluctuations in current draw.

    Resource contention:
    Although modern CPUs are generally overpowered, systems that aim for ultimate sound quality tend to treat any unnecessary interrupts as undesirable. Frequent control requests may disrupt the smoothness of data flow and, in theory, affect clock stability. While this occurs at the network and software layers, proponents argue that the effects may ultimately manifest as increased electrical noise at the circuit level.

    storaid
    参加者

    Hello Tiki,

    Thanks for the clarification.

    I noticed from packet capture that GetPositionInfo is currently being called roughly once per second.

    Test DMRs: volumio, moode

    Out of curiosity, is this polling frequency a deliberate design choice?

    I’ve seen some control points reduce or avoid periodic GetPositionInfo polling, partly to minimize control-plane traffic and potential impact on playback stability or sound quality.

    Is there any consideration for alternative strategies, such as lower-frequency polling or event-driven updates?

     

    storaid
    参加者

    Hello Tiki,

    Please feel free to close this topic.

    Given the current UPnP-compliant design, I think it is an appropriate time to conclude this discussion.

    Thank you.

    storaid
    参加者

    I would like to express my disappointment with my recent experience with DENON support.
    The DENON support I interacted with years ago — which was capable of understanding protocol-level UPnP issues — appears to no longer exist.

    I contacted them regarding a UPnP issue strictly limited to WAV / LPCM / L16, yet the response I received consisted of questions such as:

    1. Whether the same problem occurs with MP3
    2. Whether the same problem occurs with FLAC
    3. Whether a specific FLAC sample can be provided
    4. Requests for HEOS diagnostic logs
    5. Requests for a list of network devices
    6. Questions about the third-party seek bar
    7. Requests for generic reproduction steps

    Given the context, these questions were extremely basic and largely irrelevant to the issue being reported.
    They indicate that the original description was either not carefully read or not technically understood.

    I had already provided detailed technical background, clearly explaining that this is a format-specific UPnP behavior affecting uncompressed PCM formats, not a general playback or content-compatibility problem.

    In the past, when I raised UPnP-related questions to DENON support, they were at least able to grasp the technical intent and respond accordingly.
    With the current level of interaction, I can only lower my expectations to the minimum.

    🙁

     

    返信先: Audiophile UPnP Renderer is not working! #17410
    storaid
    参加者

    Hello, WanFie

    The AudiophileUPnP Renderer hasn’t been maintained for a long time. I also wonder why you’d want the AudiophileUPnP Renderer.

    It’s only for UPnP debugging and testing..

    Thank you!

    storaid
    参加者

    Hello Tiki,

    I checked the log.

    Your Wireshark capture shows that the renderer is gettting next track ((03) [KOKIA] 愛のメロディー (soundtrack ver.).wav).

    Your renderer is checking first track and next track at almost same time. I think what you saw was the second GET.

    Thank you very much for reviewing the logs and confirming the actual HTTP transaction details.

    Upon double-checking my Wireshark capture and refining my filtering criteria, I’ve realized my mistake:

    I mistakenly analyzed the GET request for the next URI, not the actively playing track.
    After properly isolating the initial URI, I can confirm the Content-Length provided by TuneBrowser was entirely correct.

    I apologize for the confusion—sometimes with Wireshark’s rapid packet updates and multi-threaded track management, it’s easy to mix up request contexts.

    Unfortunately, with the DENON HEOS (GStreamer/libsoup3) environment, TrackDuration for WAV/LPCM/L16 still consistently returns 00:00:00, but I think that this may relate to DLNA tag support.

    It’s not a pure UPnP Renderer.

    Denon & Marantz Group devices…Orz

    Based on my guess (I’m not sure!), it appears that the HEOS system (which uses GStreamer/libsoup3 under the hood) relies heavily on commercial DLNA metadata, particularly DIDL-Lite attributes and DLNA-specific headers/flags, to accurately detect and report track duration and seek capabilities. When these DLNA extensions, such as contentFeatures.dlna.org and DLNA.ORG_OP, are missing from the server’s response, HEOS treats the incoming stream as a live or linear broadcast, resulting in zero duration and disabling seeking functions.

    Since TuneBrowser does not support commercial DLNA metadata extensions—by design, and as you mentioned long time ago— maybe this is the root cause of the missing duration metadata and seekbar issues in HEOS and similar devices.

    Thank you again for your patience and confirmation!

    返信先: Audiophile UPnP Renderer is not working! #17406
    storaid
    参加者

    Ok

    Thank you

    storaid
    参加者

    Hello, Tiki

    Still I can not change default value of SUBSCRIBE timeout advance (sec).

    It always keep 30 sec.

    Could you help me confirm to that?

    Thanks

    storaid
    参加者

    Hello, Tiki

    Here is the log file with handling Content-Length: 74508492 case

    Plz check it!

    Thank you

    storaid
    参加者

    Hello,

    Sorry! Tiki

    I still have a question regarding how TuneBrowser determines the Content-Length value in HTTP 200 OK responses for WAV/LPCM/L16 files.

    As described in RFC9110 Section 8.6, the Content-Length header should indicate the total length of the HTTP response’s message body in bytes. This length should reflect exactly the number of octets being transmitted as content, including all file header and data chunks, matching the actual file size as stored on disk.

    For reference, RFC9110 states:

    “The ‘Content-Length’ header field indicates the associated representation’s data length as a decimal non-negative integer number of octets. … When transferring a representation as content, Content-Length refers specifically to the amount of data enclosed so that it can be used to delimit framing.”

    “A sender MUST NOT forward a message with a Content-Length header field value that is known to be incorrect.”

    RFC9110: https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length

    MDN: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Length

    Given this, I would appreciate it if you could clarify how TuneBrowser calculates Content-Length. For example, is it based on the actual file size reported by the operating system, or is it derived from a calculation based on the file’s internal structure or audio chunks?

    In my testing, I’ve noticed incongruities between the Content-Length header and the file size reported by Windows File Explorer or file system APIs.

    Something-based Content-Length (v5.9.2): 74508492

    Content-Length: 48620028

    File Size (from Windows): 46.3 MB (48,623,616 bytes)

     

    Thank you for your continued support and development!

    storaid
    参加者

    Sorry

    but I don’t really get it!

    v5.8.1 (GStreamer souphttpsrc 1.22.12 libsoup/3.6.5)

    
    
    HTTP/1.1 200 OK
    
    Accept-Ranges: bytes
    
    ...
    
    TuneBrowserIFID: 0ba67ab5
    
    Content-Length: 48620028
    
    

    v5.9.2 (GStreamer souphttpsrc 1.22.12 libsoup/3.6.5)

    
    
    HTTP/1.1 200 OK
    
    Accept-Ranges: bytes
    
    ...
    
    TuneBrowserIFID: 0ba85cb4
    
    Content-Length: 74508492
    
    
    storaid
    参加者

    Hello,

    So strange….!! =_=

    I tested the exact same WAV URI with another DMR, iFi audio ZEN Stream, which is MPD-based.
    In this case, the HTTP response returned a Content-Length that matches the approximately actual file size:

    
    
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Content-Encoding: identity
    Content-Type: audio/wav
    TuneBrowserIFID: 0b8aa17f
    Content-Length: 48620028
    
    

    File Size: 46.3 MB (48,623,616 bytes)

    After downloading the URI directly, I confirmed that the actual file size is approximately 48.6 MB, which is consistent with this value.

    However, when the same URI is requested by the DENON DMR (GStreamer + libsoup3), the response is:

    
    
    User-Agent: GStreamer souphttpsrc 1.22.12 libsoup/3.6.5
    Content-Length: 74508492
    
    

    Since:

    • the URI is identical,
    • the HTTP status is 200 OK in both cases,
    • and no Range request is involved,

    this suggests that TuneBrowser is applying different Content-Length calculation strategies depending on the client (User-Agent).

    The MPD-based path clearly demonstrates that TuneBrowser can provide the correct file-based Content-Length for WAV content.
    The GStreamer/libsoup3 path, however, appears to use an estimated something-based length instead, which does not match the actual payload and causes issues with strict HTTP clients.

    I hope this comparison is helpful, and I’m happy to run additional tests if needed.

    Thank you

    storaid
    参加者

    Hello Tiki,

    I would like to report an observation related to WAV / LPCM / L16 playback behavior.

    When I call GetPositionInfo, the returned TrackDuration is always 00:00:00 for WAV / LPCM / L16 streams, while most other formats return a valid duration as expected(STREAMINFO/metadata).

    * WAV / LPCM / L16

    
    
    libsouphttpsrc
    ↓
    typefind
    ↓
    wavparse / qtdemux / decodebin
    
    

    My suspicion is that this behavior may be related to the stricter requirements of DENON’s GStreamer / libsoup3 stack.
    When I tested with several MPD-based DMRs, the same content worked correctly and TrackDuration was reported as expected.

    One notable difference is that MPD does not rely on HTTP Content-Length to determine media duration.
    Instead, duration is derived from metadata (such as DIDL-Lite res@duration) or from decoder-level information, which makes it more tolerant of non-file-based streaming semantics.

    I also noticed that some UPnP development tools explicitly use Transfer-Encoding: chunked for WAV / LPCM streams, which avoids the need to declare a precise Content-Length when the final size is not known in advance.

    For comparison, foobar2000’s UPnP implementation works reliably in all cases.
    Its design is quite deliberate: it intentionally sets a sentinel Content-Length (around 4 GB) as a fake length, and it does not trust the renderer’s DIDL res@duration or TrackDuration at all.
    Instead, foobar2000 calculates and maintains the true track duration internally based on the original file metadata.

    This difference in design may explain why some renderers (especially those based on GStreamer / libsoup3) react differently to WAV / LPCM streams.

    I hope this information is useful as a reference, and I would be happy to provide additional test data if needed.

    Thank you!

    storaid
    参加者

    Hello Tiki,

    Based on the GET request issued by the DMR, I accessed the following URI directly:

    [audio src="http://10.1.1.166:29400/TuneID/00018084-RFH-0BC02582.wav" /]

    After downloading it manually, I confirmed that the file size is 46.3 MB (48,623,616 bytes), which matches the size of the original WAV file exactly.

    Given this, I’m a bit unclear about how the following header value is being calculated:

    Content-Length: 74,508,492

    Could you please clarify how this Content-Length value is derived?

    Thank you!

    storaid
    参加者

    Hello, Tiki

    In my case,

    
    
    HTTP/1.1 200 OK
    
    Accept-Ranges: bytes
    
    Content-Encoding: identity
    
    Content-Type: audio/wav
    
    TuneBrowserIFID: 0aeb740c
    
    Content-Length: 74508492
    
    

    I’ve verified that the original WAV file size is 48,623,616 bytes.
    However, the HTTP response for the TuneID URI reports:

    Content-Length: 74,508,492

    Could you please clarify whether this TuneID URI is serving:
    1) the original WAV file as-is, or
    2) a dynamically generated WAV / PCM stream (e.g. decoded or reformatted audio)?

    If it is the latter, that would explain the size difference and would help clarify how Content-Length is currently being calculated.

    storaid
    参加者

    Hello Tiki,

    Thank you for your reply.

    Since reading RFC 9110 in full can be quite time-consuming, it may be easier to confirm this part of the HTTP specification using the MDN documentation, which is widely regarded as an authoritative reference:

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/206

    (JP: https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Status/206)

    MDN states:

    The HTTP 206 Partial Content successful response status code is sent in response to a range request. The response body contains the requested ranges of data as specified in the Range header of the request.

    The format of the response depends on the number of ranges requested. If a single range is requested, the Content-Type of the entire response is set to the type of the document, and a Content-Range is provided. If several ranges are requested, the Content-Type is set to multipart/byteranges, and each fragment covers one range, with its own Content-Range and Content-Type headers describing it.

    From this description, we can see that Content-Range is used with a 206 Partial Content response, and that this behavior depends on whether the DMR (client) actually sends a Range request header.
    If no Range header is present in the request, the server should return 200 OK instead.

    For example, MDN provides the following request:

    
    
    GET /z4d4kWk.gif HTTP/1.1
    Host: images.example.com
    Range: bytes=21010-
    
    

    Here, the client explicitly includes a Range header, so the server responds with:

    
    
    HTTP/1.1 206 Partial Content
    Date: Wed, 15 Nov 2015 06:25:24 GMT
    Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT
    Content-Range: bytes 21010-47021/47022
    Content-Length: 26012
    Content-Type: image/gif
    ETag: "abc123"
    Accept-Ranges: bytes
    
    

    From this response, we can also note that Content-Range is required in a 206 response, and that its format is important.
    According to RFC 9110, the syntax is defined as:

    Content-Range = range-unit SP ( range-resp / unsatisfied-range )

    This means a range-unit (for example, bytes) must be present.
    Following the MDN example:

    Content-Range: bytes 21010-47021/47022

    is a valid Content-Range header, whereas a format such as:

    Content-Range: 0-59773209/59773210

    is not compliant. On stricter DMR implementations, such a header may lead to state-machine confusion or timing-related side effects.

     

    As a practical comparison, here is an example of a UPnP WAV streaming exchange using foobar2000:

    Client request:

    
    
    GET /04EBE99C-6FDA-4F3B-8A2D-29E013CC686E/stream.wav HTTP/1.1
    User-Agent: GStreamer souphttpsrc 1.22.12 libsoup/3.6.5
    Accept-Encoding: identity
    Connection: Keep-Alive
    Host: 10.1.1.166:62738
    
    

    Server response:

    
    
    HTTP/1.1 200 OK
    TransferMode.dlna.org: Streaming
    Server: PFCv2/1.0
    Content-Type: audio/wav
    Content-Length: 4294967294
    Connection: close
    Accept-Ranges: none
    
    

    Ignoring the DLNA-specific headers (which are not relevant here), we can see that the 200 OK response does not include a Content-Range header, which is consistent with the HTTP specification.

    Thank you

    storaid
    参加者

    Hello Tiki,

    In this case,

    DENON uses GStreamer with libsoup 3, which is an HTTP library.

    Compared to libsoup 2, libsoup 3 is more strict about HTTP protocol compliance. This change can affect commercial DMRs that rely on such libraries.

    Because of this, it may be necessary to follow the HTTP specification more closely.

    For example, in an HTTP 200 OK response, the Content-Range header is not something that can be added arbitrarily according to RFC 2616, RFC 7233, and RFC 9110.

    Thank you.

    storaid
    参加者

    Hello Tiki,

    Thank you for the clarification.
    Let me try to restate my question more precisely, as I think there may have been a misunderstanding.

    I am not questioning the correctness of the calculated values (first/last byte positions or total length).
    I understand that those were carefully computed, including the WAV header.

    My concern is purely about HTTP semantics, independent of UPnP or implementation tolerance.

    Specifically, my question is:

    In HTTP/1.1 semantics, is it valid for a response with status
    200 OK to include a Content-Range header at all?

    According to my understanding of RFC 2616 §14.16 and RFC 7233, Content-Range is defined to describe a partial entity-body, and is normally associated with 206 (Partial Content) or 416 responses.

    (Or RFC9110: https://datatracker.ietf.org/doc/html/rfc9110#name-content-range)

    So my question is not whether a client can ignore the header, but whether this header/status-code combination has a defined meaning in the HTTP specification, or if it falls into an undefined / non-standard area that some clients may handle differently.

    I hope this clarifies what I was trying to ask.
    Thank you again for your time and for the excellent work on TuneBrowser.

    storaid
    参加者

    Hello, Tiki,

    If your HTTP/HTTPS functionalities are implemented using hand-written sockets or raw HTTP generators, I would like to offer a small suggestion. If not, please feel free to skip this message.

    Maintaining clean and robust code helps avoid unexpected RFC edge case issues. By directly using modern and efficient HTTP libraries—such as Boost.Beast, libmicrohttpd, or cpp-httplib—you can prevent subtle mistakes commonly made with hand-crafted implementations, like generating non-standard header combinations or mismatched status codes and headers (for example, returning 200 OK with a Content-Range header).

    Otherwise, you may encounter DMRs that use industry-standard commercial HTTP/HTTPS libraries, which can be much stricter about protocol compliance during handshakes.

    Please consider this suggestion.

    Thank you very much for your excellent work.

    storaid
    参加者

    If my memory serves me correctly regarding HTTP semantics:
    When playback initially starts, the DMR issues an HTTP GET request. In this case, the server should return 200 OK, and the Content-Range header is not required (and according to RFCs, it should not be present).

    However, the situation changes when the Seekbar is moved. To handle seeking, the server is expected to return 206 Partial Content. In this scenario, the response structure is different; for instance, the Content-Range header becomes mandatory to define the specific byte range being delivered.

    Since DENON relies on GStreamer (which uses libsoup for its HTTP/HTTPS implementation), it tends to be much more strict about protocol compliance compared to other players like MPD. GStreamer’s state machine might become confused or fail if it encounters a Content-Range within a 200 OK response, as this contradicts standard HTTP behavior.

    storaid
    参加者

    Interesting..

    It’s my quess!

    FLAC works fine because GStreamer can extract duration from the FLAC STREAMINFO header itself.

    However, WAV and LPCM fail because they rely heavily on accurate HTTP metadata (Content-Length/Range) to determine duration.

    The non-standard Content-Range in 200 OK is specifically breaking formats that depend on transport-level length signaling.

    storaid
    参加者
    storaid
    参加者

    Hello, Tiki

    I did a bit of investigation recently and captured some traffic using Wireshark.
    I still need some time to further check the subscription mechanism, but I already have a few questions.

    First, I extracted some packets from Wireshark for inspection.
    Below is the HTTP GET handshake for a WAV file.

    Request (DENON → TuneBrowser):

    
    
    GET /TuneID/00018083-RFH-7CD83014.wav HTTP/1.1
    User-Agent: GStreamer souphttpsrc 1.22.12 libsoup/3.6.5
    Accept-Encoding: identity
    Connection: Keep-Alive
    Host: 10.1.1.166:29400
    
    

    a bit tough! GStreamer..Orz

    Response (TuneBrowser → DENON):

    
    
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Content-Range: 0-59773209/59773210
    Content-Encoding: identity
    Content-Type: audio/x-wav
    TuneBrowserIFID: 09e42e96
    Content-Length: 59773210
    
    

    I have a couple of questions:

    1. I am a bit confused about the Content-Type.
    Why does it return audio/x-wav instead of audio/wav?

    2. If we step outside the UPnP context and look purely at HTTP semantics,
    is the Content-Range field in this response actually correct?

    I am trying to recall my old TCP/IP knowledge, but I must admit that much of it has already been “returned to my professors.”
    So my understanding and references are somewhat limited.

    The main references I looked at are:

    RFC 2616
    https://datatracker.ietf.org/doc/html/rfc2616#section-14.16

    RFC 7233
    https://datatracker.ietf.org/doc/html/rfc7233#section-4.2

    Could you please help double-check this behavior?

    Thank you very much for your excellent work on TuneBrowser.

    storaid
    参加者
    storaid
    参加者

    Hello, Tiki,

    I hope you are doing well. I would like to share an interesting technical observation regarding the interaction between TuneBrowser and the iFi Audio ZEN Stream.

    After using the ZEN Stream as a UPnP Renderer for a while, I have occasionally encountered a situation where its internal UPnP stack (such as libupnp/upnpdcli) crashes, which makes re-initialization impossible without a hard reboot of the device.

    Based on my analysis using Wireshark, I suspect this might be related to a potential memory leak, possibly caused by a large number of redundant SUBSCRIBE operations.

    I am considering SSHing into the ZEN Stream’s Linux to further monitor the process behavior, but I wanted to share these findings with you first.

    Thank you very much for your excellent work on TuneBrowser!

    storaid
    参加者

    Hello, Tiki,

    The fragmentation of MIME standards is indeed a complex issue, and referencing relevant RFCs can be challenging. This is closely related to historical baggage—complete standardization is simply not feasible.

    As you review different RFC documents, you may notice situations where:

    1. There are occasional conflicts.
    2. The specifications try to resolve or interpret each other.

    Ultimately, there is no unified solution—this ideal does not exist in reality.

    For instance, as highlighted in RFC 6648 Section 2 (“Recommendations for Implementers of Application Protocols”):
    > Implementations of application protocols MUST NOT make any assumptions about the status of a parameter, nor take automatic action regarding a parameter, based solely on the presence or absence of “X-” or a similar construct in the parameter’s name.

    The use of “MUST NOT” as defined by RFC 2119 carries a strong normative prohibition. RFC 6648 also clearly lays out the historical context for deprecating the “x-” prefix.

    Signalyst’s reliance on custom types like “x-dsd/x-dff/x-dsf” is simply their interpretation, driven by their own commercial ecosystem (e.g., Roon), and should be considered only as a reference, not a universal standard.

    Looking for further clarification, RFC 6838 offers guidance, though it’s admittedly long and complex. Section 3.4 (“Unregistered x. Tree”) and the grandfather clause (Appendix A, Grandfathered Media Types) expand on the importance of backward compatibility.

    Due to the historical context of MIME, backward compatibility must be considered. Otherwise, strict adherence to only the types registered in the IANA registry would impact a very broad range of users and devices, with severe consequences.

    Thank you very much for your excellent work.

    storaid
    参加者

    Hello,

    If my attitude toward the “x-” prefix sounded a bit harsh, please accept my apology.
    I don’t intend to criticize Jussi Laako (Signalyst) personally regarding Sony’s DSD format.
    He is simply very much a fundamentalist when it comes to standards — IANA is essentially his “bible,” and he has a strong preference for strict determinism.

    In the old specification era (RFC 2045), unregistered media types were indeed required to use the “x-” prefix.
    However, this rule was officially abolished in 2012 with RFC 6648.

    Therefore, his view on the “x-” prefix reflects Signalyst’s own interpretation, rather than the current industry practice.

    Thank you!

    storaid
    参加者

    The MIME type audio/dsf will never appear in the IANA registry because DSF is a proprietary format originally created by Sony.

    It is indeed a peculiar situation.

    DSD is not widely popular, and under normal circumstances its fate should have been similar to MQA.

    However, the history of DSD is different: unlike MQA, its adoption was not tied to a strict commercial licensing scheme, and a large number of DACs and AVRs eventually added native support for it.
    This widespread hardware compatibility is the main reason why the DSD/DSF format continues to survive today.

    The HQPlayer developer (Signalyst) appeared to deflect the issue in his response.

    Maybe..

    He relied on the obsolete “x- prefix convention” — formally deprecated 14 years ago — as justification, which effectively masks either limitations in his parser implementation (I don’t think so..) or a decision not to support the format for business-related reasons.

    In reality, Sony never submitted a formal media type registration for DSF to IANA.

    Thank you

    storaid
    参加者

    I did not see this issue when testing with version 5.8.1.

    Please don’t strictly require MIME types that begin with the “x-” prefix.

    There is no such rule in IANA, and RFC 6648 officially deprecated the “x-*” convention.

    The reason many DMRs still list MIME types beginning with “x-” is simply due to historical legacy, not because they follow a formal standard.

    Thank you very much for your excellent work.

    storaid
    参加者

    Correct!

    UDA 2.0

    https://openconnectivity.org/upnp-specs/UPnP-arch-DeviceArchitecture-v2.0-20200417.pdf

    Page 89, 4.1.1 Subscription

    Page 91, 4.1.2 SUBSCRIBE with NT and CALLBACK

    Page 94, 4.1.3 Renewing a subscription with SUBSCRIBE with SID

    Thank you

    storaid
    参加者

    Hello, Tiki

    Here is what I know about UPnP..
    The behavior I mentioned—renewing an existing event subscription using the SID—comes directly from the UPnP Device Architecture (UDA) specification.

    Here are the relevant parts of the specification:

    UPnP Device Architecture 1.0 / 1.1 — Eventing (Section: GENA Eventing)

    1. Initial SUBSCRIBE
    The controller sends:
    CALLBACK
    NT: upnp:event
    TIMEOUT

    Example:

    
    
    Hypertext Transfer Protocol
    SUBSCRIBE /upnp/event/renderer_dvc/AVTransport HTTP/1.1\r\n
    Request Method: SUBSCRIBE
    Request URI: /upnp/event/renderer_dvc/AVTransport
    Request Version: HTTP/1.1
    HOST: 10.1.1.142:60006\r\n
    USER-AGENT: Windows/10.0 UPnP/1.1 ohNet/1.0 TuneBrowser/1.0\r\n
    CALLBACK: <http://10.1.1.166:29500/SR_AVTransport.notify>\r\n
    NT: upnp:event\r\n
    TIMEOUT: Second-360\r\n
    Content-Length: 0\r\n
    [Content length: 0]
    \r\n
    
    

    Then, DMR return the following:

    
    
    Hypertext Transfer Protocol
    HTTP/1.1 200 OK\r\n
    Response Version: HTTP/1.1
    Status Code: 200
    [Status Code Description: OK]
    Response Phrase: OK
    Connection: Keep-Alive\r\n
    Content-Length: 0\r\n
    [Content length: 0]
    SERVER: Linux/4.4.167+, UPnP/1.0, Portable SDK for UPnP devices/4.0.14\r\n
    TIMEOUT: Second-300\r\n
    SID: uuid:cff1b202-e395-1370-b3aa-80e94ad851a3\r\n
    \r\n
    
    

    Please remember SID, TIMEOUT

    2. Subscription Renewal (Re-SUBSCRIBE)
    To extend the duration of an existing subscription before it expires, the controller must send a SUBSCRIBE request using the existing SID (uuid:<first subscription sid>):

    
    
    Hypertext Transfer Protocol
    SUBSCRIBE /upnp/event/renderer_dvc/AVTransport HTTP/1.1\r\n
    Request Method: SUBSCRIBE
    Request URI: /upnp/event/renderer_dvc/AVTransport
    Request Version: HTTP/1.1
    HOST: 10.1.1.142:60006\r\n
    USER-AGENT: Windows/10.0 UPnP/1.1 ohNet/1.0 TuneBrowser/1.0\r\n
    SID: uuid:cff1b202-e395-1370-b3aa-80e94ad851a3
    TIMEOUT: Second-360\r\n
    Content-Length: 0\r\n
    [Content length: 0]
    \r\n
    
    

    According to the specification:

    A renewal must not include CALLBACK or NT.
    If SID is missing, the device treats the request as a new subscription, issues a new SID, and keeps the old one active until its timeout.

    (UPnP DA 1.0: “If the SID header is not included, the publisher SHALL treat the request as a new subscription.”)

    Most DMRs overwrite or auto-clean expired SIDs, so multiple subscriptions are not harmful.
    However, certain strict implementations keep each SID active until timeout, so repeated “new SUBSCRIBE instead of renewal” can temporarily accumulate multiple active subscriptions.

    By implementing SID-based renewal, TuneBrowser will achieve the highest level of compatibility and long-term stability across all types of hardware DMRs.

     

    Thank you again for your continued development and improvements to TuneBrowser.

    storaid
    参加者

    From a UPnP-specification perspective:
    If a controller repeatedly performs “initial SUBSCRIBE” instead of sending a renewal with the existing SID, some DMR devices may internally register multiple subscriptions before their timeout expires.
    On most modern devices this is handled safely, but on certain hardware-limited DMRs it could potentially lead to resource issues over long playback sessions.

    Therefore, implementing the standard SID-based renewal process would provide the highest compatibility and long-term stability across all types of DMRs.

    Thank you again for continuing to improve TuneBrowser — the software keeps getting better with every release.

     

    storaid
    参加者

    Hello Tiki

    I checked the SUBSCRIBE packet in v5.9.2 via Wireshark. It seems it is performing a new subscription instead of a renewal.
    1. It contains CALLBACK and NT headers (which should only be in the first subscription).
    2. It is missing the SID header from the previous subscription.

    TuneBrowser Example:

    Re-SUBSCRIBE

    
    
    SUBSCRIBE /upnp/event/renderer_dvc/AVTransport HTTP/1.1\r\n
    Request Method: SUBSCRIBE
    Request URI: /upnp/event/renderer_dvc/AVTransport
    Request Version: HTTP/1.1
    HOST: 10.1.1.142:60006\r\n
    USER-AGENT: Windows/10.0 UPnP/1.1 ohNet/1.0 TuneBrowser/1.0\r\n
    CALLBACK: <http://10.1.1.166:29500/SR_AVTransport.notify>\r\n
    NT: upnp:event\r\n
    TIMEOUT: Second-360\r\n
    Content-Length: 0\r\n
    [Content length: 0]
    \r\n
    
    

    RE-SUBSCRIBE Example:

    AFAIK, Renewal should only contain the SID and TIMEOUT, and must exclude CALLBACK/NT.

    Otherwise, it will be a new subscription..

     

    Thank you very much for your great work on TuneBrowser!

    storaid
    参加者

    Hello, Tiki

    Maybe I found a potential UI bug in v5.9.2: The value for ‘SUBSCRIBE Advance (sec)’ cannot be changed or saved; it reverts to 3 every time. Please check if this field is incorrectly set to read-only.

    Thanks

    storaid
    参加者

    pic

    storaid
    参加者

    Other Examples:

    [Property Name]

    a. Re-SUBSCRIBE Margin (sec)

    b. Subscription Renewal Margin (sec)

    c. Subscription Renewal (sec)

    [Description]

    a. Specify how many seconds before the SUBSCRIBE timeout TuneBrowser should perform the re-SUBSCRIBE.

    b. Specifies the number of seconds before the SUBSCRIBE timeout at which TuneBrowser will send a re-SUBSCRIBE request.

    storaid
    参加者

    Hello Tiki,

    Thank you very much for the improvement.
    I’m currently testing the new behavior, so please give me a little time to analyze it in detail.

    I also have a small suggestion regarding the wording of the new setting:

    SUBSCRIBE Advance (sec)
    “Specify the margin (advance) in seconds relative to the specified SUBSCRIBE timeout.
    Re-SUBSCRIBE operation will be performed advanced by the number of seconds specified here.”

    The naming and description feel a bit unnatural in English.
    Perhaps using a different term would make the meaning clearer. For example:

    Resubscribe Margin (sec)
    “Specify how many seconds before the timeout TuneBrowser should renew the event subscription.”

    The word “Advance” can be slightly confusing in this context, while terms like “Margin” or “Lead Time” more clearly express a buffer before the subscription expires.

    In addition, I noticed something interesting during testing.

    When “Redo SUBSCRIBE before playback” is disabled,

    TuneBrowser sends the initial SUBSCRIBE after startup and then continually listens for events.
    However, sometimes in some cases I encountered the following errors:

    
    
    2026/01/17 10:45:58,148: UL33471: T02fd0: Warning: UPnP_P: [SOAP Request]: XMLReader detected error: 0xc00cee2b (WC_E_XMLCHARACTER)
    2026/01/17 10:45:58,148: UL33473: T02fd0: Warning: UPnP_P: [SOAP Request]: - OS Error: [illegal xml character]
    2026/01/17 10:45:58,148: UL33475: T02fd0: Warning: UPnP_P: [SOAP Request]: - Source : [10.1.1.142 [http://10.1.1.142:60006/upnp/control/renderer_dvc/AVTransport]]
    2026/01/17 10:45:58,148: UL33477: T02fd0: Warning: UPnP_P: [SOAP Request]: - At line 5, column 351
    2026/01/17 10:45:58,148: UL33479: T02fd0: Warning: UPnP_P: [SOAP Request]: - Line:5 : [<TrackMetaData><DIDL-Lite xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/DIDL-(...)]
    
    

    Could you please take a look when you have time?
    It seems the renderer might be sending an invalid XML character inside TrackMetaData.

    Thank you again for your continued work on TuneBrowser!

    storaid
    参加者

    Hi,

    Here is the log file!

    Thanks

    storaid
    参加者

    Hello Tiki,

    I used Wireshark to analyze TuneBrowser’s UPnP event behavior with different DMR devices.
    During testing, I noticed that devices based on upmpdcli (Volumio, moOde, RED OS, etc.) tend to behave more leniently with UPnP event subscriptions — even if the controller does not renew the subscription, these devices often continue sending LastChange events without interruption.

    However, when testing with Denon/Marantz devices, I observed a different behavior that seems strictly aligned with the UPnP Eventing specification:

    1. Timeout handling
    TuneBrowser sends TIMEOUT: Second-360, but Denon/Marantz responds with TIMEOUT: Second-300, which is valid per UPnP specifications.

    2. No SUBSCRIBE renewal observed
    In Wireshark, I did not see TuneBrowser sending a SUBSCRIBE renewal with the assigned SID before the 300-second timeout returned by the DMR.

    3. Subscription expiration
    Exactly at 300 seconds, Denon/Marantz stops sending AVTransport LastChange events.
    When a track is longer than 300 seconds, TuneBrowser does not receive the final TransportState=STOPPED, which prevents automatic track advance.

    Does TuneBrowser currently implement automatic renewal of AVTransport subscriptions based on the TIMEOUT value returned by the DMR (rather than the value sent by TuneBrowser)?

    If renewal is already implemented, perhaps Denon’s strict timeout behavior requires a slightly different handling.

    Denon/Marantz devices seems like to follow the specification very strictly. Orz

    Thank you very much for your excellent work on TuneBrowser!

    UPnP Log:

    
    
    2025/12/31 21:07:41,512: UL43712: T01df8: UPnP_M: USNID_03 is new. Poll description to device: uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7d::urn:schemas-upnp-org:device:WANConnectionDevice:2
    2025/12/31 21:07:41,512: UL43713: T01df8: UPnP_M: *** Processing USNID_02 by NOTIFY from: 10.1.1.15 : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,512: UL43714: T01df8: UPnP_M: This is TargetURN: NT: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,512: UL43715: T01df8: UPnP_M: ProcDeviceUSN: USNID_02 STAY ( 1): [IPv4]: FN:[] USN:[uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,512: UL43716: T01df8: UPnP_M: USNID_02 is new. Poll description to device: uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2
    2025/12/31 21:07:41,514: UL43718: T03694: UPnP_M: Poll device to: 10.1.1.15 [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,528: UL43719: T02774: UPnP_M: Description contains 2 devices.
    2025/12/31 21:07:41,528: UL43720: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,528: UL43721: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    2025/12/31 21:07:41,528: UL43722: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,528: UL43723: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,528: UL43724: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANIPConnection:2
    2025/12/31 21:07:41,528: UL43725: T02774: UPnP_M: Not interested service 2: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
    2025/12/31 21:07:41,528: UL43726: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,529: UL43727: T02774: UPnP_M: - NOT Target device: 10.1.1.15 [10.1.1.15]
    2025/12/31 21:07:41,529: UL43728: T02774: UPnP_M: - DeviceType : [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,529: UL43729: T02774: UPnP_M: - Location : [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,529: UL43730: T02774: UPnP_M: - USN : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7b::urn:schemas-upnp-org:device:InternetGatewayDevice:2]
    2025/12/31 21:07:41,529: UL43731: T02774: UPnP_M: - USNID : [USNID_04]
    2025/12/31 21:07:41,530: UL43733: T02774: UPnP_M: Poll device to: 10.1.1.15 [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,533: UL43734: T02774: UPnP_M: Description contains 2 devices.
    2025/12/31 21:07:41,533: UL43735: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,534: UL43736: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    2025/12/31 21:07:41,534: UL43737: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,534: UL43738: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,534: UL43739: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANIPConnection:2
    2025/12/31 21:07:41,534: UL43740: T02774: UPnP_M: Not interested service 2: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
    2025/12/31 21:07:41,534: UL43741: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,534: UL43742: T02774: UPnP_M: - NOT Target device: 10.1.1.15 [10.1.1.15]
    2025/12/31 21:07:41,534: UL43743: T02774: UPnP_M: - DeviceType : [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,534: UL43744: T02774: UPnP_M: - Location : [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,534: UL43745: T02774: UPnP_M: - USN : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,534: UL43746: T02774: UPnP_M: - USNID : [USNID_02]
    2025/12/31 21:07:41,754: UL43747: T01df8: UPnP_M: *** Processing USNID_02 by NOTIFY from: 10.1.1.15 : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,762: UL43748: T01df8: UPnP_M: This is TargetURN: NT: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,762: UL43749: T01df8: UPnP_M: ProcDeviceUSN: USNID_02 STAY ( 1): [IPv4]: FN:[] USN:[uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,762: UL43750: T01df8: UPnP_M: USNID_02 is new. Poll description to device: uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2
    2025/12/31 21:07:41,762: UL43752: T02774: UPnP_M: Poll device to: 10.1.1.15 [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,764: UL43753: T01df8: UPnP_M: *** Processing USNID_03 by NOTIFY from: 10.1.1.15 : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7d::urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,764: UL43754: T01df8: UPnP_M: This is TargetURN: NT: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,764: UL43755: T01df8: UPnP_M: ProcDeviceUSN: USNID_03 STAY ( 1): [IPv4]: FN:[] USN:[uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7d::urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,764: UL43756: T01df8: UPnP_M: USNID_03 is new. Poll description to device: uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7d::urn:schemas-upnp-org:device:WANConnectionDevice:2
    2025/12/31 21:07:41,764: UL43757: T01df8: UPnP_M: *** Processing USNID_04 by NOTIFY from: 10.1.1.15 : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7b::urn:schemas-upnp-org:device:InternetGatewayDevice:2]
    2025/12/31 21:07:41,764: UL43758: T01df8: UPnP_M: This is TargetURN: NT: [urn:schemas-upnp-org:device:InternetGatewayDevice:2]
    2025/12/31 21:07:41,764: UL43759: T01df8: UPnP_M: ProcDeviceUSN: USNID_04 STAY ( 1): [IPv4]: FN:[] USN:[uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7b::urn:schemas-upnp-org:device:InternetGatewayDevice:2]
    2025/12/31 21:07:41,764: UL43760: T01df8: UPnP_M: USNID_04 is new. Poll description to device: uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7b::urn:schemas-upnp-org:device:InternetGatewayDevice:2
    2025/12/31 21:07:41,771: UL43761: T02774: UPnP_M: Description contains 2 devices.
    2025/12/31 21:07:41,771: UL43762: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,772: UL43763: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    2025/12/31 21:07:41,772: UL43764: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,772: UL43765: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,772: UL43766: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANIPConnection:2
    2025/12/31 21:07:41,772: UL43767: T02774: UPnP_M: Not interested service 2: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
    2025/12/31 21:07:41,772: UL43768: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,772: UL43769: T02774: UPnP_M: - NOT Target device: 10.1.1.15 [10.1.1.15]
    2025/12/31 21:07:41,772: UL43770: T02774: UPnP_M: - DeviceType : [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,772: UL43771: T02774: UPnP_M: - Location : [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,772: UL43772: T02774: UPnP_M: - USN : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7c::urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,772: UL43773: T02774: UPnP_M: - USNID : [USNID_02]
    2025/12/31 21:07:41,772: UL43775: T02774: UPnP_M: Poll device to: 10.1.1.15 [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,774: UL43776: T02774: UPnP_M: Description contains 2 devices.
    2025/12/31 21:07:41,774: UL43777: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,774: UL43778: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    2025/12/31 21:07:41,774: UL43779: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,774: UL43780: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,774: UL43781: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANIPConnection:2
    2025/12/31 21:07:41,774: UL43782: T02774: UPnP_M: Not interested service 2: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
    2025/12/31 21:07:41,774: UL43783: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,774: UL43784: T02774: UPnP_M: - NOT Target device: 10.1.1.15 [10.1.1.15]
    2025/12/31 21:07:41,774: UL43785: T02774: UPnP_M: - DeviceType : [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,774: UL43786: T02774: UPnP_M: - Location : [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,774: UL43787: T02774: UPnP_M: - USN : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7d::urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,775: UL43788: T02774: UPnP_M: - USNID : [USNID_03]
    2025/12/31 21:07:41,776: UL43790: T02774: UPnP_M: Poll device to: 10.1.1.15 [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,778: UL43791: T02774: UPnP_M: Description contains 2 devices.
    2025/12/31 21:07:41,778: UL43792: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,778: UL43793: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    2025/12/31 21:07:41,778: UL43794: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,778: UL43795: T02774: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,779: UL43796: T02774: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANIPConnection:2
    2025/12/31 21:07:41,779: UL43797: T02774: UPnP_M: Not interested service 2: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
    2025/12/31 21:07:41,779: UL43798: T02774: UPnP_M: No interested services found.
    2025/12/31 21:07:41,779: UL43799: T02774: UPnP_M: - NOT Target device: 10.1.1.15 [10.1.1.15]
    2025/12/31 21:07:41,779: UL43800: T02774: UPnP_M: - DeviceType : [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,779: UL43801: T02774: UPnP_M: - Location : [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,779: UL43802: T02774: UPnP_M: - USN : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7b::urn:schemas-upnp-org:device:InternetGatewayDevice:2]
    2025/12/31 21:07:41,779: UL43803: T02774: UPnP_M: - USNID : [USNID_04]
    2025/12/31 21:07:41,826: UL43804: T03694: UPnP_M: Description contains 2 devices.
    2025/12/31 21:07:41,826: UL43805: T03694: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANDevice:2]
    2025/12/31 21:07:41,827: UL43806: T03694: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    2025/12/31 21:07:41,827: UL43807: T03694: UPnP_M: No interested services found.
    2025/12/31 21:07:41,827: UL43808: T03694: UPnP_M: - deviceType(URN) is TargetURN: [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,827: UL43809: T03694: UPnP_M: Not interested service 1: urn:schemas-upnp-org:service:WANIPConnection:2
    2025/12/31 21:07:41,827: UL43810: T03694: UPnP_M: Not interested service 2: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
    2025/12/31 21:07:41,827: UL43811: T03694: UPnP_M: No interested services found.
    2025/12/31 21:07:41,827: UL43812: T03694: UPnP_M: - NOT Target device: 10.1.1.15 [10.1.1.15]
    2025/12/31 21:07:41,827: UL43813: T03694: UPnP_M: - DeviceType : [urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,827: UL43814: T03694: UPnP_M: - Location : [http://10.1.1.15:46721/rootDesc.xml]
    2025/12/31 21:07:41,827: UL43815: T03694: UPnP_M: - USN : [uuid:aedc4ed9-0c85-48c5-8cf8-a7ff09ab5b7d::urn:schemas-upnp-org:device:WANConnectionDevice:2]
    2025/12/31 21:07:41,827: UL43816: T03694: UPnP_M: - USNID : [USNID_03]
    2025/12/31 21:07:42,327: UL43818: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:43,326: UL43820: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:44,326: UL43822: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:45,325: UL43824: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:46,324: UL43826: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:47,322: UL43828: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:48,322: UL43830: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:49,321: UL43833: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:50,319: UL43837: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:51,318: UL43850: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:52,317: UL43852: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    2025/12/31 21:07:53,316: UL43860: T06a3c: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:05:18 -> 318.0 / 318.0 sec
    
    
    storaid
    参加者

    Tested Devices and Results:

    ifi-audio Zen Stream (old: v3): Works as expected
    Volumio (new): Works as expected
    moOde: Works as expected
    Holo RED: Works as expected
    WiiM Plus (Linkplay): Works as expected
    DENON Device: For some tracks, does not move on to the next track (likely due to internal EOF detection caused by TrackDuration’s small precision errors), but does send TransportState=STOPPED in the LastChange event when playback is completed.
    Marantz Device: Same behavior as DENON

    Thank you for your attention and your great support.

    If you need any further details or logs, I’d be happy to provide them.

    storaid
    参加者

    Hi, Tiki

    Thank you for your reply.

    I did notice that even when playback is finished (for example, 251 sec / 251 sec, playback actually stopped), the seek bar remains at the end and the next track does not automatically start.

    It seems to be related to the DMR’s internal EOF detection.

    For reference:

    
    
    251 sec / 251 sec
    251 sec / 251 sec
    251 sec / 251 sec
    251 sec / 251 sec
    251 sec / 251 sec
    
    

    I have confirmed in my log that the DMR does send TransportState=STOPPED in LastChange.

    Does TuneBrowser’s current event handling trigger next-track/track advance logic on TransportState=STOPPED (from LastChange), or does it only rely on position polling something internal logic?

    It looks like in this case, manual intervention is required to go to the next track, so I guess the event may not be used for this scenario.

    Thank you very much for your help!

    storaid
    参加者

    Hi, Tiki

    I’ve been testing this for about a week and I think I may have found something worth checking.

    For some Japanese DMRs (especially Denon/Marantz), the reported TrackDuration often has small precision errors, which seems to affect their internal EOF detection. As a result, even when playback has actually finished, the device sometimes does not move on to the next track.

    This made me wonder:
    Does TuneBrowser currently monitor the AVTransport LastChange event?

    During testing, I noticed that although the device sometimes fails to advance the track on its own, it does correctly send:

    
    
    6:15 PM Denon Home 350/urn:upnp-org:serviceId:AVTransport LastChange
    
    <Event xmlns="urn:schemas-upnp-org:metadata-1-0/AVT/"><InstanceID val="0"><TransportState val="STOPPED"/></InstanceID></Event>
    
    

    in the LastChange event.

    So I’m thinking that subscribing to LastChange and using TransportState=STOPPED as a trigger might help handle these cases.

    I’m not sure if TuneBrowser already uses this mechanism, so I wanted to ask in case this observation is useful.

    Thank you as always for your great work.

    storaid
    参加者

    Hi,

    Thank you for implementing TrackDuration support in TuneBrowser 1817.

    I have tested it with both ifi-audio ZenStream (very OLD volumio) and Denon Home Speaker (HEOS).

    Previously, due to inconsistent or nested DIDL structures and missing duration metadata, the seekbar was unreliable and often failed.

    After updating, the seekbar now works consistently and correctly in my environment.

    I appreciate your effort and responsiveness!

    Thanks

    storaid
    参加者

    Hi Tiki,

    Thank you for your explanation.

    Elapsed time like RelTime is a dynamic information and it is checked and updated each time during playback.

    Yes, RelTime is dynamic, but TrackDuration is not, right?

    Actually, one reason I am concerned about relying on the DIDL-Lite metadata for seekbar duration is that, in practice, the content of DIDL from various vendors is not standardized.

    Each device or server can provide very different structures, attributes, or even omit certain metadata fields. For example, the <res duration> attribute is optional and often implemented inconsistently.

    Because DIDL is so flexible and open to vendor-specific extensions, using it for playback control (such as the seekbar’s total duration) can sometimes lead to compatibility problems—especially when there are multiple <res> tags or unexpected attribute values.

    That’s why I think using TrackDuration from the AVTransport, which is designed to provide the accurate total time of the currently playing track, is more robust and reliable for seekbar control.

    Is it possible to use TrackDuration as the total duration of the seekbar?

    Thanks..

    storaid
    参加者

    Hi Tiki,

    Thank you for the detailed analysis.

    It’s a nested structure..

    Would it be possible to adjust TuneBrowser’s behavior to skip <res> entries with protocolInfo=”http-get:*:*:*” and instead try to detect and use a more valid <res> that includes meaningful metadata?

    Thanks again!

    storaid
    参加者

    Hello,

    Here is the metadata by calling GetPositionInfo

    
    
    <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">
    
    <item id="1" parentID="1" restricted="1">
    <dc:title>The Cell</dc:title>
    
    <res protocolInfo="http-get:*:*:*" size="0" bitrate="4610005" sampleFrequency="96000" bitsPerSample="24" duration="00:04:14">
    [audio src="http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac" /]
    </res>
    
    <desc id="audioFormat" nameSpace="urn:schemas-denon-com:metadata/" xmlns:aios="urn:schemas-denon-com:metadata/">
    FLAC
    </desc>
    
    <res protocolInfo="http-get:*:*:*" size="0" duration="00:00:00">
    <DIDL-Lite xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"
    xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
    
    <item>
    <res protocolInfo="http-get:*:audio/flac:*"
    duration="0:04:14.333"
    bitrate="4615928"
    bitsPerSample="24"
    nrAudioChannels="2"
    sampleFrequency="96000"
    ProxyStreamT="Normal">
    [audio src="http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac" /]
    </res>
    
    <dc:title>The Cell</dc:title>
    <dc:creator>KOKIA</dc:creator>
    <dc:publisher>anco&amp;co.</dc:publisher>
    <upnp:album>KOKIA 25th Anniversary Best -The Lighthouse- Vol.1</upnp:album>
    <upnp:genre>J-POP</upnp:genre>
    <upnp:artist>KOKIA</upnp:artist>
    <upnp:artist role="AlbumArtist">KOKIA</upnp:artist>
    <upnp:artist role="Composer">KOKIA</upnp:artist>
    <upnp:originalTrackNumber>01</upnp:originalTrackNumber>
    <upnp:albumArtURI>http://10.1.1.166:29400/Image/14184.38dc30e8-eeba-47d8-8ebf4d56ca061494.jpg</upnp:albumArtURI>
    <upnp:class>object.item.audioItem.musicTrack</upnp:class>
    </item>
    
    </DIDL-Lite>
    </res>
    
    <upnp:class>object.item.audioItem.musicTrack</upnp:class>
    <dc:creator>KOKIA</dc:creator>
    <upnp:genre>J-POP</upnp:genre>
    <upnp:artist>KOKIA</upnp:artist>
    <upnp:album>KOKIA 25th Anniversary Best -The Lighthouse- Vol.1</upnp:album>
    <upnp:albumArtURI>http://10.1.1.166:29400/Image/14184.38dc30e8-eeba-47d8-8ebf4d56ca061494.jpg</upnp:albumArtURI>
    </item>
    
    </DIDL-Lite>
    
    
    storaid
    参加者

    Hi, Tiki

    Here is the log

    
    
    2025/04/28 22:00:03,114: UL02630: T0bdd0: HTTPServer: [10.1.1.144 :50064]: Begin monitoring playback.
    2025/04/28 22:00:03,534: UL02735: T0228c: UPnP_P: Notified on GUI: ProxyStream [Normal] SampleRate: 0 BitDepth: 0
    2025/04/28 22:00:03,757: UL02737: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: Getting PositionInfo from device.
    2025/04/28 22:00:03,757: UL02739: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] to: 10.1.1.144 [http://10.1.1.144:60006/upnp/control/renderer_dvc/AVTransport]
    2025/04/28 22:00:03,770: UL02741: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] finished.
    2025/04/28 22:00:03,771: UL02743: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> RelTime: 00:00:00
    2025/04/28 22:00:03,771: UL02745: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:00 -> 0.0 / 0.0 sec
    2025/04/28 22:00:03,771: UL02747: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackURI: http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac
    2025/04/28 22:00:03,771: UL02749: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackMetaData: <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http:/ (...)
    2025/04/28 22:00:03,771: UL02751: T06590: UPnP_P: [Proc:UriAndMeta] <POL>: DIDL/res: [http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac]
    2025/04/28 22:00:03,771: UL02753: T06590: UPnP_P: [Proc:UriAndMeta] <POL>: - protocolInfo:[http-get:*:*:*] bitsPerSample:[24] bitrate:[4610005] size:[0] sampleFrequency:[96000]
    2025/04/28 22:00:03,771: UL02755: T06590: UPnP_P: [Proc:UriAndMeta] <POL>: - duration:[00:04:14]
    2025/04/28 22:00:03,771: UL02757: T06590: UPnP_P: [Proc:UriAndMeta] <POL>: DIDL/res: [<DIDL-Lite xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
    <item>
    <res protocolInfo="http-get:*:audio/flac:*" duration="0:04:14.333" bitrate="4615928" bitsPerSample="24" nrAudioChannels="2" sampleFrequency="96000" ProxyStreamT="Normal">http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac</res>
    <dc:title>The Cell</dc:title>
    <dc:creator>KOKIA</dc:creator>
    <dc:publisher>anco&amp;co.</dc:publisher>
    <upnp:album>KOKIA 25th Anniversary Best -The Lighthouse- Vol.1</upnp:album>
    <upnp:genre>J-POP</upnp:genre>
    <upnp:artist>KOKIA</upnp:artist>
    <upnp:artist role="AlbumArtist">KOKIA</upnp:artist>
    <upnp:artist role="Composer">KOKIA</upnp:artist>
    <upnp:originalTrackNumber>01</upnp:originalTrackNumber>
    <upnp:albumArtURI>http://10.1.1.166:29400/Image/14184.38dc30e8-eeba-47d8-8ebf4d56ca061494.jpg</upnp:albumArtURI>
    <upnp:class>object.item.audioItem.musicTrack</upnp:class>
    </item>
    </DIDL-Lite>]
    2025/04/28 22:00:03,771: UL02759: T06590: UPnP_P: [Proc:UriAndMeta] <POL>: - protocolInfo:[http-get:*:*:*] size:[0] duration:[00:00:00]
    2025/04/28 22:00:04,756: UL02761: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: Getting PositionInfo from device.
    2025/04/28 22:00:04,756: UL02763: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] to: 10.1.1.144 [http://10.1.1.144:60006/upnp/control/renderer_dvc/AVTransport]
    2025/04/28 22:00:04,764: UL02765: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] finished.
    2025/04/28 22:00:04,765: UL02767: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> RelTime: 00:00:01
    2025/04/28 22:00:04,765: UL02769: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:01 -> 1.0 / 0.0 sec (Void)
    2025/04/28 22:00:04,765: UL02771: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackURI: http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac
    2025/04/28 22:00:04,765: UL02773: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackMetaData: <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http:/ (...)
    2025/04/28 22:00:05,754: UL02866: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: Getting PositionInfo from device.
    2025/04/28 22:00:05,755: UL02869: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] to: 10.1.1.144 [http://10.1.1.144:60006/upnp/control/renderer_dvc/AVTransport]
    2025/04/28 22:00:05,765: UL02871: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] finished.
    2025/04/28 22:00:05,765: UL02873: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> RelTime: 00:00:02
    2025/04/28 22:00:05,765: UL02875: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:02 -> 2.0 / 0.0 sec (Void)
    2025/04/28 22:00:05,765: UL02877: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackURI: http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac
    2025/04/28 22:00:05,765: UL02879: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackMetaData: <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http:/ (...)
    2025/04/28 22:00:06,753: UL02975: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: Getting PositionInfo from device.
    2025/04/28 22:00:06,753: UL02977: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] to: 10.1.1.144 [http://10.1.1.144:60006/upnp/control/renderer_dvc/AVTransport]
    2025/04/28 22:00:06,763: UL02982: T06590: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] finished.
    2025/04/28 22:00:06,763: UL02984: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> RelTime: 00:00:03
    2025/04/28 22:00:06,763: UL02986: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:03 -> 3.0 / 0.0 sec (Void)
    2025/04/28 22:00:06,763: UL02988: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackURI: http://10.1.1.166:29400/TuneID/00013386-RFH-9AA42264.flac
    2025/04/28 22:00:06,763: UL02990: T06590: UPnP_P: [UPP_WorkerThread]: QuerySOAP: -> TrackMetaData: <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http:/ (...)
    2025/04/28 22:00:07,752: UL03157: T06590: UPnP_P: [UPP_WorkerThread]: Polling SOAP log turns to off.
    2025/04/28 22:00:07,762: UL03162: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:04 -> 4.0 / 0.0 sec (Void)
    2025/04/28 22:00:08,762: UL03431: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:05 -> 5.0 / 0.0 sec (Void) (per 5 seconds)
    2025/04/28 22:00:13,254: UL03433: T079b8: HTTPServer: [10.1.1.144 :50054]: Sent 12582912 bytes.
    2025/04/28 22:00:13,760: UL03435: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:10 -> 10.0 / 0.0 sec (Void) (per 5 seconds)
    2025/04/28 22:00:18,753: UL03437: T06590: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 00:00:15 -> 15.0 / 0.0 sec (Void) (per 5 seconds)
    
    
    storaid
    参加者

    Hello Tiki,

    To investigate carefully, I decided to upgrade TuneBrowser step-by-step, starting from version 5.5.0 and gradually moving up to version 5.7.1.

    Through this process, I noticed that in the newer versions, the title bar cannot be hidden in two specific Views:

    – Tree View
    – Player View

    In older versions, it was possible to hide the title bar correctly.

    Thank you very much for your continuous development of TuneBrowser.

    storaid
    参加者

    Hello Tiki,

    As a follow-up to my previous message, I decided to conduct a version-by-version test regarding the Denon Home playback issue.

    Here are my findings:

    – In version 5.5.0, the timebar function works correctly with Denon Home

    – Starting from version 5.6.x, the timebar no longer moves during playback

    – In version 5.7.x as well, the timebar still does not operate properly

    This result surprised me.

    It seems that there might have been a major change in the UPnP functionality starting from version 5.6.x, which could be related to this issue.

    I hope this information helps.

    Thank you again for your continuous efforts.

    storaid
    参加者

    Hello,

    My test:

    v5.6.4(x64 AVX2): no issue

    v5.7.0(x64 AVX2): no issue

    Thanks

    storaid
    参加者

    Hi

    Just now

    I just tried installing older v5.6.4, and the issue didn’t happen.
    That’s a bit strange.

    storaid
    参加者

    Hi,

    Does the issue occur in any view? Or only certain views?

    All views

    OS: Windows 11 24H2

    This issue didn’t happen before I reinstalled the OS,

    but it started showing up after I installed the new Windows 11 24H2.

    Thanks

    返信先: new view component “GroupView”? #16303
    storaid
    参加者

    Hello,

    I didn’t quite understand the difference between Album View and Group View.

    but what you mentioned “Group View shows the group (album) selected in Album View” gave me a very helpful hint.

    I’ll try adjusting the layout and see how it works with Group View.

    Thank you!

    storaid
    参加者

    Hello,

    Thank you for your explanation regarding the actual format being Wave or Raw PCM in ProxyStream.

    I think –

    some Linux-based audio renderer systems use MediaInfo or libmediainfo to parse track metadata in their Web UI.

    When the file has a non-standard extension like .flac_WPRX, MediaInfo detects it as a valid FLAC internally, but still flags the extension as invalid (FileExtension_Invalid).

    Because of this, the Web interface, which depends on MediaInfo, may fail to parse the file or even hang.

    Thanks again for your attention and thoughtful response!

    storaid
    参加者

    Hi, Tiki

    I found another issue.

    When I set “ProxyStream Indicator Reporting Source” to “HttpRequest,” I noticed a consistent behavior that applies to all UPnP Renderers:

    1. Open TuneBrowser.

    2. Play any track (DST) for the first time—GUI correctly displays information obtained from the indicators.

    3. Play another track (DST) for the second time—GUI still correctly displays information obtained from the indicators.

    4. Starting from the third playback onward, no matter which track (DST) is played, the indicators fail to retrieve information, and the GUI is not notified to update the information.

    If you have some free time, I would greatly appreciate it if you could help confirm and investigate this issue.

    Thank you for your support!

    storaid
    参加者

    Hello, Tiki,

    I’ve resolved the issue myself.

    I adjusted the Sample Rate Limit based on the transcoding value length from the UPnP logs.

    Please feel free to close this topic.

    Thank you!

    storaid
    参加者

    “You know, UPnP playback schema consists of three parts: Controler, Media Server, and Renderer. These are independent of each other. I think it is not a good idea to design the Controler part with the basic concept that only TuneBrowser exists in your network.”

    Understood. 🙂

    Kindly, I wanted to ask a quick question:
    Do you rely on something NOTIFY, like NOTIFY#AVTransportURIMetaData, notification sent by the device to determine whether it is considered “ready”?

    Similar responses, but different results:

    [WiiM]

    
    
    2024/12/02 18:55:54,227: UL43993: T0204c: UPnP_P: PlayImpl: QuerySOAP: Getting PositionInfo from device.
    2024/12/02 18:55:54,227: UL43995: T0204c: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] to: 10.1.1.136 [http://10.1.1.136:49152/upnp/control/rendertransport1]
    2024/12/02 18:55:54,259: UL43997: T0204c: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] finished.
    2024/12/02 18:55:54,259: UL43999: T0204c: UPnP_P: PlayImpl: QuerySOAP: -> TrackURI: http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavPro (...)
    2024/12/02 18:55:54,259: UL44001: T0204c: UPnP_P: PlayImpl: QuerySOAP: -> TrackMetaData: <DIDL-Lite xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:dc="http:/ (...)
    2024/12/02 18:55:54,259: UL44003: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: DIDL/res: [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&BitDepth=24&SampleRate=88200]
    2024/12/02 18:55:54,259: UL44005: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: - protocolInfo:[http-get:*:audio/wav:*] duration:[0:04:38.147] bitsPerSample:[24]
    2024/12/02 18:55:54,259: UL44007: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: - sampleFrequency:[88200] nrAudioChannels:[2] ProxyStreamT:[WavProxy]
    2024/12/02 18:55:54,259: UL44009: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: New URI found: 10.1.1.157 [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&BitDepth=24&SampleRate=88200]
    2024/12/02 18:55:54,259: UL44011: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: Track: [Dell'invito trascorsa è già l'ora from "La traviata"]
    2024/12/02 18:55:54,260: UL44013: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: ProxyStream mark found in URI: [ProxyStreamT:WavProxy] (WPRX)
    2024/12/02 18:55:54,260: UL44015: T0204c: UPnP_P: [Proc:UriAndMeta] <POL>: Notifying to GUI by Metadata: ProxyStream [WavProxy] SampleRate: 88200 BitDepth: 24
    2024/12/02 18:55:54,260: UL44017: T03810: UPnP_P: [UPP_MetaUPThread]: MyURI: Yes [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&BitDepth=24&SampleRate=88200]
    2024/12/02 18:55:54,260: UL44019: T03810: UPnP_P: [ResolveTune]: URI: 10.1.1.157 [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&BitDepth=24&SampleRate=88200]
    2024/12/02 18:55:54,260: UL44021: T03810: UPnP_P: [ResolveTune]: This is mine.
    2024/12/02 18:55:54,260: UL44023: T03810: UPnP_P: [ResolveTune]: Mine:Yes Managed:Yes Recorded:Yes Local file: [\\10.1.1.127\music\[Hi-Res]SS REFERENCE - SACD柳沢功力氏選曲\01 - Carlos Kleiber, Bayerisches Staatsorchester - Dell'invito trascorsa è già l'ora from La traviata.dff]
    2024/12/02 18:55:54,260: UL44025: T07c94: UPnP_P: Notified on GUI: ProxyStream [WavProxy] SampleRate: 88200 BitDepth: 24
    2024/12/02 18:55:54,261: UL44027: T07c94: UPnP_P: Post PlayerNotify: 444692 [SpecUpdate]
    2024/12/02 18:55:54,261: UL44029: T07c94: UPnP_P: Proc PlayerNotify: 444692 [SpecUpdate]
    2024/12/02 18:55:54,269: UL44031: T07c94: UPnP_P: [PlayerView]: Set Freq indicator: [ 88.2kHz*] By ProxyStream
    2024/12/02 18:55:54,269: UL44033: T07c94: UPnP_P: [PlayerView]: Set BitD indicator: [24bit*] By ProxyStream
    
    

     

    [Holo-Audio RED]

    
    
    2024/12/02 19:00:58,469: UL02037: T07060: UPnP_P: PlayImpl: QuerySOAP: Getting PositionInfo from device.
    2024/12/02 19:00:58,469: UL02039: T07060: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] to: 10.1.1.97 [http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/ctl-urn-schemas-upnp-org-service-AVTransport-1]
    2024/12/02 19:00:58,477: UL02041: T09a88: UPnP_P: Proc PlayerNotify: 000001 [Start]
    2024/12/02 19:00:58,479: UL02043: T07060: UPnP_P: [SOAP Request]: SOAP request: [GetPositionInfo ] finished.
    2024/12/02 19:00:58,479: UL02045: T07060: UPnP_P: PlayImpl: QuerySOAP: -> RelTime: 0:00:00
    2024/12/02 19:00:58,479: UL02047: T07060: UPnP_P: [Proc:RelTime ] <POL>: Elapsed: 0:00:00 -> 0.0 / 278.1 sec
    2024/12/02 19:00:58,479: UL02049: T07060: UPnP_P: PlayImpl: QuerySOAP: -> TrackURI: http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavPro (...)
    2024/12/02 19:00:58,479: UL02051: T07060: UPnP_P: PlayImpl: QuerySOAP: -> TrackMetaData: <DIDL-Lite xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:dc="http:/ (...)
    2024/12/02 19:00:58,479: UL02053: T07060: UPnP_P: [Proc:UriAndMeta] <POL>: DIDL/res: [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&BitDepth=24&SampleRate=88200]
    2024/12/02 19:00:58,479: UL02055: T07060: UPnP_P: [Proc:UriAndMeta] <POL>: - protocolInfo:[http-get:*:audio/wav:*] duration:[0:04:38.147] bitsPerSample:[24]
    2024/12/02 19:00:58,479: UL02057: T07060: UPnP_P: [Proc:UriAndMeta] <POL>: - sampleFrequency:[88200] nrAudioChannels:[2] ProxyStreamT:[WavProxy]
    2024/12/02 19:00:58,479: UL02059: T07060: UPnP_P: [Proc:UriAndMeta] <POL>: New URI found: 10.1.1.157 [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&amp;BitDepth=24&amp;SampleRate=88200]
    2024/12/02 19:00:58,479: UL02061: T07060: UPnP_P: [Proc:UriAndMeta] <POL>: Track: [Dell'invito trascorsa è già l'ora from "La traviata"]
    2024/12/02 19:00:58,479: UL02063: T07060: UPnP_P: [Proc:UriAndMeta] <POL>: ProxyStream mark found in URI: [ProxyStreamT:WavProxy] (WPRX)
    2024/12/02 19:00:58,479: UL02065: T08850: UPnP_P: [UPP_MetaUPThread]: MyURI: Yes [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&amp;BitDepth=24&amp;SampleRate=88200]
    2024/12/02 19:00:58,479: UL02067: T08850: UPnP_P: [ResolveTune]: URI: 10.1.1.157 [http://10.1.1.157:29400/TuneID/00003241-RFH40DFCB58.dff_WPRX?ProxyStreamT=WavProxy&amp;BitDepth=24&amp;SampleRate=88200]
    2024/12/02 19:00:58,480: UL02069: T08850: UPnP_P: [ResolveTune]: This is mine.
    2024/12/02 19:00:58,480: UL02071: T08850: UPnP_P: [ResolveTune]: Mine:Yes Managed:Yes Recorded:Yes Local file: [\\10.1.1.127\music\[Hi-Res]SS REFERENCE - SACD柳沢功力氏選曲\01 - Carlos Kleiber, Bayerisches Staatsorchester - Dell'invito trascorsa è già l'ora from La traviata.dff]
    2024/12/02 19:00:58,482: UL02073: T09a88: UPnP_P: Proc PlayerNotify: 000001 [Started]
    2024/12/02 19:00:58,497: UL02077: T09a88: UPnP_P: Notified on GUI: ProxyStream [WavProxy] SampleRate: 0 BitDepth: 0
    2024/12/02 19:00:58,497: UL02079: T09a88: UPnP_P: Post PlayerNotify: 444414 [SpecUpdate]
    2024/12/02 19:00:58,498: UL02081: T09a88: UPnP_P: Proc PlayerNotify: 444414 [SpecUpdate]
    2024/12/02 19:00:58,506: UL02083: T09a88: UPnP_P: [PlayerView]: Set Freq indicator: [-----kHz] By ProxyStream
    2024/12/02 19:00:58,506: UL02085: T09a88: UPnP_P: [PlayerView]: Set BitD indicator: [--/--bit] By ProxyStream
    
    

    Thank you so much for your time and clarification!

    storaid
    参加者

    Hello Tiki,

    I’m sorry to bother you again with this, but I wanted to share some additional findings and thoughts regarding the GUI behavior.

    After consulting with the device manufacturer, they mentioned that this issue might be related to the complexity of internal buffering control in UPnP, which they consider challenging—especially for tasks like handling Seek commands.

    Additionally, they explained that it’s difficult to ensure the control point knows exactly when the player is “ready.”

    Network environment complexity could also add uncertainty, and they acknowledged that addressing such issues might not be a priority currently.

    Their suggestion was to avoid relying on Player feedback for GUI updates after on-the-fly transcoding occurs.

    Since this behavior is initiated by the Control Point, they recommended having the Control Point proactively update the GUI information instead.

    This might require some consideration on your end or not, and the above feedback is just for reference.

    I’ve tested several UPnP devices. Some devices, such as WiiM, display the information correctly, while others—particularly those based on upmpdcli, such as Holo Audio, iFi-audio, and Audiolab—do not show the information as expected.

    If there’s a possibility to improve it in the future, I’d greatly appreciate it.

    In the meantime, I’ve suggested to my some friends (who also use the TuneBrowser and encountered this GUI display issue) to set “Disable ProxyStream indicator” to “YES” as a solution.

    Lastly, one of my friends has asked if it’s possible anyway to change the ProxyStream samplerate display in the GUI from a single click to a double-click action?

    Occasionally, when switching devices, they accidentally click it.

    If you don’t need to keep this topic open, you can close it.

    Thank you again for all your work on improving UPnP support. 🙂

     

    storaid
    参加者

    Hello, Tiki

    Sorry to bother you,

    I think I understand your explanation maybe.

    I realize my thoughts might be a bit simplified.

    When the ProxyStream (e.g., WavProxy) process is triggered, I guess the internal indicators would be initialized, and the GUI would be notified to update the relevant information.

    The Player should only be aware of the information provided through SetAVTransportURI (e.g., the URI and protocolInfo).

    This decoupling is between the Control Point and the Player.

    Based on complex network environments, like multiple switches in the path or an internal firewall (e.g., deep packet inspection), could introduce delays. These delays might cause wired UPnP devices, including the Renderer, to respond slower than expected.
    In such cases, the Control Point might misinterpret this as the Player not being ready.

    Maybe my understanding does not match with your design.

    Specifically, I noticed the following behavior:
    1. Before playback, the Control Point’s GUI correctly displays information related to the ProxyStream (e.g., SampleRate and BitDepth).
    2. Then, shortly after, there’s a brief flicker, and this information disappears.

    Thank you so much for your continuous improvements to the UPnP implementation.

    storaid
    参加者

    Hello,

    I understand.

    If you have some free time in the future, I’d appreciate it if you could consider improving it.

    Thank you!

    返信先: CUSHEET issue #15789
    storaid
    参加者

    Hello,

    Please close this ticket…

    I re-updated the database for this album.

    And, then the issue is gone.

    Sorry to bother you

    storaid
    参加者

    Hi, Tiki

    “Metadata” is based on metadata received by the controller part of TuneBrowser.

    “HttpRequest” is based on URL params received by the media server part of TuneBrowser.

    Anyway, as previously discussed, this info is experimental and useless to you. Sorry.

    I got it!

    Thanks for the clarification

    storaid
    参加者

    Hello, Tiki

    Thanks for your explanation.

    Here are some questions:

    1. The “ProxyStream Indicator Reporting Source” appears after setting “Disable ProxyStream Indicator” to “Yes” (default). Is this a conflict?

    2. Is “ProxyStream Indicator Reporting Source” an upcoming feature for a future release?

    Thank you

    storaid
    参加者

    Hello, Tiki,
    I confirmed that the UI issue has improved.
    Thank you

    返信先: Ifi ZEN Streamer #15641
    storaid
    参加者

    Hello,

    If you use TuneBrowser as the UPnP (ohNet) Server, you only need to enable the OpenHome and UPnP Renderer features in TuneBrowser.

    For the iFi ZEN Stream, the default settings of TuneBrowser in UPnP Renderer are already optimized.

    Cheers!

    storaid
    参加者

    Hello, Tiki

    I’ve been testing for a few hours now, and it looks like the random message pop-up is not showing up anymore.

    Thanks

    and, a simple question

    Does the term “Connet timeout” mean “Connection timeout”?

    If so, I think “Connection timeout” is the better term.

    返信先: Pause and Play issue for UPnP #15624
    storaid
    参加者

    Hello, Tiki

    This behavior issue is getting improved.

    Thanks

    storaid
    参加者

    Hi,

    confirmed

    seems like the seekbar flickering is gone on my test.

    Thanks

    test env:

    GPU: nVIDIA RTX4070S

    Monitor 1: SONY X90K@120Hz,10b, freesync

    Monitor 2: ASUS ProArt PA328CGV@165Hz,10b, freesync

    storaid
    参加者

    Hello, Tiki

    Thanks for your explanation..

    I thought that when the screen displayed the “WPRX” string, it would also provide the new Sample Rate and Bit-depth information on the UI with the same thread.

    I’ve been continuously analyzing these logs to identify any differences because the WiiM streamer always shows the correct information, but other streamers sometimes leave the information blank.

    This led me to suspect that there might be some differences in the UPnP logs.

    It’s very difficult to observe this through Wireshark.

    Based on what you said, the issue might be related to how different threads are executed.

    Perhaps this additional feature should be disabled as you said.

    Thanks.

    返信先: About DIDL-Lite metadata suggestion #15612
    storaid
    参加者

    Hi, Tiki

    I sincerely apologize for any inconvenience caused.

    I have never complained about anything with this software.

    TuneBrowser is currently one of the best software in terms of UPnP support.

    And I have continuously recommended this software to other users.

    Since TuneBrowser started supporting UPnP, I’ve always been very grateful for the improvements you’ve made to its UPnP functionality.

    This is one of the very few music software on Windows that provides excellent UPnP support.

    I truly hope you won’t give up on supporting UPnP.

    I have always respected the developer’s suggestions.

    If you can, please close this topic.

    and, apologize again for any trouble caused.

    Thanks

    返信先: About DIDL-Lite metadata suggestion #15606
    storaid
    参加者

    Hi, Tiki

    If possible, please don’t stop supporting UPnP.( Please, Orz)

    It’s just a suggestion.

    After all, your development of the CAS Player is one of the few that provides excellent UPnP support.

    Currently, it’s quite difficult to find CAS players on Windows OS with good UPnP support.

    Please Orz

    Thank you

    返信先: About DIDL-Lite metadata suggestion #15604
    storaid
    参加者

    Hi, Tiki

    I asked my friend, and this is his opinion (though he’s not particularly focused on UPnP in audio development).

    Generally, DIDL-Lite metadata is unlikely to pose a security risk for the intranet.

    The security concerns are usually related to the UPnP Renderer (IoT), such as when the URI in the returned DIDL-Lite metadata is tampered with, for example: CVE-2020-12695.

    However, this kind of mechanism serves other purposes:
    1. Consistency: Ensuring that parts of the CreatedMetaData and ReceivedMetaData are consistent.
    2. Compatibility: At the very least, it helps to identify whether the renderer is returning inconsistent DIDL metadata.
    3. Reliability: Checking specific required metadata attributes against the original metadata can improve reliability.
    4. Transparency: It helps to determine whether there’s a compatibility issue with the renderer (since some brands of UPnP Renderers don’t respect UPnP and return incorrect DIDL metadata).

    Cases include:
    1. Early WiiM firmware: Incorrect metadata returned (wrong DIDL metadata format).
    2. ifi-audio streamer: The inconsistent metadata I mentioned previously.
    3. Yamaha device (R-N803D): Wrong URI.

    If the check fails, it could trigger a pop-up message with some information.

    This is just a suggestion for your reference.

    Thank you

    返信先: About DIDL-Lite metadata suggestion #15602
    storaid
    参加者

    Hello, Tiki

    The UPnP Renderer is a very useful feature, and I do not recommend discontinuing its support.

    DIDL-lite metadata compliance check do not involve any particularly complex information.

    They are simply used to ensure that the content of the DIDL metadata passed through SetAVTransportURI or SetAVNextTransportURI matches the DIDL metadata retrieved from the UPnP Renderer (e.g., GetPositionInfoResponse or GetMediaInfoResponse).

    If the DIDL-Lite metadata compliance check fails, an error message pop-up will be displayed on the UI and stop the music playback.

    Thanks

    storaid
    参加者

    Hi, Tiki

    could you help me check the log?

    thanks

    storaid
    参加者

    Additionally, I want to clarify that sometimes the information display works correctly, but other times it doesn’t.

     

    storaid
    参加者

    Hi,

    “It is difficult to understand this behavior from the log because sevral threads are involved. Please understand.”

    I see.

    If it’s difficult to confirm from the log, then this might be a bit tricky.

    At the moment, aside from the WiiM streamer, which cannot reproduce this issue, the other UPnP streamers I have might encounter this.

    Although, it’s just that the information doesn’t display properly.

    storaid
    参加者

    Hi, Tiki

    “This item means that “Queues the selected track for the next playback”.”

    It’s a little bit confusing for me because this ‘Play Next’ makes me think it’s used to play the next track.

    Anyway, thanks for your explanation…

    storaid
    参加者

    My Test devices:

    ifi-audio Zen Stream,
    Denon Home Speaker,
    HoloAudio Red Streamer,
    WiiM Pro Plus

    PS: it’s very hard to reproduce this issue in the WiiM Pro Plus streamer.

    storaid
    参加者

    Hi, Tiki

    How to confirm this issue from the log?

    Thanks

    storaid
    参加者

    Hi, Tiki

    If the log isn’t checked, seeing an error message pop-up in the UI might cause some misunderstanding, since the device might eventually connect successfully.

    Therefore, I think the error message pop-up should be suppressed in the UI unless the device completely fails to connect.

    Thanks

    返信先: How to keep new UI layout? #15580
    storaid
    参加者

    Hi, Tiki

    You’re right.

    This issue is related to the operating system, but the exact cause is unclear.

    I found a solution:

    After pressing the Windows key and using the direction keys (up/down/left/right) to move the window around a few times, then restoring it to its original position, the next time you open the program, it will retain the previous layout.

    Thanks

    storaid
    参加者

    Hi, Tiki,

    Sorry, I may not have explained clearly enough.

    
    
    2024/10/05 17:09:09,164: UL13826: T0b7b8: UPnP_P: [UPP_WorkerThread]: Phase 1.
    2024/10/05 17:09:09,664: UL13828: T0b7b8: UPnP_P: [UPP_InitDevice1] 2: Initialize UPnP info of the Player.
    2024/10/05 17:09:09,664: UL13830: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP is initialized.
    2024/10/05 17:09:09,664: UL13832: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP DeviceInfo: USN:[uuid:87f1e18e-7e24-b992-8383-d83adde83eaf::urn:schemas-upnp-org:device:MediaRenderer:1]
    2024/10/05 17:09:09,664: UL13834: T0b7b8: UPnP_P: [UPP_InitDevice1] - Location: http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/description.xml
    2024/10/05 17:09:09,664: UL13836: T0b7b8: UPnP_P: [UPP_InitDevice1] - Name : Red_10.1.1.97-UPnP/AV
    2024/10/05 17:09:09,664: UL13838: T0b7b8: UPnP_P: [UPP_InitDevice1] - Model : UpMPD
    2024/10/05 17:09:09,664: UL13840: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP Service found: [urn:schemas-upnp-org:service:ConnectionManager:1]
    2024/10/05 17:09:09,664: UL13842: T0b7b8: UPnP_P: [UPP_InitDevice1] QuerySOAP: Getting ProtocolInfo.
    2024/10/05 17:09:09,665: UL13844: T0b7b8: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] to: 10.1.1.97 [http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/ctl-urn-schemas-upnp-org-service-ConnectionManager-1]
    2024/10/05 17:09:12,677: UL13868: T0b7b8: Error: UPnP_P: [SOAP Request]: Cannot connect to server: 10.1.1.97 :49152
    2024/10/05 17:09:12,677: UL13870: T0b7b8: Error: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] was failed.
    2024/10/05 17:09:12,677: UL13872: T0b7b8: Error: UPnP_P: [SOAP Request]: SOAP request detected error: [ 4] (TFXFWTimeout)
    2024/10/05 17:09:12,678: UL13874: T0b7b8: Error: UPnP_P: [UPP_InitDevice1] GetProtocolInfo failed.
    2024/10/05 17:09:12,778: UL13877: T0b7b8: UPnP_P: [UPP_InitDevice1] 3: Initialize UPnP info of the Player.
    2024/10/05 17:09:12,778: UL13879: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP is initialized.
    2024/10/05 17:09:12,778: UL13881: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP DeviceInfo: USN:[uuid:87f1e18e-7e24-b992-8383-d83adde83eaf::urn:schemas-upnp-org:device:MediaRenderer:1]
    2024/10/05 17:09:12,778: UL13883: T0b7b8: UPnP_P: [UPP_InitDevice1] - Location: http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/description.xml
    2024/10/05 17:09:12,778: UL13885: T0b7b8: UPnP_P: [UPP_InitDevice1] - Name : Red_10.1.1.97-UPnP/AV
    2024/10/05 17:09:12,778: UL13887: T0b7b8: UPnP_P: [UPP_InitDevice1] - Model : UpMPD
    2024/10/05 17:09:12,778: UL13889: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP Service found: [urn:schemas-upnp-org:service:ConnectionManager:1]
    2024/10/05 17:09:12,778: UL13891: T0b7b8: UPnP_P: [UPP_InitDevice1] QuerySOAP: Getting ProtocolInfo.
    2024/10/05 17:09:12,779: UL13893: T0b7b8: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] to: 10.1.1.97 [http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/ctl-urn-schemas-upnp-org-service-ConnectionManager-1]
    2024/10/05 17:09:15,794: UL13895: T0b7b8: Error: UPnP_P: [SOAP Request]: Cannot connect to server: 10.1.1.97 :49152
    2024/10/05 17:09:15,794: UL13897: T0b7b8: Error: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] was failed.
    2024/10/05 17:09:15,794: UL13899: T0b7b8: Error: UPnP_P: [SOAP Request]: SOAP request detected error: [ 4] (TFXFWTimeout)
    2024/10/05 17:09:15,794: UL13901: T0b7b8: Error: UPnP_P: [UPP_InitDevice1] GetProtocolInfo failed.
    2024/10/05 17:09:15,894: UL13903: T0b7b8: UPnP_P: [UPP_InitDevice1] 4: Initialize UPnP info of the Player.
    2024/10/05 17:09:15,894: UL13905: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP is initialized.
    2024/10/05 17:09:15,894: UL13907: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP DeviceInfo: USN:[uuid:87f1e18e-7e24-b992-8383-d83adde83eaf::urn:schemas-upnp-org:device:MediaRenderer:1]
    2024/10/05 17:09:15,894: UL13909: T0b7b8: UPnP_P: [UPP_InitDevice1] - Location: http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/description.xml
    2024/10/05 17:09:15,894: UL13911: T0b7b8: UPnP_P: [UPP_InitDevice1] - Name : Red_10.1.1.97-UPnP/AV
    2024/10/05 17:09:15,894: UL13913: T0b7b8: UPnP_P: [UPP_InitDevice1] - Model : UpMPD
    2024/10/05 17:09:15,894: UL13915: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP Service found: [urn:schemas-upnp-org:service:ConnectionManager:1]
    2024/10/05 17:09:15,894: UL13917: T0b7b8: UPnP_P: [UPP_InitDevice1] QuerySOAP: Getting ProtocolInfo.
    2024/10/05 17:09:15,895: UL13919: T0b7b8: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] to: 10.1.1.97 [http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/ctl-urn-schemas-upnp-org-service-ConnectionManager-1]
    2024/10/05 17:09:18,905: UL13922: T0b7b8: Error: UPnP_P: [SOAP Request]: Cannot connect to server: 10.1.1.97 :49152
    2024/10/05 17:09:18,905: UL13924: T0b7b8: Error: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] was failed.
    2024/10/05 17:09:18,905: UL13926: T0b7b8: Error: UPnP_P: [SOAP Request]: SOAP request detected error: [ 4] (TFXFWTimeout)
    2024/10/05 17:09:18,906: UL13928: T0b7b8: Error: UPnP_P: [UPP_InitDevice1] GetProtocolInfo failed.
    2024/10/05 17:09:19,006: UL13930: T0b7b8: UPnP_P: [UPP_InitDevice1] 5: Initialize UPnP info of the Player.
    2024/10/05 17:09:19,006: UL13932: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP is initialized.
    2024/10/05 17:09:19,006: UL13934: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP DeviceInfo: USN:[uuid:87f1e18e-7e24-b992-8383-d83adde83eaf::urn:schemas-upnp-org:device:MediaRenderer:1]
    2024/10/05 17:09:19,006: UL13936: T0b7b8: UPnP_P: [UPP_InitDevice1] - Location: http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/description.xml
    2024/10/05 17:09:19,006: UL13938: T0b7b8: UPnP_P: [UPP_InitDevice1] - Name : Red_10.1.1.97-UPnP/AV
    2024/10/05 17:09:19,006: UL13940: T0b7b8: UPnP_P: [UPP_InitDevice1] - Model : UpMPD
    2024/10/05 17:09:19,006: UL13942: T0b7b8: UPnP_P: [UPP_InitDevice1] - UPnP Service found: [urn:schemas-upnp-org:service:ConnectionManager:1]
    2024/10/05 17:09:19,006: UL13944: T0b7b8: UPnP_P: [UPP_InitDevice1] QuerySOAP: Getting ProtocolInfo.
    2024/10/05 17:09:19,010: UL13946: T0b7b8: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] to: 10.1.1.97 [http://10.1.1.97:49152/uuid-87f1e18e-7e24-b992-8383-d83adde83eaf/ctl-urn-schemas-upnp-org-service-ConnectionManager-1]
    2024/10/05 17:09:22,544: UL13951: T0b7b8: UPnP_P: [SOAP Request]: SOAP request: [GetProtocolInfo ] finished.
    
    

    From the log, it looks very similar to a retry operation.

    However, my key point is that unless the connection completely fails,

    I think the following error message should not appear, as it might cause confusion…

    storaid
    参加者

    dears

    Well, I’m not sure

    maybe it seems to be a classic flickering issue from Windows I guess.

    I’m not sure if it is easy to solve or can be suppressed.

    Intentional testing method:

    Step 0: Please set the refresh rate of your main monitor to over 60Hz, for example, 120Hz.

    Step 1: If you have more than one GPU, force the app to use the high-performance GPU in the app settings.

    Step 2: Open TuneBrowser.

    Step 3: Play any track.

    While playing, wait for about 10 seconds. You might see the timebar flickering issue.

    If the problem still doesn’t appear, move your mouse to the timebar around on the Player View and click a few times randomly to test if the issue occurs.

    storaid
    参加者

    Hi, Tiki

    Thanks for your explanation..

    I’ve expanded my testing with other music players.

    Foobar2000 and Synology Audio Station both have the same issue.

    For the ifi UPnP renderer device, inconsistent metadata should be a bug.

    However, interestingly, to keep compatibility with certain brands, they’ve added support for the OpenHome UPnP API.

    Since the ifi UPnP renderer natively retains OpenHome API support.

    I’ve noticed that Foobar2000 and Synology Audio Station prioritize calling the OpenHome UPnP API, so they are not affected by the inconsistent metadata bug.

    I will continue communicating with ifi-audio tech support, hoping to resolve this very basic error.

    Thanks

    storaid
    参加者

    Hi, Tiki

    here is the difference the timebar function is still working in v5.5.3, even if the DIDL metadata is inconsistent.

    as you said above, if the handling of duration logic has not changed in v5.6.0, that timebar function should be working the same as with the previous version.

    but in fact this is not the case.

    also, that’s a question maybe you changed something for timebar function?

    thanks

    storaid
    参加者

    “I think the handling of duration has not changed between versions.”

    Ok

    If that is the case, even if the DIDL metadata format obtained from the renderer is incorrect.

    I don’t know exactly why the total track length retrieved by the UI timebar function in version v5.5.3 is working well.

100件の投稿を表示中 - 1 - 100件目 (全348件中)