フォーラム › TuneBrowser › Non-linear seek bar pointer movement issue in UPnP playback
-
投稿者投稿
-
2026-02-06 20:45 #17427storaid参加者
Hello Tiki,
I’ve encountered an issue during UPnP playback.
If I pause the UPnP renderer for a period of time and then resume playback, the seek bar may behave abnormally.For example:
- Current displayed position: 0:03
- (after waiting about 5–10 seconds)
- It suddenly jumps to: 0:10
In other words, the seek bar pointer does not move linearly with time progression.
So far, the only workaround I’ve found is restarting TuneBrowser.
Could you please help confirm whether this behavior is expected or investigate the cause?
Thank you very much for your excellent development.
Attachments:
2026-02-08 18:41 #17437TikiキーマスターTuneBrowser is only using response of GetPositionInfo. Unfortunately, there doesn’t seem to be anything I can do.
2026-02-08 19:00 #17439storaid参加者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?
2026-02-08 19:23 #17440storaid参加者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.2026-02-08 20:09 #17441storaid参加者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
2026-02-08 21:30 #17442storaid参加者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.
2026-02-08 22:15 #17443storaid参加者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 DMRVolumio:
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
2026-02-09 15:54 #17444storaid参加者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:
- 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. - 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. - 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!
2026-02-09 19:10 #17445TikiキーマスターOut of curiosity, is this polling frequency a deliberate design choice?
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.
2026-02-09 19:41 #17446storaid参加者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!
2026-02-09 20:02 #17447storaid参加者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.
2026-02-09 20:44 #17448TikiキーマスターThis processing has been refined over many years and is highly complex. Therefore, accurately answering your long question would require re-examining the processing, which is very difficult, primarily due to time constraints.
It appears that polling is reduced after detecting an event five or more times. But you probably don’t want an answer that includes speculation. It’s a very difficult situation.2026-02-09 20:46 #17449TikiキーマスターThe event is LastChange::RelativeTimePosition.
2026-02-09 21:23 #17450storaid参加者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!
2026-02-09 21:32 #17451storaid参加者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
2026-02-09 21:39 #17452TikiキーマスターIf it’s not LastChange::RelativeTimePosition, which event are you talking about?
2026-02-09 21:58 #17453storaid参加者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!
2026-02-09 22:07 #17454TikiキーマスターIn practice, the vast majority of real-world DMRs are simply not designed to emit frequent RelativeTimePosition events.
I agree. That’s why TuneBrowser supports GetPositionInfo. Are you talking about some other means?
2026-02-09 22:25 #17455storaid参加者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!
2026-02-09 22:41 #17456TikiキーマスターSetting a longer polling interval is fine. What I don’t understand is what you mean by “event-preferred mode.”
2026-02-09 22:48 #17457storaid参加者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!
2026-02-09 22:57 #17458TikiキーマスターAh, that’s separate from GetPositionInfo. Considering cases where TransportState isn’t properly notified, I can’t easily agree.
2026-02-09 23:19 #17459storaid参加者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
2026-02-09 23:52 #17460TikiキーマスターAgain, setting a longer polling interval is fine. I’d improve it in future release. And your “event-preferred mode” does not agree.
2026-02-10 00:10 #17461storaid参加者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.
2026-02-10 01:03 #17462storaid参加者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!
-
投稿者投稿
- このトピックに返信するにはログインが必要です。