Open posti85 opened 1 month ago
I understand hls.js makes the requests 'based' on the first one, which was to https://localhost/. Is there any way to prevent this behaviour? are there any option to set that base url manually or similar...?
HLS.js uses the response URL as the base URL when resolving relative URLs in HLS playlists:
The base for media playlists is the response URL from the parent multi-variant playlist: https://github.com/video-dev/hls.js/blob/bf0180ca781ec90b8a3ab3e06ffa46817e2fe3b6/src/loader/playlist-loader.ts#L363-L365
The base for media segments is the response URL from the parent media playlist: https://github.com/video-dev/hls.js/blob/bf0180ca781ec90b8a3ab3e06ffa46817e2fe3b6/src/loader/playlist-loader.ts#L454-L463
This is the method that gets the response URL. There is no way to currently override it. We could accept a PR that adds an option to do this. The alternative would be to customize the loader so that you rewrite the response URL to match the context URL on complete.
I was able to fix it manipulating the url before the request is made (I let in comments the first url modifications to clarify):
The issue is that segment URLs in the media playlist are relative to their parent media playlist, not the multi-variant playlist.
Thank you very much @robwalch. Based on your suggestion:
The alternative would be to customize the loader so that you rewrite the response URL to match the context URL on complete.
I made a custom loader that replaces the response.url
with the context.url
, which is the correct one:
class ResponseUrlFixLoader extends Hls.DefaultConfig.loader {
load(context, config, callbacks) {
const originalSuccess = callbacks.onSuccess;
callbacks.onSuccess = (response, stats, context, networkDetails) => {
response.url = context.url;
originalSuccess(response, stats, context, networkDetails);
};
super.load(context, config, callbacks);
}
}
const hls = new Hls({
loader: ResponseUrlFixLoader
});
And now the video plays! I hope it is usefull for someone else.
But I have found a new problem. I don't know if it's related to the fact of executing hls.js in a webview... or it might be related to other issue I should open.
The video plays well for 3 seconds but, after that, the video does like a zoom and only a top left region is shown (the red border belongs to the video tag):
The full frame of that scene:
What could be happening?
Edit: I was testing in an Android Emulator. I have tested the same in a real device and there it works! Maybe an issue related with the emulator hardware acceleration?
What could be happening?
Have you looked at the page layout?
An HTMLMediaElement will resize according to the resolution of rendered bitrate variants, unless it and its parent containers are constrained using CSS.
What do you want to do with Hls.js?
I'm developing an Android hybrid application with Capacitor and using hls.js to play video sources. The application uses CapacitorHttp plugin, which patches
fetch
andXMLHttpRequest
to proxy the webview request to make with the native system. When a video is played, it fails due m3u8 and ts files failed requests.I'm trying to play the Big Buck Bunny video: https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
What have you tried so far?
In my desktop in Google Chrome browser (normal execution), the request are:
When execute that code in the Android device, the first request to the m3u8 file is made successfully. The webview makes a local request which proxies to a native system HTTP request:
The problem is that the following request hls.js does is:
note that the query param refers to
https://localhost/
(insead ofhttps://test-streams.mux.dev/x36xhzz/
, which should be the valid one).I was able to fix it manipulating the url before the request is made (I let in comments the first url modifications to clarify):
The video plays are first, but a few seconds later it ends showing weird frames.
I understand hls.js makes the requests 'based' on the first one, which was to
https://localhost/
. Is there any way to prevent this behaviour? are there any option to set that base url manually or similar...?