video-dev / hls.js

HLS.js is a JavaScript library that plays HLS in browsers with support for MSE.
https://hlsjs.video-dev.org/demo
Other
14.93k stars 2.59k forks source link

not absolute segment path (ts) for filename with colon (:), regression because of URLToolkit #1478

Closed proxy-m closed 6 years ago

proxy-m commented 6 years ago
Environment
Steps to reproduce

Put something like playlist (with ts files in same folder) on server A with correct CORS headers. 2017.12.28-15-49-14.000_2017.12.28-15-59-22.000_ng_4.m3u8.txt It has segments names like ng_42017-12-28_15:49:14.000__2017-12-`28_15:49:16.442_ng_42d7c5859cc1ed26b92da83e3ce48f97aIbodyframecamng_4__0card_body_yv4e6_GUI_FULL_VIDEO_PLAYER.ts` (with colon (:) ). Try to play it from browser javascript, hosted on server B. It successfully load and parses m3u8 with absoolute url, but urls of ts segments will not be absolute and same dir as m3u8 playlist on server A. It will try to download ts segments from server B relative to window.location.href of current page (server B) and get 404 errors or something else.

But if you put on server A with correct CORS (again) something like playlist ng_4.Quality.m3u8.txt which has not colon (:) in filenames, all will works fine from server A: both m3u8 manifest and ts segments will have absolute urls.

Expected behavior

Absolute urls from server A as expected for ts segments. This excpected behaviour was in hls.js v0.6.3 .

Actual behavior

Not absolute urls relative to server B and 404 or other errors (depends on server B configuration). Regression in hls.js v0.8.9.

I found https://github.com/video-dev/hls.js/issues/1063 and https://github.com/video-dev/hls.js/pull/1075 . But removing line url = URLToolkit.buildAbsoluteURL(window.location.href, url, { alwaysNormalize: true }); (commit revert) does not helps. So problem is in other place. Maybe you need to convert urls of ts segments somewhere not relative to window.location.href, but relative to m3u8 manifest location?

Console output
many:
GET http://B-SERVER:8080/itso/iweb/operator/ng_4__2017-12-28_16:21:48.000__2017-12-28_16:21:50.441_ng_4__2d7c5859cc1ed26b92da83e3ce48f97a__I__bodyframecamng_4__0card_body_2afa5h_GUI_FULL_VIDEO_PLAYER.ts 404 (Not Found) xhr-loader.js:80 // loadInternal()::xhr.send() line.

window.location.href is http://B-SERVER:8080/itso/iweb/operator/screen2.html . m3u8 playlist is http://A-SERVER:8081/cache_archive/2017.12.28-16:21:48.000_2017.12.28-16:31:56.000_ng_4.m3u8

tjenkinson commented 6 years ago

The problem is that when it tries to parse

ng_4__2017-12-28_15:49:14.000__2017-12-28_15:49:16.442_ng_4__2d7c5859cc1ed26b92da83e3ce48f97a__I__bodyframecamng_4__0card_body_yv4e6_GUI_FULL_VIDEO_PLAYER.ts

it is seeing

ng_4__2017-12-28_15:49:14.000__2017-12-28_15:49:

as the scheme and the remainder as the path, and therefore thinking it is a complete url not a relative one

See https://runkit.com/embed/zfwofbhjfo16

proxy-m commented 6 years ago

@tjenkinson, yes, I agree (I test it now with URLToolkit from whole hls.js build). But looks like Hls.js v0.6.3 does not use this urlToolkit and does not have the problem.

tjenkinson commented 6 years ago

Ok. I think this case should be handled in URL toolkit so I'll fix it there. (The regex for scheme should be a bit stricter and we should not allow a scheme when there is no net loc)

If you want to guarantee that URL toolkit sees the URLs as relative and you have control of the playlist generation you can prefix the URLs with './'

tjenkinson commented 6 years ago

@proxy-m https://github.com/video-dev/hls.js/pull/1480 should fix the problem. However the only reason why is because your urls currently contain characters that are not valid in a scheme (e.g _).

If you know the urls will be relative it would be best to prefix them with ./ as mentioned here.