google / google/ExoPlayer

Getting current PTS in HLS livestream?

Open
#7,708 4 comments 0 reactions 1 assignee Claimed by @AquilesCanta View on GitHub
needs triage question
Dominant language
Java
Stars
21.9k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

### Searched documentation and issues

- https://github.com/google/ExoPlayer/issues/2118
- https://github.com/google/ExoPlayer/issues/2289
- https://github.com/google/ExoPlayer/issues/7658
- https://github.com/google/ExoPlayer/issues/2930

### Question

I want to detect if the current position is at or has passed a certain PTS in an HLS livestream so that I can perform arbitrary actions (such as applying different visual style). For example, if it's at 00:10:31 (or has already passed that mark because the player joined the livestream late), change the background image.

When the HLS manifest includes `#EXT-X-PROGRAM-DATE-TIME`, I can use the following to get current timestamp:

```java
final int windowIndex = player.getCurrentWindowIndex();
final Timeline timeline = player.getCurrentTimeline();
final Timeline.Window window = timeline.getWindow(windowIndex, new Timeline.Window());

// This is not really PTS but good enough info to use:
window.windowStartTimeMs + player.getCurrentPosition()
```

In many cases HLS manifest author doesn't include `#EXT-X-PROGRAM-DATE-TIME`, and without such tag, it looks like I cannot get PTS (or timestamp) of the livestream. I tried the following:

```java
// presentationStartTimeMs is C.TIME_UNSET unfortunately.
window.presentationStartTimeMs + player.getCurrentPosition()
```

But, `window.presentationStartTimeMs` is `C.TIME_UNSET`.

Segments do have PTS:

```
$ ffprobe -v error -of json -select_streams v -show_packets https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/segment_1_20200803_1596481155.ts | jq .packets[] -c | head -1 | jq .
{
"codec_type": "video",
"stream_index": 0,
"pts": 1292217244,
"pts_time": "14357.969378",
```

`pts_time`, 14357.969378, is about 03:59:18 . And using a different player, I can verify that:

```
$ mpv --rebase-start-time=no --osd-level=3 https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/segment_1_20200803_1596481155.ts
```

The video starts with 03:59:18 (with --rebase-start-time=no , [mpv](https://mpv.io/manual/master/#options-rebase-start-time) doesn't start with 00:00:00 but displays PTS as-is).

This livestream is from https://ottverse.com/free-hls-m3u8-test-urls/ . And I'm not sure how long it'll last. I used https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/level_1.m3u8 (from master.m3u8).

Would it be a good idea to set `window.presentationStartTimeMs` to PTS of the first packet/frame of the current window? Or, I think adding that to Timeline.Period is better because a window may contain multiple periods including foreign segments (such as ad). And, if we only expose "start time" of a window, instead of a period, it'll be difficult to get the current position (PTS or some timestamp).

For example, `window.windowStartTimeMs + player.getCurrentPosition()` doesn't accurately describe where the player is at in the "main" HLS stream. If I have the following manifest:

```m3u8
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2020-07-30T20:00:00.000Z
output303.ts

#EXTINF:10,
#EXT-X-DISCONTINUITY
ad.ts

#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2020-07-30T20:00:04.000Z
output304.ts
```

I expect `window.windowStartTimeMs + player.getCurrentPosition()` to be around 2020-07-30T20:00:04 when it's playing `output304.ts` segment. But, since window hasn't changed (this particular short example wasn't livestream, but vod), `window.windowStartTimeMs` is still at 2020-07-30T20:00:00 and `player.getCurrentPosition()` includes those 10 seconds from ad.ts. So, `window.windowStartTimeMs + player.getCurrentPosition()` results in 2020-07-30T20:00:14 .

The question is, how do I get current PTS or current timestamp (based on `#EXT-X-PROGRAM-DATE-TIME`) in HLS even in the presence of discontinuity?

### A full bug report captured from the device

N/A

### Link to test content

- https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/level_1.m3u8 (I don't own this. It's from https://ottverse.com/free-hls-m3u8-test-urls/ .)
- https://github.com/saml/exoplayer-example/blob/master/fixture/hls-with-audio/output-date-time.m3u8 (This is for testing `#EXT-X-PROGRAM-DATE-TIME` with an ad in the middle)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.