Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stringify : Manifest malformation with multiple rendition (group-id) #135

Closed
xavierlaffargue opened this issue Oct 17, 2023 · 6 comments
Closed

Comments

@xavierlaffargue
Copy link

When I've multiple rendition (for example multiple codec for the same language) stringify return the manifest with a EXT-X-STREAM-INF between EXT-X-MEDIA.

For example :

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aacl",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aacl.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.5",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aacl"
1080p.m3u8
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aac.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8417895,AVERAGE-BANDWIDTH=6810888,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="eng_aac"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aacl"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5094830,AVERAGE-BANDWIDTH=3810268,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="eng_aac"
720p.m3u8

It's appear to be a design issue in the code : https://github.com/kuu/hls-parser/blob/3d37ad8ef3a4836357e30764c8c43010cb8ed0a4/stringify.ts#L126C1-L126C1

You should first create the renditions and then the EXT-X-STREAM-INF

@kuu
Copy link
Owner

kuu commented Oct 21, 2023

If there are multiple rendition groups, stringify() writes the variants per group.

It can read this file:

    #EXTM3U
    #EXT-X-VERSION:4
    #EXT-X-INDEPENDENT-SEGMENTS
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_high",NAME="English",DEFAULT=YES,URI="aac_high_eng.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_high",NAME="Japanese",DEFAULT=NO,URI="aac_high_jp.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_mid",NAME="English",DEFAULT=YES,URI="aac_mid_eng.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_mid",NAME="Japanese",DEFAULT=NO,URI="aac_mid_jp.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_low",NAME="English",DEFAULT=YES,URI="aac_low_eng.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_low",NAME="Japanese",DEFAULT=NO,URI="aac_low_jp.m3u8"
    #EXT-X-STREAM-INF:BANDWIDTH=6000000,AUDIO="aac_high"
    1080p.m3u8
    #EXT-X-STREAM-INF:BANDWIDTH=3000000,AUDIO="aac_mid"
    720p.m3u8
    #EXT-X-STREAM-INF:BANDWIDTH=1500000,AUDIO="aac_mid"
    540p.m3u8
    #EXT-X-STREAM-INF:BANDWIDTH=1000000,AUDIO="aac_low"
    360p.m3u8

However, it writes like this:

    #EXTM3U
    #EXT-X-VERSION:4
    #EXT-X-INDEPENDENT-SEGMENTS
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_high",NAME="English",DEFAULT=YES,URI="aac_high_eng.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_high",NAME="Japanese",DEFAULT=NO,URI="aac_high_jp.m3u8"
    #EXT-X-STREAM-INF:BANDWIDTH=6000000,AUDIO="aac_high"
    1080p.m3u8
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_mid",NAME="English",DEFAULT=YES,URI="aac_mid_eng.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_mid",NAME="Japanese",DEFAULT=NO,URI="aac_mid_jp.m3u8"
    #EXT-X-STREAM-INF:BANDWIDTH=3000000,AUDIO="aac_mid"
    720p.m3u8
    #EXT-X-STREAM-INF:BANDWIDTH=1500000,AUDIO="aac_mid"
    540p.m3u8
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_low",NAME="English",DEFAULT=YES,URI="aac_low_eng.m3u8"
    #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac_low",NAME="Japanese",DEFAULT=NO,URI="aac_low_jp.m3u8"
    #EXT-X-STREAM-INF:BANDWIDTH=1000000,AUDIO="aac_low"
    360p.m3u8

@kuu kuu closed this as completed Oct 21, 2023
@xavierlaffargue
Copy link
Author

No, that’s not my behavior. And I've never seen variants by group in a master playlist HLS in the real life, a correction must be made (I can create a PR).

@kuu
Copy link
Owner

kuu commented Oct 22, 2023

Can you provide expected/actual manifests and what issue was caused by the actual manifest?
Your first example only has one rendition per group, which looks unrealistic to me.

@xavierlaffargue
Copy link
Author

With 3 audio rendition group you will see the issue :

File read:

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aacl",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aacl.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aac.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_heaac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_heaac.m3u8"

#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.5",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aacl"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aacl"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_aacl"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_aacl"
360p.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=8417895,AVERAGE-BANDWIDTH=6810888,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aac"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5094830,AVERAGE-BANDWIDTH=3810268,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aac"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_aac"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_aac"
360p.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.1",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_heaac"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_heaac"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_heaac"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_heaac"
360p.m3u8

Actual :

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aacl",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aacl.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.5",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aacl"
1080p.m3u8
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aac.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8417895,AVERAGE-BANDWIDTH=6810888,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aac"
1080p.m3u8
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_heaac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_heaac.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.1",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_heaac"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aacl"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_aacl"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_aacl"
360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5094830,AVERAGE-BANDWIDTH=3810268,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aac"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_aac"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_aac"
360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_heaac"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_heaac"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_heaac"
360p.m3u8

@kuu
Copy link
Owner

kuu commented Oct 22, 2023

The current version of stringify() actually generates the following playlist:

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aacl",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aacl.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.5",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aacl"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aacl"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_aacl"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_aacl"
360p.m3u8
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_aac.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8417895,AVERAGE-BANDWIDTH=6810888,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_aac"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5094830,AVERAGE-BANDWIDTH=3810268,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_aac"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_aac"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.5",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_aac"
360p.m3u8
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_heaac",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="eng_heaac.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=8277095,AVERAGE-BANDWIDTH=6670088,CODECS="avc1.640028,mp4a.40.1",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="audio_heaac"
1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=1280x720,FRAME-RATE=29.970,AUDIO="audio_heaac"
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=858x480,FRAME-RATE=29.970,AUDIO="audio_heaac"
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5235630,AVERAGE-BANDWIDTH=3951068,CODECS="avc1.4D401F,mp4a.40.1",RESOLUTION=480x360,FRAME-RATE=29.970,AUDIO="audio_heaac"
360p.m3u8

Dis you observe any playback issue with the above playlist?
Or, did you see a playlist written differently by some products?

@kuu
Copy link
Owner

kuu commented Oct 22, 2023

BTW, the playlist examples in the HLS spec suggest 2 patterns of multiple rendition groups:

   #EXTM3U
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Main", \
      DEFAULT=YES,URI="low/main/audio-video.m3u8"
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Centerfield", \
      DEFAULT=NO,URI="low/centerfield/audio-video.m3u8"
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Dugout", \
      DEFAULT=NO,URI="low/dugout/audio-video.m3u8"

   #EXT-X-STREAM-INF:BANDWIDTH=1280000,CODECS="...",VIDEO="low"
   low/main/audio-video.m3u8

   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Main", \
      DEFAULT=YES,URI="mid/main/audio-video.m3u8"
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Centerfield", \
      DEFAULT=NO,URI="mid/centerfield/audio-video.m3u8"
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Dugout", \
      DEFAULT=NO,URI="mid/dugout/audio-video.m3u8"

   #EXT-X-STREAM-INF:BANDWIDTH=2560000,CODECS="...",VIDEO="mid"
   mid/main/audio-video.m3u8

   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Main", \
      DEFAULT=YES,URI="hi/main/audio-video.m3u8"
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Centerfield", \
      DEFAULT=NO,URI="hi/centerfield/audio-video.m3u8"
   #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Dugout", \
      DEFAULT=NO,URI="hi/dugout/audio-video.m3u8"

   #EXT-X-STREAM-INF:BANDWIDTH=7680000,CODECS="...",VIDEO="hi"
   hi/main/audio-video.m3u8
   #EXTM3U
   #EXT-X-CONTENT-STEERING:SERVER-URI="/steering?video=00012", \
      PATHWAY-ID="CDN-A"
   #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="A",NAME="English",DEFAULT=YES, \
      URI="eng.m3u8",LANGUAGE="en",STABLE-RENDITION-ID="Audio-37262"
   #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="B",NAME="ENGLISH",DEFAULT=YES, \
      URI="https://b.example.com/content/videos/video12/eng.m3u8", \
      LANGUAGE="en",STABLE-RENDITION-ID="Audio-37262"
   #EXT-X-STREAM-INF:BANDWIDTH=1280000,AUDIO="A",PATHWAY-ID="CDN-A", \
      STABLE-VARIANT-ID="Video-128"
   low/video.m3u8
   #EXT-X-STREAM-INF:BANDWIDTH=7680000,AUDIO="A",PATHWAY-ID="CDN-A", \
      STABLE-VARIANT-ID="Video-768"
   hi/video.m3u8
   #EXT-X-STREAM-INF:BANDWIDTH=1280000,AUDIO="B",PATHWAY-ID="CDN-B", \
      STABLE-VARIANT-ID="Video-128"
   https://backup.example.com/content/videos/video12/low/video.m3u8
   #EXT-X-STREAM-INF:BANDWIDTH=7680000,AUDIO="B",PATHWAY-ID="CDN-B", \
      STABLE-VARIANT-ID="Video-768"
   https://backup.example.com/content/videos/video12/hi/video.m3u8

Though the spec does not state which pattern is correct, I'm open to discuss based on the examples in real life.
Please let me know if you observe any issues with the current behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants