[tvOS] Seeking in livestreams will eventually stall

Since tvOS 17, seeking in livestreams is bugged. I’m talking specifically about livestreams with a DVR window (so no seeking into the future).

Normally when seeking in a livestream, these events fire in order:

  • (regular .onTimeChanged callbacks at a ~1s interval)
  • onTimeShift
  • state changes to .loading
  • onStallStarted
  • state changes to .playing
  • onStallEnded
  • onTimeShifted ( = completed the seek action)
  • (regular .onTimeChanged callbacks at a ~1s interval)

Now there is something strange happening, which is not 100% reproducible:

  • (regular .onTimeChanged callbacks at a ~1s interval)
  • onTimeShift
  • state changes to .loading
  • onStallStarted
  • state changes to .playing
  • onStallEnded

And that’s it. No “onTimeShifted” and no more “onTimeChanged” callbacks, even though the streams keeps on playing. This behaviour is often indicated with an infinite spinner in the seekbar.

Whenever the player enters this scenario, it keeps on playing the content until the buffer is empty, and no more segments are loaded in. With a simple “seek 10s back” user-action this can be solved. I’ve also managed to recognise this behaviour in code, and apply the following patch:
“player.timeShift = player.timeShift” to set the user at their current point in the stream. This seems to “reset” the player into a valid state. The only downside is that the user sees a little hiccup in the stream, but they’re able to watch the stream uninterrupted.

This is definitely not an ideal situation. Are there more people experiencing this behaviour in live streams?
I’m wondering if this is a Bitmovin or Apple issue

ps.
a bullet list is not showing visually any bullets on this forum?

  • indicated with a star
  • indicated with a dash
  1. indicated with a number

Hi @mart.zonneveld,

Thank you for reporting the issue and the very detailed description. We are not aware of this issue yet.

Would it be possible for you to share an example stream where this issue occurs?


I will also delegate the missing bullet list issue. Thank you also for that.

Hi David,

I’ve sent you a DRM-free live manifest to test with via private message.

Within the “BasicUIKitTV” sample app I could reproduce my issue with mentioned stream. I’ve added some specific PlayerListener-callbacks to clarify the logs. These are:

    func onTimeShift(_ event: TimeShiftEvent, player: Player) {
        print("\(#function) towards \(event.timeShift)")
    }
    
    func onTimeShifted(_ event: TimeShiftedEvent, player: Player) {
        print("\(#function)")
    }
    
    func onStallStarted(_ event: StallStartedEvent, player: Player) {
        print("\(#function)")
    }
    
    func onStallEnded(_ event: StallEndedEvent, player: Player) {
        print("\(#function)")
    }
    
    func onTimeChanged(_ event: TimeChangedEvent, player: Player) {
        print("\(#function) at \(player.currentTime(.relativeTime))")
    }

Reproduction steps:

  • Seek back to almost the beginning of the DVR window
  • Seek by tapping the remote 2 or 3 times. This does not have 100% reproduction rate, so you’ll have to repeat the timeshift forward action a few times.

In the logs the issue is reflected by not getting an onTimeShifted and no more onTimeChanged updates. In almost all cases when this happens, the player will not buffer more segments and will eventually stall forever.

Thank you for the sample stream and the reproduction steps. I was able to reproduce the issue you described.

Hi David,
Is there any update on this issue?

Hi Mart,

Could I ask you to open a support ticket via the portal please? This will help give some visibility in the account and allow us to help you more directly

Thanks,
Jacob