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

Live stream stalls with "playback stalling in low buffer" #1172

Closed
kiranatious opened this issue May 25, 2017 · 49 comments
Closed

Live stream stalls with "playback stalling in low buffer" #1172

kiranatious opened this issue May 25, 2017 · 49 comments
Labels

Comments

@kiranatious
Copy link

Environment
  • [ x] The stream has correct Access-Control-Allow-Origin headers (CORS)
  • [ x] There are no network errors such as 404s in the browser console when trying to play the stream
  • [x ] The issue observed is not already reported by searching on Github under https://github.com/video-dev/hls.js/issues
  • [x ] The issue occurs in the latest reference client on http://video-dev.github.io/hls.js/demo and not just on my page
Steps to reproduce
  1. Click the link below to open HLS JS demo page with Live HLS stream
    http://video-dev.github.io/hls.js/demo/?src=http%3A%2F%2Fhsn.mpl.miisolutions.net%2Fhsn-live01%2F_definst_%2Fsmil%3AHSN1_ipad.smil%2Fplaylist.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined
  2. Leave it to play for 5 -20 minutes
  3. after few minutes, playback stops (dev tool, we can see "playback stalling in low buffer "
Expected behavior

Playback should not stop

Actual behavior

playback stops after few minutes

Console output
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > live playlist, switching playlist, unknown, load middle frag : 49
logger.js:39 [log] > Loading 49 of [45 ,51],level 2, currentTime:176.396,bufferEnd:176.469
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [warn] > playback stalling in low buffer @176.39583
(anonymous) @ logger.js:39
_checkBuffer @ stream-controller.js:1449
doTick @ stream-controller.js:171
tick @ stream-controller.js:124
(index):529 Object {type: “mediaError”, details: “bufferStalledError”, fatal: false, buffer: 0.07350200000001905}
(anonymous) @ (index):529
EventEmitter.emit @ events.js:96
trigger @ hls.js:93
_checkBuffer @ stream-controller.js:1450
doTick @ stream-controller.js:171
tick @ stream-controller.js:124
logger.js:39 [log] > Loaded  49 of [45 ,51],level 2
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 49 of [45 ,51],level 2, cc 0
logger.js:39 [log] > main:switch detected
blob:http://video-dev.github.io/8ba6d870-5476-4e58-b5f3-350c9dc42fdc:5167 [log] > manifest codec:mp4a.40.5,ADTS data:type:2,sampleingIndex:6[24000Hz],channelConfig:2
blob:http://video-dev.github.io/8ba6d870-5476-4e58-b5f3-350c9dc42fdc:5167 [log] > parsed codec:mp4a.40.5,rate:24000,nb channel:2
blob:http://video-dev.github.io/8ba6d870-5476-4e58-b5f3-350c9dc42fdc:5167 [log] > audio sampling rate : 24000
logger.js:39 [log] > main track:audio,container:audio/mp4,codecs[level/parsed]=[mp4a.40.5/mp4a.40.5]
logger.js:39 [log] > main track:video,container:video/mp4,codecs[level/parsed]=[avc1.420015/avc1.42c015]
logger.js:39 [log] > Parsed audio,PTS:[192.512,196.523],DTS:[192.512/196.523],nb:94,dropped:0
logger.js:39 [log] > Parsed video,PTS:[192.519,196.523],DTS:[192.519/196.523],nb:120,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [4.014,168.478][169.763,176.469][192.519,196.523]
logger.js:39 [log] > latency/loading/parsing/append/kbps:382/53/11/3/4021
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > Loading key for 45 of [45 ,51],level 2
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > Loading 45 of [45 ,51],level 2, currentTime:176.396,bufferEnd:176.469
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded  45 of [45 ,51],level 2
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 45 of [45 ,51],level 2, cc 0
logger.js:39 [log] > Parsed audio,PTS:[176.469,180.480],DTS:[176.469/180.480],nb:94,dropped:0
logger.js:39 [log] > Parsed video,PTS:[176.470,180.507],DTS:[176.470/180.507],nb:121,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [4.014,168.478][169.763,180.480][192.519,196.523]
logger.js:39 [log] > latency/loading/parsing/append/kbps:320/52/16/2/4631
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > switching to level 3
logger.js:39 [log] > loading playlist for level 3
logger.js:39 [log] > main stream:IDLE->WAITING_LEVEL
logger.js:39 [log] > main stream:WAITING_LEVEL->IDLE
logger.js:39 [log] > main stream:IDLE->WAITING_LEVEL
logger.js:39 [warn] > playback not stuck anymore @176.470523, after 1101ms
(anonymous) @ logger.js:39
_checkBuffer @ stream-controller.js:1423
doTick @ stream-controller.js:171
tick @ stream-controller.js:124
logger.js:39 [log] > main stream:WAITING_LEVEL->IDLE
logger.js:39 [log] > main stream:IDLE->WAITING_LEVEL
logger.js:39 [log] > live playlist, reload in 3631 ms
logger.js:39 [log] > level 3 loaded [45,51],duration:28.0749
logger.js:39 [log] > live playlist - outdated PTS, unknown sliding
logger.js:39 [log] > main stream:WAITING_LEVEL->IDLE
For media errors reported on Chrome browser, please also paste the output of chrome://media-internals 
@mangui
Copy link
Member

mangui commented May 27, 2017

looks like you just have rebuffering due to network conditions.
from the logs it has recovered after 1.1s
logger.js:39 [warn] > playback not stuck anymore @176.470523, after 1101ms

@mdtjrfg
Copy link

mdtjrfg commented May 30, 2017

@mangui This issue may have multiple different manifestations. The variety that I experience consistently is represented with successive level info requests without requests for any new fragments. The streamcontroller appears to believe that the end of the buffer is greater than the live edge, as defined by the comment and section of code provided below. This is regardless of bandwidth availability in this case and proceeds for an arbitrary amount of time, but can go on ad infinitum. A log is pasted below. You can see the successive level loading begin starting at the first instance of the following log line.

logger.js:39 [log] > loading playlist for level 8

In the case of the log it was roughly a two minute delay, however as mentioned this can go on for hours. There is an AMP link below seeded with the ABC Television live stream, however I am able to reproduce the issue consistently at the link Kiran provided with the HSN stream. Whereas the HSN stream tends to recover more readily, the Uplynk stream in the AMP link does not.

AMP link
http://jgirard.mediadev.edgesuite.net/test/temp/abctv/amp-hls-0.7.9/samples/index.html?amp-debug=true&amp-usecorsproxy=false#0

Screen cast
https://www.screencast.com/t/OCmEmk6zbM

Comment

// if end of buffer greater than live edge, don't load any fragment
// this could happen if live playlist intermittently slides in the past.
// level 1 loaded [182580161,182580167]
// level 1 loaded [182580162,182580169]
// Loading 182580168 of [182580162 ,182580169],level 1 ..
// Loading 182580169 of [182580162 ,182580169],level 1 ..
// level 1 loaded [182580162,182580168] <============= here we should have bufferEnd > end. in that case break to avoid reloading 182580168
// level 1 loaded [182580164,182580171]
//
// don't return null in case media not loaded yet (readystate === 0)

Code block [lines 4129-4131 of hls.js 0.7.9]
if (levelDetails.PTSKnown && bufferEnd > end && media && media.readyState) { return null; }

Log

blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > AVC:17 ms overlapping between fragments detected
logger.js:39 [log] > Parsed audio,PTS:[244.651,248.107],DTS:[244.651/248.107],nb:81,dropped:0
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > Video/PTS/DTS adjusted: 244678/244678,delta:-17 ms
logger.js:39 [log] > Parsed video,PTS:[244.678,248.098],DTS:[244.678/248.098],nb:103,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [4.021,248.098]
logger.js:39 [log] > latency/loading/parsing/append/kbps:42/210/30/23/40532
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > Loading key for 62 of [55 ,62],level 8
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > Loading 62 of [55 ,62],level 8, currentTime:221.872,bufferEnd:248.098
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 62 of [55 ,62],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 62 of [55 ,62],level 8, cc 1
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > main:discontinuity detected
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > manifest codec:mp4a.40.5,ADTS data:type:2,sampleingIndex:6[24000Hz],channelConfig:2
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > parsed codec:mp4a.40.5,rate:24000,nb channel:2
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > audio mp4 timescale :24000
logger.js:39 [log] > main track:audio,container:audio/mp4,codecs[level/parsed]=[mp4a.40.5/mp4a.40.5]
logger.js:39 [log] > main track:video,container:video/mp4,codecs[level/parsed]=[avc1.64001f/avc1.64001f]
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > AVC:248065 ms overlapping between fragments detected
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > Video/PTS/DTS adjusted: 248098/248098,delta:-248065 ms
logger.js:39 [log] > Parsed video,PTS:[248.098,3.904],DTS:[248.098/3.904],nb:114,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [4.021,248.107]
logger.js:39 [log] > latency/loading/parsing/append/kbps:24/215/55/41/40755
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3871 ms
logger.js:39 [log] > level 8 loaded [56,63],duration:31.452400000000004
logger.js:39 [log] > live playlist sliding:224.597
logger.js:39 [log] > Updating mediasource duration to 256.050
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3881 ms
logger.js:39 [log] > level 8 loaded [57,64],duration:31.425700000000006
logger.js:39 [log] > live playlist sliding:228.608
logger.js:39 [log] > Updating mediasource duration to 260.034
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3875 ms
logger.js:39 [log] > level 8 loaded [58,65],duration:31.399
logger.js:39 [log] > live playlist sliding:232.619
logger.js:39 [log] > Updating mediasource duration to 264.018
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3768 ms
logger.js:39 [log] > level 8 loaded [59,66],duration:31.372300000000003
logger.js:39 [log] > live playlist sliding:236.629
logger.js:39 [log] > Updating mediasource duration to 268.002
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3863 ms
logger.js:39 [log] > level 8 loaded [60,67],duration:31.345600000000005
logger.js:39 [log] > live playlist sliding:240.640
logger.js:39 [log] > Updating mediasource duration to 271.986
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3851 ms
logger.js:39 [log] > level 8 loaded [61,68],duration:31.318900000000006
logger.js:39 [log] > live playlist sliding:244.651
logger.js:39 [log] > Updating mediasource duration to 275.970
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3923 ms
logger.js:39 [log] > level 8 loaded [62,69],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:248.098
logger.js:39 [log] > Updating mediasource duration to 279.970
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3921 ms
logger.js:39 [log] > level 8 loaded [63,70],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:3.904
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3907 ms
logger.js:39 [log] > level 8 loaded [64,71],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:7.888
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3933 ms
logger.js:39 [log] > level 8 loaded [65,72],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:11.872
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3924 ms
logger.js:39 [log] > level 8 loaded [66,73],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:15.856
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3937 ms
logger.js:39 [log] > level 8 loaded [67,74],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:19.840
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3933 ms
logger.js:39 [log] > level 8 loaded [68,75],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:23.824
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3935 ms
logger.js:39 [log] > level 8 loaded [69,76],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:27.808
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3915 ms
logger.js:39 [log] > level 8 loaded [70,77],duration:31.872000000000007
logger.js:39 [log] > live playlist sliding:31.792
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3532 ms
logger.js:39 [log] > level 8 loaded [71,78],duration:28.688800000000004
logger.js:39 [log] > live playlist sliding:35.776
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3530 ms
logger.js:39 [log] > level 8 loaded [72,79],duration:28.6888
logger.js:39 [log] > live playlist sliding:39.760
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3534 ms
logger.js:39 [log] > level 8 loaded [73,80],duration:28.6888
logger.js:39 [log] > live playlist sliding:43.744
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3532 ms
logger.js:39 [log] > level 8 loaded [74,81],duration:28.6888
logger.js:39 [log] > live playlist sliding:47.728
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > same live playlist, reload twice faster
logger.js:39 [log] > live playlist, reload in 1739 ms
logger.js:39 [log] > level 8 loaded [74,81],duration:28.6888
logger.js:39 [log] > live playlist sliding:47.728
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3457 ms
logger.js:39 [log] > level 8 loaded [75,82],duration:28.688800000000008
logger.js:39 [log] > live playlist sliding:51.712
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3505 ms
logger.js:39 [log] > level 8 loaded [76,83],duration:28.688800000000008
logger.js:39 [log] > live playlist sliding:55.696
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3536 ms
logger.js:39 [log] > level 8 loaded [77,84],duration:28.6888
logger.js:39 [log] > live playlist sliding:59.680
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3536 ms
logger.js:39 [log] > level 8 loaded [78,85],duration:28.6888
logger.js:39 [log] > live playlist sliding:63.664
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3933 ms
logger.js:39 [log] > level 8 loaded [79,86],duration:31.898700000000005
logger.js:39 [log] > live playlist sliding:64.465
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3942 ms
logger.js:39 [log] > level 8 loaded [80,87],duration:31.925400000000003
logger.js:39 [log] > live playlist sliding:68.449
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3944 ms
logger.js:39 [log] > level 8 loaded [81,88],duration:31.9521
logger.js:39 [log] > live playlist sliding:72.433
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3948 ms
logger.js:39 [log] > level 8 loaded [82,89],duration:31.9788
logger.js:39 [log] > live playlist sliding:76.417
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3956 ms
logger.js:39 [log] > level 8 loaded [83,90],duration:32.0055
logger.js:39 [log] > live playlist sliding:80.401
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > same live playlist, reload twice faster
logger.js:39 [log] > live playlist, reload in 1660 ms
logger.js:39 [log] > level 8 loaded [84,90],duration:28.0215
logger.js:39 [log] > live playlist sliding:84.385
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3955 ms
logger.js:39 [log] > level 8 loaded [85,91],duration:28.0482
logger.js:39 [log] > live playlist sliding:88.369
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3707 ms
logger.js:39 [log] > level 8 loaded [86,92],duration:28.0749
logger.js:39 [log] > live playlist sliding:92.353
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3966 ms
logger.js:39 [log] > level 8 loaded [87,93],duration:28.0749
logger.js:39 [log] > live playlist sliding:96.363
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3927 ms
logger.js:39 [log] > level 8 loaded [89,95],duration:28.0749
logger.js:39 [log] > live playlist sliding:104.385
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3961 ms
logger.js:39 [log] > level 8 loaded [91,97],duration:28.0749
logger.js:39 [log] > live playlist sliding:112.406
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3963 ms
logger.js:39 [log] > level 8 loaded [92,98],duration:28.0749
logger.js:39 [log] > live playlist sliding:116.417
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3962 ms
logger.js:39 [log] > level 8 loaded [93,99],duration:28.0749
logger.js:39 [log] > live playlist sliding:120.428
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3952 ms
logger.js:39 [log] > level 8 loaded [94,100],duration:28.0749
logger.js:39 [log] > live playlist sliding:124.438
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3958 ms
logger.js:39 [log] > level 8 loaded [95,101],duration:28.0749
logger.js:39 [log] > live playlist sliding:128.449
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3961 ms
logger.js:39 [log] > level 8 loaded [96,102],duration:28.0749
logger.js:39 [log] > live playlist sliding:132.460
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3961 ms
logger.js:39 [log] > level 8 loaded [97,103],duration:28.0749
logger.js:39 [log] > live playlist sliding:136.470
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3962 ms
logger.js:39 [log] > level 8 loaded [98,104],duration:28.0749
logger.js:39 [log] > live playlist sliding:140.481
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3964 ms
logger.js:39 [log] > level 8 loaded [99,105],duration:28.0749
logger.js:39 [log] > live playlist sliding:144.492
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3955 ms
logger.js:39 [log] > level 8 loaded [100,106],duration:28.0749
logger.js:39 [log] > live playlist sliding:148.502
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3954 ms
logger.js:39 [log] > level 8 loaded [101,107],duration:28.0749
logger.js:39 [log] > live playlist sliding:152.513
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3961 ms
logger.js:39 [log] > level 8 loaded [102,108],duration:28.0749
logger.js:39 [log] > live playlist sliding:156.524
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3960 ms
logger.js:39 [log] > level 8 loaded [103,109],duration:28.0749
logger.js:39 [log] > live playlist sliding:160.535
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3960 ms
logger.js:39 [log] > level 8 loaded [104,110],duration:28.0749
logger.js:39 [log] > live playlist sliding:164.545
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3959 ms
logger.js:39 [log] > level 8 loaded [105,111],duration:28.0749
logger.js:39 [log] > live playlist sliding:168.556
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3960 ms
logger.js:39 [log] > level 8 loaded [106,112],duration:28.0749
logger.js:39 [log] > live playlist sliding:172.567
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3959 ms
logger.js:39 [log] > level 8 loaded [107,113],duration:28.0749
logger.js:39 [log] > live playlist sliding:176.577
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3960 ms
logger.js:39 [log] > level 8 loaded [108,114],duration:28.0749
logger.js:39 [log] > live playlist sliding:180.588
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3938 ms
logger.js:39 [log] > level 8 loaded [109,115],duration:28.0749
logger.js:39 [log] > live playlist sliding:184.599
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3956 ms
logger.js:39 [log] > level 8 loaded [110,116],duration:28.0749
logger.js:39 [log] > live playlist sliding:188.609
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3962 ms
logger.js:39 [log] > level 8 loaded [111,117],duration:28.0749
logger.js:39 [log] > live playlist sliding:192.620
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3946 ms
logger.js:39 [log] > level 8 loaded [112,118],duration:28.0749
logger.js:39 [log] > live playlist sliding:196.631
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3962 ms
logger.js:39 [log] > level 8 loaded [113,119],duration:28.0749
logger.js:39 [log] > live playlist sliding:200.642
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3962 ms
logger.js:39 [log] > level 8 loaded [114,120],duration:28.0749
logger.js:39 [log] > live playlist sliding:204.652
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3957 ms
logger.js:39 [log] > level 8 loaded [115,121],duration:28.0749
logger.js:39 [log] > live playlist sliding:208.663
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3961 ms
logger.js:39 [log] > level 8 loaded [116,122],duration:28.0749
logger.js:39 [log] > live playlist sliding:212.674
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3796 ms
logger.js:39 [log] > level 8 loaded [117,123],duration:28.0749
logger.js:39 [log] > live playlist sliding:216.684
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3957 ms
logger.js:39 [log] > level 8 loaded [118,124],duration:28.0749
logger.js:39 [log] > live playlist sliding:220.695
logger.js:39 [log] > Loading key for 124 of [118 ,124],level 8
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > Loading 124 of [118 ,124],level 8, currentTime:248.065,bufferEnd:248.107
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 124 of [118 ,124],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 124 of [118 ,124],level 8, cc 25
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > main:discontinuity detected
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > manifest codec:mp4a.40.5,ADTS data:type:2,sampleingIndex:6[24000Hz],channelConfig:2
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > parsed codec:mp4a.40.5,rate:24000,nb channel:2
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > audio mp4 timescale :24000
logger.js:39 [log] > main track:audio,container:audio/mp4,codecs[level/parsed]=[mp4a.40.5/mp4a.40.5]
logger.js:39 [log] > main track:video,container:video/mp4,codecs[level/parsed]=[avc1.64001f/avc1.64001f]
logger.js:39 [log] > Parsed audio,PTS:[244.759,3562.989],DTS:[244.759/3562.989],nb:77771,dropped:0
logger.js:39 [log] > Parsed video,PTS:[3558.989,3562.993],DTS:[3558.989/3562.993],nb:120,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [4.021,248.165][3558.989,3562.989]
logger.js:39 [log] > latency/loading/parsing/append/kbps:473/242/1487/293/5732
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3937 ms
logger.js:39 [log] > level 8 loaded [119,125],duration:28.0749
logger.js:39 [log] > live playlist sliding:224.706
logger.js:39 [log] > SN just loaded, load next one: 125
logger.js:39 [log] > Loading key for 125 of [119 ,125],level 8
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > SN just loaded, load next one: 125
logger.js:39 [log] > Loading 125 of [119 ,125],level 8, currentTime:249.323,bufferEnd:249.323
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 125 of [119 ,125],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 125 of [119 ,125],level 8, cc 25
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
logger.js:39 [log] > Parsed audio,PTS:[3562.989,3566.999],DTS:[3562.989/3566.999],nb:94,dropped:0
logger.js:39 [log] > Parsed video,PTS:[3562.993,3567.030],DTS:[3562.993/3567.030],nb:121,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [4.021,248.165][3558.989,3566.999]
logger.js:39 [log] > latency/loading/parsing/append/kbps:43/257/79/43/34267
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > Loading key for 124 of [119 ,125],level 8
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > Loading 124 of [119 ,125],level 8, currentTime:249.827,bufferEnd:249.827
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 124 of [119 ,125],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 124 of [119 ,125],level 8, cc 25
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
logger.js:39 [log] > Parsed audio,PTS:[244.759,3562.989],DTS:[244.759/3562.989],nb:77771,dropped:0
logger.js:39 [log] > Parsed video,PTS:[3558.989,3562.993],DTS:[3558.989/3562.993],nb:120,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > loading playlist for level 8
logger.js:39 [log] > live playlist, reload in 3948 ms
logger.js:39 [log] > level 8 loaded [120,126],duration:28.0749
logger.js:39 [log] > live playlist sliding:228.716
logger.js:39 [log] > main buffered : [77.355,248.165][3558.989,3562.993][3565.128,3566.999]
logger.js:39 [log] > latency/loading/parsing/append/kbps:101/34/1411/2009/4023
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > SN just loaded, load next one: 125
logger.js:39 [log] > Loading key for 125 of [120 ,126],level 8
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > SN just loaded, load next one: 125
logger.js:39 [log] > Loading 125 of [120 ,126],level 8, currentTime:251.038,bufferEnd:251.038
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 125 of [120 ,126],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 125 of [120 ,126],level 8, cc 25
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
logger.js:39 [log] > Parsed audio,PTS:[3562.989,3566.999],DTS:[3562.989/3566.999],nb:94,dropped:0
logger.js:39 [log] > Parsed video,PTS:[3562.993,3567.030],DTS:[3562.993/3567.030],nb:121,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED
logger.js:39 [log] > main buffered : [77.355,248.165][3558.989,3566.999]
logger.js:39 [log] > latency/loading/parsing/append/kbps:114/34/62/22/62193
logger.js:39 [log] > main stream:PARSED->IDLE
logger.js:39 [log] > Loading key for 124 of [120 ,126],level 8
logger.js:39 [log] > main stream:IDLE->KEY_LOADING
logger.js:39 [log] > main stream:KEY_LOADING->IDLE
logger.js:39 [log] > Loading 124 of [120 ,126],level 8, currentTime:251.038,bufferEnd:251.038
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 124 of [120 ,126],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING

@mangui
Copy link
Member

mangui commented May 31, 2017

there is an issue parsing the fragment below. this is completely messing up the end duration in the above code snippet.

logger.js:39 [log] > Loading 62 of [55 ,62],level 8, currentTime:221.872,bufferEnd:248.098
logger.js:39 [log] > main stream:IDLE->FRAG_LOADING
logger.js:39 [log] > Loaded 62 of [55 ,62],level 8
logger.js:39 [log] > main stream:FRAG_LOADING->PARSING
logger.js:39 [log] > Parsing 62 of [55 ,62],level 8, cc 1
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > WebCrypto AES decrypt
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > main:discontinuity detected
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > manifest codec:mp4a.40.5,ADTS data:type:2,sampleingIndex:6[24000Hz],channelConfig:2
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > parsed codec:mp4a.40.5,rate:24000,nb channel:2
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > audio mp4 timescale :24000
logger.js:39 [log] > main track:audio,container:audio/mp4,codecs[level/parsed]=[mp4a.40.5/mp4a.40.5]
logger.js:39 [log] > main track:video,container:video/mp4,codecs[level/parsed]=[avc1.64001f/avc1.64001f]
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > AVC:248065 ms overlapping between fragments detected
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > Video/PTS/DTS adjusted: 248098/248098,delta:-248065 ms
logger.js:39 [log] > Parsed video,PTS:[248.098,3.904],DTS:[248.098/3.904],nb:114,dropped:0
logger.js:39 [log] > main stream:PARSING->PARSED

I
end PTS is smaller than start PTS !
I see that continuity counter is set to 1, meaning that there are discontinuities in this stream.
However as the log is truncated I can't figure when this discontinuity occurred.
as I see some logs about overlapping between fragments, it might happen that there is a missing discontinuity marker before this fragment.

what would be great is to have a playlist extract when that happens.

@mdtjrfg
Copy link

mdtjrfg commented Jun 1, 2017

@mangui Attached are three playlist files requested in sequence. The DISCONTINUITY and DISCONTINUITY-SEQUENCE tags are present. As mentioned before this issue is occurring often during content transitions, specifically in the ABC Television Uplynk streams, here.

Some quick research yielded this ExoPlayer ticket, which potentially seems related. I merely glanced at what the spec stipulates, but I don't see any removal of DISCONTINUITY tags from successive playlist requests.

Please let us know what else you might possibly need. In the meantime we are going to move forward and document other manifestations of the same (visual) issue.

Many thanks for your assistance.

j.m3u~3.txt
j.m3u~2.txt
j.m3u~1.txt

@mangui
Copy link
Member

mangui commented Jun 3, 2017

ok i think i understand what is going on.
there is a discontinuity marker, and hls.js loads a new fragment
on this fragment, audio and video samples are not aligned timestamp-wise (audio is still using the timestamp range as before the discontinuity, however video timestamp are reset)
this gap between audio and video timestamp (240s gap in your case) is the only thing that could explain the following traces (with video start PTS bigger than video end PTS)

blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > AVC:248065 ms overlapping between fragments detected
blob:http://localhost/529e2d9c-4ed2-48c9-9159-b12c8dc56ea5:4863 [log] > Video/PTS/DTS adjusted: 248098/248098,delta:-248065 ms
logger.js:39 [log] > Parsed video,PTS:[248.098,3.904],DTS:[248.098/3.904],nb:114,dropped:0

@mdtjrfg
Copy link

mdtjrfg commented Jun 5, 2017

@mangui We will check ourselves but do you know if this discrepancy violates the spec? The pushback we're going to get is that this works in Safari in relation to that question.

@mangui
Copy link
Member

mangui commented Jun 8, 2017

If my assumption is correct, yes that should violate the spec. but Safari might be more robust to handle that cases.
I would be glad to enhance hls.js robustness but I would need a stream capture highlighting the issue.

@frankpaolino
Copy link

frankpaolino commented Jun 8, 2017 via email

@mdtjrfg
Copy link

mdtjrfg commented Jun 22, 2017

@mangui, We were able to capture a representation of the issue using a perl script that meets the primary characteristics. That script is below in code.

The script we're using doesn't insert DISCONTINUITY tags however, thus the issue in the capture could merely be hls.js reacting to the absence of the tag.

That said, the issue as represented in the captured stream behaves exactly like the issue in the actual live stream, aside from the absence of the discontinuity tags and some additional and different logging.

Here's the stream, which fails 100% of the time @ 6:59:

http://projects.mediadev.edgesuite.net/customers/abctv/streamcapture/j003/manifest.m3u8

Let us know what you're findings are. In the meantime we have engaged Uplynk VDMS (Verizon) and asked for assistance producing a capture of the stream with the DISCONTINUITY tags inserted.

    #!/usr/bin/perl

use Digest::MD5 qw(md5 md5_hex md5_base64);
### manifest directory should exist prior to running
if (!-d "./manifest"){
	print "Error: Please create \"manifest\" directory in this location before running\n";
	exit(1);
}
if (!-d "./tsdump"){
	print "Error: Please create \"tsdump\" directory in this location before running\n";
	exit(1);
}
### Clean up previous run
system ("rm -f ./manifest/*");
system ("rm -f ./tsdump/*");
system ("rm -f ./*enc");
open MOUTFILE, ">./manifest/manifest.m3u8" or die $!;
open OUTFILE, ">./manifest/sub.m3u8" or die $!;
$manifest = $ARGV[0];
$total = $ARGV[1];
print "\nAssuming that you are pulling a DISNEY stream at 992x558 resolution - Bandwidth 1512243.\nPlease edit MOUTFILE section in code if different\n\n\n";
if (!$manifest) {
	print "\n";
	print "Please provide Manifest URL when running script.\n";
	print "Usage: $0 \"Streaming URL (ex: http://domain.com/manifest.m3u8)\" \"Optional: Total number of cycles (ex: 200)\"\n";
	print "Example: $0 \"http://www.domain.com/streaming/manifest.m3u8\" \"100\"\n";
	print "\n";
	exit(1);
}
#$manifest = "http://content.uplynk.com/channel/412b0949b4ad495ebdbdbc10a161309c.m3u8?exp=1511041781&ct=c&cid=412b0949b4ad495ebdbdbc10a161309c&iph=493335c5aa3832a85e9ac65738862fc525f612873e2dee9d31d57b656e4e5205&rays=jihgfedcb&euid=null_000_1_001_live_01-06-00_NA&cdn=ec&cdn=ec&stgcfg=datg&pp2ip=0&delay=0&sig=cb06fed4f203b94384cede6ce65d26ece032a502edb21e93a09e5c342f9734cf";
print MOUTFILE qq|#EXTM3U
#EXT-X-VERSION:6
#EXT-UPLYNK-LIVE
#EXT-X-START:TIME-OFFSET=0.00
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="unspecified",LANGUAGE="en",AUTOSELECT=YES,DEFAULT=YES
#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,NAME="English",AUTOSELECT=YES,DEFAULT=YES,LANGUAGE="en",INSTREAM-ID="CC1",GROUP-ID="ccs"
#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,NAME="English",AUTOSELECT=YES,DEFAULT=YES,LANGUAGE="en",INSTREAM-ID="CC3",GROUP-ID="ccs"
#UPLYNK-MEDIA0:992x558x30,main-31,2x48000
#EXT-X-STREAM-INF:RESOLUTION=995x558,BANDWIDTH=1512243,CODECS="mp4a.40.5,avc1.4d001f",FRAME-RATE=30.000,AUDIO="aac",CLOSED-CAPTIONS="ccs",AVERAGE-BANDWIDTH=998718
sub.m3u8
|;
$SIG{INT} = \&complete_manifest;
$SIG{TERM} = \&complete_manifest;
$SIG{KILL} = \&complete_manifest;
if (!$total) {$total = 200; print "Total (Number of cycles) not given via command line, using $total.\n";}
### Create Manifest header: Edit this if you want to change RESOLUTION, BANDWIDTH, ETC
print OUTFILE qq|#EXTM3U
#EXT-X-VERSION:6
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:8
#UPLYNK-SEGMENT: f31981537cec4a419202f7266935076b,0000004A,segment
#EXT-X-PROGRAM-DATE-TIME:2017-02-23T15:06:06.880000+00:00
|;
### Get Manifest X number of times, waiting 5 sec between each pull
for ($i=1;$i<$total;$i++) {
	### Get Master Manifest
	@output = `curl -v \"$manifest\" 2>&1`;
	### Loop through Manifest
	foreach $line (@output) {
		### Remove new lines and CRs
		chomp ($line);
		$line=~s/\r//g;
		chomp ($line);
		### Look for encryption information and save it for later
		if ($line=~/EXT-X-KEY\:METHOD\=AES-128,URI\=\"(.*)\",IV\=0x(.*)$/) {
			$key = $1;
			$iv = $2;
		}
		### Save EXTINF info (not using right now --- Static EXTINF Below)
		if ($line=~/EXTINF:.*/) {
			$ext = $line;
		}
		# print "line: $line";
		### Look for .ts file and save it
		if ($line=~/.*\/(\w+\.ts)\?.*/) {
			#$$ts = $1;
			print "Processing .ts $ts...\n";
			$url = $line;
			### Avoid duplicate filenames --- ADS!
			$ts = md5_hex($line);
			print "TS is $ts\n";
			### Get encrypted .ts using Curl
			system("curl -o ./tsdump/$ts-enc \"$url\" 2>/dev/null 1>/dev/null");
			### Get keyfile using Curl
			system("curl -o ./keyfile \"$key\" 2>/dev/null 1>/dev/null");
			### Convert keyfile to something usable
			$keyfile2 = `cat ./keyfile | hexdump -e '16/1 \"%02x\"'`;
			### Decrypt .ts and save to "manifest" directory
			$ouput = `openssl aes-128-cbc -d -K \"$keyfile2\" -iv \"$iv\" -nosalt -in ./tsdump/$ts-enc -out ./manifest/$ts`;
			#print "Output from openssl : $output\n";
			### Only work on .ts we haven't already seen before
			if (!grep( /^$ts$/, @seg ) ) {
				$j++;
				### Rename decrypted manifest to incremental one for easier playback via VOD
				system("mv ./manifest/$ts ./manifest/sequence$j.ts");
				print "Renaming $ts to sequence$j.ts...\n";
				push @seg, $ts;
				### Note: Notice STATIC EXTINF. If you want to use original EXTINF, un-comment next line and comment one after it.
				print "Adding sequence$j.ts to manifest...\n";
				#print OUTFILE "$ext\nsequence$j.ts\n";
				print OUTFILE "#EXTINF:4.0,\nsequence$j.ts\n";
			}
		}
	}
	### 5 seconds sleep between each manifest pull
	sleep 5;
}
### Once script is finished, write ENDLIST to manifest
print OUTFILE "#EXT-X-ENDLIST\n";
close(OUTFILE);
exit(0);
### Handle CTRL-C or hard KILL by writing ENDLIST and exiting
sub complete_manifest {
print "Finalizing Playlist...\n";
print OUTFILE "#EXT-X-ENDLIST\n";
close(OUTFILE);
die "Caught a kill signal $!";
 }

@mangui
Copy link
Member

mangui commented Jun 22, 2017

perfect, will check tonight

@mdtjrfg
Copy link

mdtjrfg commented Jun 22, 2017

@mangui Many thanks for your assistance!

mangui added a commit that referenced this issue Jun 23, 2017
…e of gap

if delta between expected timestamp and received timestamp is bigger than 10s, reset initPTS.
this helps overcoming issues in streams in which DISCONTINUITY are sometimes missing

related to #1172
@mangui
Copy link
Member

mangui commented Jun 23, 2017

ok there is definitely discontinuities in timestamps with your playlist.
I added a check that recompute initPTS in case of inconsistency. this acts a bit like a DISCONTINUITY (but without generating a new init segment)
this will add robustness and hls.js will be able to play it.
But the playlist is not compliant with the spec

@mdtjrfg
Copy link

mdtjrfg commented Jun 24, 2017

@mangui thanks again. I patched our current build using 0.7.9 with the change but I'm not seeing an improvement. You can take a look here if you like.

Can you let me know which portion of the spec it is that you believe the playlist is violating? The relevant sections seemed to be:

Section 3: https://tools.ietf.org/html/draft-pantos-http-live-streaming-21#section-3
Section 6.2.1: https://tools.ietf.org/html/draft-pantos-http-live-streaming-21#section-6.2.1
Section 6.3.3: https://tools.ietf.org/html/draft-pantos-http-live-streaming-21#section-6.3.3

All of those are referenced under the discontinuity section:

https://tools.ietf.org/html/draft-pantos-http-live-streaming-21#section-4.3.2.3

I don't see a clear indication of the expectation around timestamps therein. If there is, we can take this to Verizon and ask them to fix the instances under which the timestamps diverge.

Thank you!

@mangui
Copy link
Member

mangui commented Jun 24, 2017

https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-3

Each Media Segment MUST carry the continuation of the encoded
   bitstream from the end of the segment with the previous Media
   Sequence Number, where values in a series such as timestamps and
   Continuity Counters MUST continue uninterrupted.  The only exceptions
   are the first Media Segment ever to appear in a Media Playlist, and
   Media Segments which are explicitly signaled as discontinuities
   (Section 4.3.2.3).  Unmarked media discontinuities can trigger
   playback errors.

and there are CORS issue on your link
image

@mdtjrfg
Copy link

mdtjrfg commented Jun 25, 2017

@mangui Thank you. I have to be honest - I agree with you that it should violate the spec, but I think that section can be interpreted such that the timestamps can diverge provided the discontinuity is present and the timestamps are received in an uninterrupted fashion. I suppose it depends upon the definition of "uninterrupted" in this context. Channeling my inner Bill Clinton ;)

We'll ask internally about the spec with a resource who knows it well. Apologies regarding the CORS issues. Unfortunately this is the nature of ABCTV's environment, and we work around those issues locally in a couple of different ways (Charles and a websocket that serves as a proxy for the CORS).

In the meantime, if you want to work around the CORS issue, you can emulate the attached Charles rewrite. Note that we have all had trouble importing the .chls, thus we have had to input it manually. I've added screen shots for that.

abctv.cors.txt
cors-0
cors-1

Thanks again!

@mangui
Copy link
Member

mangui commented Jun 27, 2017

in your case there is a timestamp discontinuity without #EXT-X-DISCONTINUITY tag

@mdtjrfg
Copy link

mdtjrfg commented Jun 28, 2017

@mangui The reason the discontinuity is missing is because the script we use to capture the live stream doesn't insert them. We're trying to get you a better capture including the discontinuity tags.

@mdtjrfg
Copy link

mdtjrfg commented Jul 13, 2017

@mangui We are having some trouble procuring a capture that retains all of the HLS characteristics and surfaces the issue. Would it be possible for you to try the following with this sample page and see if you are able to reproduce the issue?

  1. Open http://test.abc.go.com/watch-live?amp-debug=true live stream in chrome
  2. Allow live to play for a couple minutes
  3. Open network tab in chrome developer tools
  4. Click on “No throttling” dropdown and select Regular 2G
  5. Wait for hls.js to lower the stream quality (video becomes blurry)

This issue is slightly different than the one we have been trying to capture in that it is triggered exclusively by a bitrate switch, but appears to run through the same routine as most of the logging is identical.

Let us know if you have any trouble with the sample page.

Thank you!

mangui added a commit that referenced this issue Jul 14, 2017
…r on level switch with unknown PTS

this helps keeping levels in sync with PTS and avoid setting up a wrong start offset, especially when level switch happens on a discontinuity

related to #1172
mangui added a commit that referenced this issue Jul 14, 2017
related to #1172
@mangui
Copy link
Member

mangui commented Jul 14, 2017

@mdtjrfg I spotted an issue while testing your stream : while switching to a new level on a discontinuity: if we load straight away a fragment which does not use the same timebase, the playlist start offset is wrong.
i commited a fix, you can use the latest dist. please let me know the outcome on your side.

@mdtjrfg
Copy link

mdtjrfg commented Jul 15, 2017

@mangui Thanks! I have been unable to reproduce the discontinuity use case recently and with your latest dist. We will continue to test and determine if it is still reproducible at some rate.

The bitrate switch case is still consistently reproducible however, at a fairly close to 100% rate, as defined by the following steps:

  1. Open http://test.abc.go.com/watch-live?amp-debug=true live stream in chrome
  2. Allow live to play for a couple minutes
  3. Open network tab in chrome developer tools
  4. Click on “No throttling” dropdown and select Regular 2G
  5. Wait for hls.js to lower the stream quality (video becomes blurry)

Here's a screen cast that depicts the issue. We see roughly the same output as is seen with the discontinuity case.

https://www.screencast.com/t/vK0JOANt

Could this case be addressed by your change if leveraged outside of the discontinuity case?

@mangui
Copy link
Member

mangui commented Jul 15, 2017

interesting.
it is stalling because when switching to level 1 there is an issue computing playlist sliding
image
computed sliding: 8 whereas it should be 500ish
SN 134 has been successfully loaded on level 1 a couple of seconds before, so hls.js should be able to compute PTS information for range [133,139]

there should be something wrong in https://github.com/video-dev/hls.js/blob/master/src/helper/level-helper.js#L9

in theory hls.js should be able to find overlapping fragments here:
https://github.com/video-dev/hls.js/blob/master/src/helper/level-helper.js#L23-L38
and then recompute PTS info for new playlist here
https://github.com/video-dev/hls.js/blob/master/src/helper/level-helper.js#L49

if it was not able to find an overlapping frag with PTS info, then this should be either because we didnt update PTS info (should be done here:

var drift = LevelHelper.updateFragPTSDTS(level.details,frag,data.startPTS,data.endPTS,data.startDTS,data.endDTS),
maybe we are updating on the wrong level?) or because this PTS info has been erased.

i will add more logs to understand what is going on.

mangui added a commit that referenced this issue Jul 15, 2017
in case a live playlist has been refreshed between frag loading and updateFragPTSDTS(), fragments array will not contain the initial frag object.
As updateFragPTSDTS() is doing the PTS update on the original frag object, we need to update fragments array with this original frag, so that PTS info could be propagated in the playlist.
this to avoid invalid sliding computation

related to #1172
mangui added a commit that referenced this issue Jul 15, 2017
related to #1172
@mangui
Copy link
Member

mangui commented Jul 15, 2017

ok plz recheck with latest diff, I found an issue that should affect a bunch of live playlists ...

basically when switching to a new rendition, if it happens that the playlist gets refreshed before the end of the parsing of the first fragment at this new rendition, then sliding computation will be incorrect.

scenario is:

switching to level 1
level 1 loaded [100,102] (unknown sliding)
loading 102 of level 1
level 1 loaded [101,103] (unknown sliding)
loaded 102 of level 1
=> here frag is loaded as expected, with the right timestamp, but we mess up with sliding computation
level 1 loaded [102,104] (wrong sliding computed)

once sliding is wrong, timestamps are messed up, and it ends up in playback stalling in low buffer

@mdtjrfg
Copy link

mdtjrfg commented Jul 18, 2017

@mangui Our testing indicates that this change addresses the issue. For the time being we are using the dist. What steps are required on your end to apply this fix to an official release?

Thanks again for your assistance, it is greatly appreciated.

@mangui
Copy link
Member

mangui commented Jul 18, 2017

@mangui
Copy link
Member

mangui commented Jul 18, 2017

looks like Vevo is already using 0.7.11
https://twitter.com/mangui_79/status/887399431087112192

@mdtjrfg
Copy link

mdtjrfg commented Aug 3, 2017

@mangui - @vitalibozhko noted anecdotally that this issue is more reproducible when both a level switch and a discontinuity are present concurrently. My understanding is that in or outside those conditions this issue is relatively difficult to reproduce.

@vitalibozhko
Copy link
Contributor

Here are some more logs
10_08_2017 Chrome Stuck Live.txt
14_08_2017 Chrome Stuck Live.txt

We can see two scenarios from these logs:

  1. Corrupted sliding on both level switch & discontinuity (e.g. search for "Parsing 101 of [97 ,103],level 1, cc 1" in logs 14_08...)
  2. Corrupted sliding on level switch without discontinuity (e.g. search for "Parsed video,PTS:[317.362,321.366],DTS:[317.362/321.366],nb:120,dropped:0" in logs 10_08...)

We're trying to figure out what's wrong in each individual scenario but unfortunately we still don't have a solid understanding of the whole picture of startPTS management across demuxer/remuxer and stream controller.

@frankpaolino
Copy link

@mangui - We (@vitalibozhko and we) are stuck on this one right now. Our QA with lesser connections can reproduce easily, but many others cannot. Do you have any guidance or suggestion for how we can dig further into this? Thanks

mangui added a commit that referenced this issue Aug 19, 2017
it was introduced to overcome a stream capture limitation in #1172
related to #1265
mangui added a commit that referenced this issue Aug 22, 2017
Date() of the beginning of the first fragment

related to #1172
@mangui
Copy link
Member

mangui commented Aug 22, 2017

on your first scenario : both level switch + discontinuity : hls.js cannot compute the sliding. we would need to use PROGRAM DATE TIME info as a time reference to sync the playlist.
this would require adding a new function in level-helper to compute playlist sliding using date-time info (as a fallback mechanism):

if playlist A sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM
and if playlist B first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM
then we can deduce that playlist B sliding is 1000+8 = 1008s

this logic should be added here, only for live playlist for which we still have newDetails.PTSKnown == false

I just pushed some code to expose the date of each level. it will simplify the computation.

@mdtjrfg
Copy link

mdtjrfg commented Aug 22, 2017

@mangui Thank you, we'll give this a shot. Note that there was some confusion on the ABCTV end in which the original issue you addressed wasn't working because of a reference to the wrong version of the hls.js dist. That is working on their end now.

@mangui
Copy link
Member

mangui commented Aug 22, 2017

ok then I guess now they should only face issue 1 (level switch + discontinuity)
which should be pretty hard to repro.

@mdtjrfg
Copy link

mdtjrfg commented Aug 23, 2017

@mangui That is correct. Thank you.

@mdtjrfg
Copy link

mdtjrfg commented Aug 28, 2017

@mangui Is b1bd73e and the related addition of alignDiscontinuities intended to address the issue described in this ticket, or is it only impactful exclusively when the discontinuities can be aligned using fragment data? I'm seeing a different issue now, wherein in most cases PTSKnown is true but the playback is still stalled when throttling. I thought we had a direction on our end regarding programDateTime but at a minimum the criteria for applying it has changed, and I'm not yet sure if it's applicable after these changes.

@mangui
Copy link
Member

mangui commented Aug 28, 2017

b1bd73e helps on level switch / discontinuity when there are overlapping continuity ranges between two rendition, which was the case in your scenario 1.
see below : you have cc 1 in both level 0 and 1

hls_c.min.js:1 [log] > level 0 loaded [95,101],duration:28.0198,frags:{sn: 95, cc: 0}{sn: 96, cc: 0}{sn: 97, cc: 1}{sn: 98, cc: 1}{sn: 99, cc: 1}{sn: 100, cc: 1}{sn: 101, cc: 1}

hls_c.min.js:1 [log] > level 1 loaded [97,103],duration:28.0749,frags:{sn: 97, cc: 1}{sn: 98, cc: 1}{sn: 99, cc: 1}{sn: 100, cc: 1}{sn: 101, cc: 1}{sn: 102, cc: 1}{sn: 103, cc: 1}

this should address most of the issues.
if you don't have overlapping cc (for example if you loose network long enough) then you would need the programDateTime

mangui added a commit that referenced this issue Aug 29, 2017
@mdtjrfg
Copy link

mdtjrfg commented Aug 29, 2017

@mangui Thank you for implementing the changes. I had gotten as far as the sliding calculation, however due to my unfamiliarity with the codebase, hadn't yet advanced to adjusting the fragment values. This confirms at least that my thinking was correct using the changes in b1bd73e as a guide, and I am becoming more familiar with project architecture and the raw code. I stashed my changes in a local branch.

Unfortunately when throttled at "Regular 3G" on a Nexus 6 with Android 7.0, the issue is still present and as bad as it's ever been. I'll continue looking into it along with you, and thank you for your time. Logs are attached of an instance in which the issue occurred and recovered over different time frames.

logs-2.txt
logs-1.txt

@mdtjrfg
Copy link

mdtjrfg commented Aug 29, 2017

@mangui These changes seem to be more impactful but I do still encounter the issue. Attached logs and screen shots show two different cases: logs-3 / ptsadjustment-3 in which the PTS diverges significantly prior to the issue occurring, and logs-4 / ptsadjustment-4 in which the PTS ends up as NaN; noting that this particular case is isolated in alignDiscontinuities and not handled.

Will continue to dig using newly available info on my end.

ptsadjustment-4

[logs-4.txt](https://github.com/video-dev/hls.js/files/1261975/logs-4.txt)

ptsadjustment-3

mangui added a commit that referenced this issue Aug 30, 2017
@mangui
Copy link
Member

mangui commented Aug 30, 2017

I added one more check so that it could use the new PDT fallback logic in NaN case.
but it is weird to get completely different cc ranges on level switch.

75 of [73 ,80],level 0, cc 3
81 of [74 ,81],level 3, cc 14
81 of [74 ,81],level 0, cc 9

@mdtjrfg
Copy link

mdtjrfg commented Aug 30, 2017

@mangui It appears as if the NaN case that you added the check for is different than the one I am running into; that appears to be the primary source of the stalling. I am seeing a level (in this case level 2) with an array of fragments that all have NaN start values. The strange thing is that I don't ever see the fragments for level 2 being adjusted, yet they still have the NaN values. I added extra logging to track every call to adjustPTS. Here is the filtered console with some extra logging I added:

fltered-console

I then encounter successive cases in which PTSKnown is true, and thus the sliding / fragment adjustments are skipped. I see a level that has its fragments adjusted and its start values are valid (in this case level 0). That looks like this:

level-0-frag

Followed by another level load (level 2 referred to earlier) that looks like this:

level-2-frags

So the question we need to answer is where these fragments are being seeded with NaN start values. I'll continue to investigate.

@mdtjrfg
Copy link

mdtjrfg commented Aug 31, 2017

@mangui It seems that the aforementioned NaN issue could be happening in relation to code added for the scenario 1 use case. See the following three screen shots:

This screen shot represents fragment metadata at the point that the fragment object is populated in parseLevelPlaylist and are initially valid. The second set of logs after the line referencing the CC increase reflects the values after modification in adjustPTS, and are also valid.
level-2-population

This screen shot represents fragment metadata at the point that the fragment object is populated in parseLevelPlaylist and are initially valid. The second set of logs after the line referencing the CC increase reflects the values after modification in adjustPTS, and have a start value of NaN.
level-3-population

This screen shot represents the fragment array produced by adjustPTS in the previous screen shot.
level-3-frags

This screen shot represents the "last level" (level 2) when it is referenced through alignDiscontinuities with a value of true for PTSKnown, and enters an else case I added for logging purposes.
level-3-object

I will continue to try and determine what is causing the NaN value, but this information at least seems to indicate the general location within the source in this case was level 2 / level 3 and he scenario 1 use case.

Thanks again for your help!

mangui added a commit that referenced this issue Aug 31, 2017
this was messing up frag.endPTS computation. and propagating NaN values

related to #1172
@mangui
Copy link
Member

mangui commented Aug 31, 2017

playlist-loader produces frag.start and frag.duration
then once PTS info are available, frag.startPTS and frag.endPTS could enrich frag metadata, but frag.end is never defined
as it was not defined, updatePTS was also messing up frag.endPTS
which is used later on ... this was propagating NaN

worth rechecking with new pushed commit. thanks for your patience 🥇

@mdtjrfg
Copy link

mdtjrfg commented Sep 1, 2017

@mangui, Thus far testing seems to indicate that your latest change addresses the issue. I am seeing the same logging sequence, but absent the NaN values and presence of the stalling. As of now I have not reproduced either of the NaN related issues, when a discontinuity throws off the fragment processing, I see fast recovery. I'll continue testing and report back with further results.

@mangui
Copy link
Member

mangui commented Sep 1, 2017

\o/ keep us posted

@vitalibozhko
Copy link
Contributor

@mangui we don't see the issue happening anymore, thank you very much for your help. Is it possible to make a 0.8.2 release anytime soon?

@jeh993
Copy link

jeh993 commented Feb 8, 2018

Environment
[ x] The stream has correct Access-Control-Allow-Origin headers (CORS)
[ x] There are no network errors such as 404s in the browser console when trying to play the stream
[x ] The issue occurs in the latest reference client on http://video-dev.github.io/hls.js/demo and not just on my page

Steps to reproduce

  1. Click the link below to open HLS JS demo page with Live HLS stream:
    http://streambox.fr/mse/hls.js-0.8.4/demo/?src=http%3A%2F%2Fsyd.foxbat.live%2Fyatk2506v%2Fmaster.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined
  2. The video is a 30-second loop with a discontinuity (including tag) every 30 seconds. If there is rendition change before the first discontinuity, it works as expected.
  3. After parsing the first discontinuity, change the quality of the video. Any rendition changes after the first discontinuity stop the player from requesting fragments. After some time, the player may recover.

Thanks for your help!

Expected behavior
Player should request new fragments after updates to the manifest

Actual behavior
The player stops requesting fragments. After some time it may recover.

Console output

[log] > main stream:FRAG_LOADING->PARSING
logger.js:37 [log] > Parsing 44 of [40 ,44],level 4, cc 8
logger.js:37 [log] > Parsed audio,PTS:[264.734,270.750],DTS:[264.734/270.750],nb:564,dropped:0
logger.js:37 [log] > Parsed video,PTS:[264.798,270.804],DTS:[264.731/270.737],nb:180,dropped:0
logger.js:37 [log] > main stream:PARSING->PARSED
logger.js:37 [log] > main buffered : [6.008,84.216][96.265,114.281][126.328,138.338][150.473,270.737]
logger.js:37 [log] > latency/loading/parsing/append/kbps:69/8/21/5/70602
logger.js:37 [log] > main stream:PARSED->IDLE
logger.js:37 [log] > set loadLevel:2
logger.js:37 [log] > switching to level 2
logger.js:37 [log] > loading playlist for level 2
logger.js:37 [log] > main stream:IDLE->WAITING_LEVEL
logger.js:37 [log] > main stream:WAITING_LEVEL->IDLE
logger.js:37 [log] > main stream:IDLE->WAITING_LEVEL
logger.js:37 [log] > main stream:WAITING_LEVEL->IDLE
logger.js:37 [log] > main stream:IDLE->WAITING_LEVEL
logger.js:37 [log] > main stream:WAITING_LEVEL->IDLE
logger.js:37 [log] > live playlist, reload in 5441 ms
logger.js:37 [log] > level 2 loaded [41,45],duration:30.03
logger.js:37 [log] > live playlist - outdated PTS, unknown sliding
logger.js:37 [log] > No frag in previous level to align on
logger.js:37 [log] > live playlist, switching playlist, unknown, load middle frag : 44
logger.js:37 [log] > Loading 44 of [41 ,45],level 2, currentTime:241.424,bufferEnd:270.737
logger.js:37 [log] > main stream:IDLE->FRAG_LOADING
?src=http%3A%2F%2Fsyd.foxbat.live%2Fyatk2506v%2Fmaster.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined:370 parsing level duration :216us,count:39
logger.js:37 [log] > Loaded  44 of [41 ,45],level 2
logger.js:37 [log] > main stream:FRAG_LOADING->PARSING
logger.js:37 [log] > Parsing 44 of [41 ,45],level 2, cc 0 
logger.js:37 [log] > main:discontinuity detected
logger.js:37 [log] > main:switch detected
blob:http://streambox.fr/2335b399-2779-439a-85a7-41a9f920d019:516 [log] > manifest codec:mp4a.40.2,ADTS data:type:2,sampleingIndex:0[96000Hz],channelConfig:2
blob:http://streambox.fr/2335b399-2779-439a-85a7-41a9f920d019:516 [log] > parsed codec:mp4a.40.5,rate:96000,nb channel:2
blob:http://streambox.fr/2335b399-2779-439a-85a7-41a9f920d019:516 [log] > audio sampling rate : 96000
logger.js:37 [log] > InitPTS for cc:0 found from video track:666544
logger.js:37 [log] > main track:audio,container:audio/mp4,codecs[level/parsed]=[mp4a.40.2/mp4a.40.5]
logger.js:37 [log] > main track:video,container:video/mp4,codecs[level/parsed]=[avc1.4d0028/avc1.4d4028]
logger.js:37 [log] > Parsed audio,PTS:[18.018,24.034],DTS:[18.018/24.034],nb:564,dropped:0
logger.js:37 [log] > Parsed video,PTS:[18.085,24.091],DTS:[18.018/24.024],nb:180,dropped:0
logger.js:37 [log] > main stream:PARSING->PARSED
logger.js:37 [log] > main buffered : [6.008,84.216][96.265,114.281][126.328,138.338][150.473,270.737]
logger.js:37 [log] > latency/loading/parsing/append/kbps:155/9/25/4/20520
logger.js:37 [log] > main stream:PARSED->IDLE
logger.js:37 [log] > loading playlist for level 2
logger.js:37 [log] > live playlist, reload in 5776 ms
logger.js:37 [log] > level 2 loaded [42,46],duration:30.03
logger.js:37 [log] > live playlist sliding:6.006
?src=http%3A%2F%2Fsyd.foxbat.live%2Fyatk2506v%2Fmaster.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined:370 parsing level duration :213us,count:40
logger.js:37 [log] > loading playlist for level 2
logger.js:37 [log] > live playlist, reload in 5532 ms
logger.js:37 [log] > level 2 loaded [43,47],duration:30.03
logger.js:37 [log] > live playlist sliding:12.012
?src=http%3A%2F%2Fsyd.foxbat.live%2Fyatk2506v%2Fmaster.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined:370 parsing level duration :211us,count:41
logger.js:37 [log] > loading playlist for level 2
logger.js:37 [log] > live playlist, reload in 5766 ms
logger.js:37 [log] > level 2 loaded [44,48],duration:30.03
logger.js:37 [log] > live playlist sliding:18.018
?src=http%3A%2F%2Fsyd.foxbat.live%2Fyatk2506v%2Fmaster.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined:370 parsing level duration :212us,count:42
logger.js:37 [log] > loading playlist for level 2
logger.js:37 [log] > live playlist, reload in 5544 ms
logger.js:37 [log] > level 2 loaded [45,49],duration:30.03
logger.js:37 [log] > discontinuity sliding from playlist, take drift into account
logger.js:37 [log] > live playlist sliding:24.091
?src=http%3A%2F%2Fsyd.foxbat.live%2Fyatk2506v%2Fmaster.m3u8&enableStreaming=true&autoRecoverError=true&enableWorker=true&dumpfMP4=false&levelCapping=-1&defaultAudioCodec=undefined:370 parsing level duration :208us,count:43
logger.js:37 [log] > loading playlist for level 2
logger.js:37 [log] > live playlist, reload in 5545 ms
logger.js:37 [log] > level 2 loaded [46,50],duration:30.03
logger.js:37 [log] > discontinuity sliding from playlist, take drift into account
logger.js:37 [log] > live playlist sliding:30.097
logger.js:37 [warn] > playback stalling in low buffer @270.713359

Here's a typical m3u8 sequence:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:2
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0003.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0004.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0005.ts
#EXT-X-DISCONTINUITY
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0001.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0002.ts
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:3
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0004.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0005.ts
#EXT-X-DISCONTINUITY
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0001.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0002.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0003.ts
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:4
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0005.ts
#EXT-X-DISCONTINUITY
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0001.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0002.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0003.ts
#EXTINF:6.0060,
http://204.236.220.132/encodes/default_1080p_0004.ts

@jeh993
Copy link

jeh993 commented Feb 9, 2018

I was able to fix my issue. I added EXT-X-DISCONTINUITY-SEQUENCE tags to the manifest and the player continues to download segments after discontinuities and rendition changes. Makes sense now that I have realized what was going on.

@stale
Copy link

stale bot commented Jun 15, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Wontfix label Jun 15, 2018
@stale stale bot closed this as completed Jun 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants