hls.js
hls.js copied to clipboard
Playing multi-program streams
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:
@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
This reference may be of some use:
https://en.wikipedia.org/wiki/MPEG_transport_stream
https://en.wikipedia.org/wiki/Program-specific_information
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.