Open BPerlakiH opened 2 weeks ago
I'm sure it can also go over 2 seconds if you have a poor HDD and/or an ("old") Intel machine.
Did you even included a hour long video in your test set?
It doesn't change anything to the issue aside from pushing emphasis on how important it is to solve this.
With the current html setup we have on the html video tag:
data-setup='{"techOrder": ["html5", "ogvjs"],
This makes video rendering hand over to html5 in both browsers. This mode is
more or less equal to the a pure html5 video implementation without any javascript (without videojs and videojs-ogvjs).
The difference being is that Safari pre-loads the whole content of the video, starting at page load,
whereas Chrome handles it better, and starts loading when it is played. The preload
attribute is ignored by Safari, and not helping in this regard.
In this scenario seeking works as expected in both browsers.
Changing it to:
data-setup='{"techOrder": ["ogvjs"],
and using the python default Simple server, it fixes the issue of initial preload: Safari is not pre-loading before the play button is pressed, similarly Chrome. Since the range request seems not to be handled by the server, it results in the following:
throw new Error("Cannot seek a non-seekable stream")
I did try it in a couple of ways, even returning 206 responses with the first range, but the player was not requesting more ranges. The preload
argument of the html5 video
tag doesn't make any difference in this regard.
After some tweaking in the application, I forced it to use
data-setup='{"techOrder": ["ogvjs"]
, meaning it is not using the HTML5 player.
It indeed creates range requests, but it is not working smoothly.
I did observed the following ranges requested:
Summary
URL: kiwix://93A5A6DA-C6BF-95B2-23AC-B67C79457880/videos/96462/video.webm
Status: 206 Partial Content
Source: —
Initiator:
ogv.js:2:91642
Request
Accept: */*
Range: bytes=0-1048575
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) > > Version/17.4 Mobile/15E148 Safari/604.1
Response
Content-Length: 16313408
Content-Range: bytes 0-1048575/16313408
Content-Type: video/webm
Summary
URL: kiwix://93A5A6DA-C6BF-95B2-23AC-B67C79457880/videos/96462/video.webm
Status: 206 Partial Content
Source: —
Initiator:
ogv.js:2:91642
Request
Accept: */*
Range: bytes=1048576-2097151
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1
Response
Content-Length: 16313408
Content-Range: bytes 1048576-2097151/16313408
Content-Type: video/webm
These ranges seem OK to me, but the video is not playing and not seekable.
I have tested it and AVPlayer (the native iOS player) is not supporting WebM at the moment. In order to use this route, we would need to use an external player library.
I measured again, how it behaves on device with a 1.5 hour long video content.
In the worst case scenario, the 1.5 hour video was loaded in ~600 ms, subsequent loads of the same video are below 50 ms.
I can conform the HTML player is not working on iOS 17.1 (and possibly neither below that), but it does work on 17.4.1. The video load time is similar: ~550 ms.
At the moment it seems the best working option is the HTML player provided by Apple, which works reasonably well on new iOS / macOS versions. At the moment, I do not see a way to support range requests, that could improve on the user experience. On end devices, even the 1.5 hour long video was loading in a reasonable time. This seems to be our best possible option for the moment.
@BPerlakiH Not sure about:
I find the last comment very difficult to be exploitable because:
@kelson42
How looks the fix concretely?
I am writing down my findings here, I do not have a fix for it (yet).
You seem to assume that you have high bandwidth between browser and server.
In our situation we are reading the video out of a local ZIM file, the network / bandwidth can be ignored in this case.
Playing a video with ojv.js creates range requests and this is not working even with a web server?
I did test this with python default http server: Well, it is playing the video, but the video is not "seek-able", we have the following error in the console, when trying to seek:
VIDEOJS:
Error: Cannot seek a non-seekable stream —
"Video is not ready. (Video.js)"
This is the request / response:
Summary
URL: http://localhost:8000/videos/onehour/video.webm
Status: 200 OK
Source: Network
Address: ::1:8000
Initiator:
ogv.js:2:91642
Request
GET /videos/onehour/video.webm HTTP/1.1
Accept: */*
Accept-Encoding: identity
Accept-Language: en-GB,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Cookie: _ga=GA1.1.1067747901.1681038766
Host: localhost:8000
Pragma: no-cache
Range: bytes=0-1048575
Referer: http://localhost:8000/le-farine-vs-le-boiserie.html?lang=undefined
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15
Response
HTTP/1.1 200 OK
Content-Length: 168736330
Content-Type: video/webm
Date: Tue, 14 May 2024 19:46:04 GMT
Last-Modified: Mon, 06 May 2024 07:34:24 GMT
Server: SimpleHTTP/0.6 Python/3.12.3
My understanding of this is: javascript requests the first range, but the server sends back the whole video file. This is what I meant: the web server is not sending back the expected Response. "Since the range request seems not to be handled by the default python server".
I keep checking what else I can improve in this regard.
You seem to assume that you have high bandwidth between browser and server. In our situation we are reading the video out of a local ZIM file, the network / bandwidth can be ignored in this case.
Yes and no, Browsers on iOS/macOS should work as well with Kiwix Server (I though this were something you were checking as well) and you can not assume everything is local (you can have a file stored on a network drive for example).
Playing a video with ojv.js creates range requests and this is not working even with a web server?
I did test this with python default http server: Well, it is playing the video, but the video is not "seek-able"
it's not because a piece of software says "not seekable" that the http has to be unable to handle range requests. This can have other root causes. In addition, if your http server is not able to handle range requests, your whole testing is worthless as you use it as reference.
@benoit74 @rgaudin Can you please confirm the Pythin http server handles range request properly?
@benoit74 @rgaudin Can you please confirm the Pythin http server handles range request properly?
It doesn't. It's a very basic HTTP server meant for educational purposes.
@benoit74 @rgaudin Can you please confirm the Pythin http server handles range request properly?
It doesn't. It's a very basic HTTP server meant for educational purposes.
Then I hardly understand why we recommend to use it as reference?! In particular for this ticket?!
I did not recommend it. I specifically mentioned nginx and caddy. I believe @benoit74 suggested it to test ogvjs in general, not for this specific issue.
OK, then @BPerlakiH you need to redo your experience with a HTTP serve handling range requests properly.
I don't know exactly what went wrong here... but I really wonder how we have managed to waste so much time for almost no learning.
Ok, I am sorry for the confusion, will look into nginx / caddy then.
Python server was original solution used by @BPerlakiH ; I provided instruction for both python and Caddy with the test ZIM, so it should be straightforward to use Caddy. I put them here again for reference.
docker run -d -p 80:80 -v $PWD:/usr/share/caddy caddy
Please see my summary of what is currently working / supported and what is not under: #765.
After checking it, and benchmarking, it turned out that the videos (webm) are pre-loaded, when the webpage is loaded in full ( in one http request we load from start to finish). This is sub optimal, and with larger videos it can cause unecesary waiting time for the user. The time it takes on macOS, using an external usb-c drive:
From this it is obvious that the loading time, can go over 2 seconds, if the video is larger.