hls.js icon indicating copy to clipboard operation
hls.js copied to clipboard

Playing multi-program streams

Open MatteoBuffo opened this issue 3 years ago • 3 comments

What do you want to do with Hls.js?

Playing multi-program streams with the Hls player

What have you tried so far?

Hi! I would like Hls to play one of the multi-program streams provided by this website (let's say this one).

Any suggestions? I have a feeling that the TS Demuxer should be involved in this, but I am not quite sure about it.

Steps to reproduce

  • clone the hls.js repo
  • create this minimal media playlist:
    #EXTM3U
    #EXT-X-TARGETDURATION:32
    
    #EXTINF:32.000,
    mux1rai.ts
    #EXT-X-ENDLIST
    
  • replace the default playlist with the new one here

The player loads indefinitely and appears like this: image

MatteoBuffo avatar Feb 22 '22 10:02 MatteoBuffo

@MatteoBuffo Just pointing out here... the reason hls.js does not play anything from that stream is because the first entry in the Program Association Table is the Network Information Table PID (program 0).

hls.js blindly reads the first entry of the Program Association Table. If that refers to the NIT rather than one of the programs, then hls.js tries to interpret the NIT tables as if a Program Map Table, comes up with junk PIDs, and fails to play anything.

As someone who's codebase generates MPEG transport streams, and was writing code to send it over HLS, I found this out by accident.

Here's what our internal MPEG-TS analysis code shows for your *.ts URL:

* Program Association Table
    Transport stream ID:              0x0001
    Version:                          0
    Section:                          0 / 0
      Network Info Table PID is 0x0010
      Program 0x0d49: PMT PID is 0x0102
        First aware of, tracking program 0x0d49
      Program 0x0d4a: PMT PID is 0x0101
        First aware of, tracking program 0x0d4a
      Program 0x0d4b: PMT PID is 0x0100
        First aware of, tracking program 0x0d4b
      Program 0x0d53: PMT PID is 0x0118
        First aware of, tracking program 0x0d53
      Program 0x0d4c: PMT PID is 0x0103
        First aware of, tracking program 0x0d4c
      Program 0x0d4d: PMT PID is 0x0104
        First aware of, tracking program 0x0d4d
      Program 0x0d4e: PMT PID is 0x0105
        First aware of, tracking program 0x0d4e
      Program 0x0d52: PMT PID is 0x012c
        First aware of, tracking program 0x0d52

The NIT is listed first, therefore hls.js tries to play that as if a program, and fails.

See: https://github.com/video-dev/hls.js/blob/master/src/demux/tsdemuxer.ts#L989

joncampbell123 avatar Apr 17 '22 02:04 joncampbell123

This reference may be of some use:

https://en.wikipedia.org/wiki/MPEG_transport_stream

https://en.wikipedia.org/wiki/Program-specific_information

joncampbell123 avatar Apr 17 '22 02:04 joncampbell123

HLS does not support multi-program transport streams. The HLS spec is specific about this requirement:

3.1.1. MPEG-2 Transport Streams

MPEG-2 Transport Streams are specified by [ISO_13818].

The Media Initialization Section of an MPEG-2 Transport Stream Segment is a Program Association Table (PAT) followed by a Program Map Table (PMT).

Transport Stream Segments MUST contain a single MPEG-2 Program; playback of Multi-Program Transport Streams is not defined. Each Transport Stream Segment MUST contain a PAT and a PMT, or have an EXT-X-MAP tag (Section 4.4.4.5) applied to it. The first two Transport Stream packets in a Segment without an EXT-X-MAP tag SHOULD be a PAT and a PMT.

Try adding a MAP tag that points the PMT and PAT packets using byte ranges. If that works in Safari but not in HLS.js we can look into addressing playback of TS segment HLS streams with MAP tags. As it stands the sample provided in the repro steps when recreated and loaded into Safari does not play because it is not spec compliant.

robwalch avatar Jul 12 '22 02:07 robwalch