shaka-project / shaka-player-embedded

Shaka Player in a C++ Framework
Apache License 2.0
239 stars 62 forks source link

How does CurrentTime() work for live streams #59

Closed Megubit closed 4 years ago

Megubit commented 4 years ago

I'm wondering how does the CurrentTime() work for live streams, more specifically the time format. I know the returned value is in seconds, but how does it get the amount of seconds for a live stream?

The general problem that I'm having is trying to implement the player in the app that already has native player in it, and make both native and shaka player work the same way.

For example, iOS native player uses CMTime type to handle players position, duration etc. It has a value in nanoseconds, and a scale indicating the format of the value (nanoseconds). The whole app uses milliseconds, so value/scale * 1000 and I get what I need.

However since shaka player already returns the format in seconds all I need to do is multiply it with 1000 or so I thought. This does work for VOD content where start is 1 second and end is xxx seconds. But how do live streams work.

This is an example of a demo app log for a live stream.

native position 1193521
shaka position  917302
native position 1194000
shaka position  917302
native position 1194501
shaka position  917303
native position 1195001
native position 1195478
native position 1195478
shaka position  917303
native position 1195500
native position 1196001
shaka position  917304
shaka position  917304
native position 1196501
shaka position  917305
native position 1197001
shaka position  917305
native position 1197501
shaka position  917306
native position 1198000
position shaka  917306

Native player is made to log out milliseconds and shaka is the default [player currentTime] so I assume it's in seconds. This is a huge difference, in native player the stream is at 1198 seconds while for shaka that's 917306 seconds. Now I didn't check, but the same app implementation is made also for android where the main player is ExoPlayer2 so I assume it returns same format as native player. Is there a way to get same position from shaka player? It's really mind boggling to get the two to work together.

TheModMaker commented 4 years ago

[player currentTime] just returns the value from the Shaka Player instance. For Live streams, Shaka Player doesn't have a well-defined value for what the current time's value is. It is suggested to just use the seekRange to determine what the range of values are.

For DASH content, the current time is the time since the availabilityStartTime, which is usually when the live stream started. For HLS, I think it is based on the segment times. So if the last segment in the HLS manifest starts at 917306, then that is the video time the live edge is. We could adjust the segments to be closer to 0, but I don't see a use for that since I'm not sure what the native player's 0 is.

When you got a value of 1198 from the native player, how long were you playing the stream for? How long ago did the live stream start? Could you provide an example URL (or use one of our demo assets from Shaka Player)? What are you using the current time for? By default, HLS manifests are unseekable, so they always play at the live edge.

Megubit commented 4 years ago

For the stream I used the one from the demo assets https://storage.googleapis.com/shaka-live-assets/player-source.m3u8, it breaks after a few seconds of playing, but it was the only live stream I could find that is not in ts format.

I started the stream on both native and shaka at the same time and sadly I don't know for how long it was going.

I'm using the current time for VOD and catch-up content. I mentioned live streams as I guess it has something to do with the wrong time for catch-up (comparing native and shaka). (I'll have to look more into the way how catch-up is handled, I didn't work on the system from the start)

What I mean with wrong time for catch-up, I assume it should start from 0 since catch-up is also a recording (in native it has some small offset, probably chuck difference cca. 10000 milliseconds), but instead it returns current time in huge numbers like for live. I'll work on it next week and see in more details.

Megubit commented 4 years ago

So the conclusion is that shakaplayer does indeed return the current position of the stream as the time from when it started, while native for some reason always starts between 10 and 30 seconds and keeps counting the time since you started watching the stream. And on our end catch-up is simulated as live, so it can keep going and the user can keep watching it without interruptions. This explains why shaka returns such a huge number for catch up.

For now I made a workaround to check if seekRange exists and use that to subtract from current position so I get a starting position from 0, and the rest is done by the offset.