Closed stephendonner closed 7 months ago
One of the test files/URLs is https://www.youtube.com/watch?v=kBW-oDpamZg
Looks like it's actually the only cached one, but it's a hefty 3.19 GB
file
...which makes sense, since this stack is in out-of-memory (OOM) land.
I Removed from playlist
the file, and all is well (no crashing when switching between media):
example | example |
---|---|
I'm hoping I could get some help about this. When playing a video, we're read the video to string and pass it to webui from c++ layer(PlaylistDataSource). I guess this could be what cased OOM. I'm not sure what else we can try.
cc. @simonhong @petemill @fallaciousreasoning
The reading the video to a string is probably the cause - we'll be downloading the entire video to memory. Maybe we can stream it to disk?
Maybe we can stream it to disk?
Yeah, that sounds great. But I'm not sure how I can achieve that 😂. Should I slice the video into small chunks of bytes and gather them with MedaiSource API? Or is there easy way?
Just curious why we don't play with local media file path and instead passing it via string? It's bcause of NVM Data source should pass that file's data :)
As we're using custom chrome-untrusted://
?chrome-untrusted://playlist-data/...
url for playlist data, we have its own data source.
I think it's worth to investigate how file:// scheme load big size media file.
Maybe loading url something like /Users/simon/Library/ApplicationSupport/BraveSoftware/Brave-Browser-Beta//Default/playlist/60A2BE63931C52698229F7F0C430D243/media_file.mp4
in omnibox will play it well?
Or how about trying local file path instead of custom media path if it's possible from untrusted webui?
I don't know how much control we have over the stream, but if we have control over a HTTP response we can do something like this:
/* super pseudo codey - I'm sure there's a built in Chromium way to just write small chunks to the HTTP stream */
auto http_response = /* whatever the chromium type is */
constexpr size_t chunk_size = 1024;
while (auto chunk = source.read(chunk_size)) {
http_response.write(chunk);
/* sleep or whatever so we don't block */
}
Maybe loading url something like /Users/simon/Library/ApplicationSupport/BraveSoftware/Brave-Browser-Beta//Default/playlist/60A2BE63931C52698229F7F0C430D243/media_file.mp4 in omnibox will play it well?
it might not be allowed due to the CSP.
local file path instead of custom media path if it's possible from untrusted webui?
Also this seems to be difficult without explicit user interaction via <input type=file
for security/privacy reason.
So, not sure if it works, but I guess we should do something like from PlaylistDataSource
chrome://playlist-data/{id}/media/
should return the size of chunks and media typeUpdate:
It seems that Youtube videos(mp4) we caches are not in format that can be used for MediaSource. So I'm going to try gather chunks into byte array(not MediaSource's source buffer), and set it to video tag's src attribute.
Even if the byte array causes OOM, only renderer would crash. I think that's better. But eventually, we'll need to work on caching MediaSource object as is.
[35205:259:0220/185131.533058:ERROR:box_definitions.cc(2063)] Failure parsing MP4: Detected unfragmented MP4. Media Source Extensions require ISO BMFF moov to contain mvex to indicate that Movie Fragments are to be expected.
Updated issue title
It would be great to support http range requests and just get the video player itself to support the chunking. Added benefit would be efficient seeking (only downloading the part of the video that's being watched).
@sangwoo108 and I took a look at URLDataSource
and it seems we don't get the request headers (or ability to set response headers). I wonder if we can use a Throttle
, which does have access to the full request data in order to set the appropriate range request and response headers? https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
It would be great to support http range requests and just get the video player itself to support the chunking.
This seems to be similar to what @fallaciousreasoning suggested. Maybe we make use of the throttle or need to plumb new API from the web_ui_url_loader_factory, which calls the WebUIDataSource's methods.
At the moment, it seems the blink::URLLoaderThrottles are attached to main resource requests(from brave_content_browser_client). So requests for sub resources are not going through URLLoaderThrottles. I might be missing because there're other types of the throttle(e.g. content::NavigationThrottle). I will keep trying find out a better way.
And one more thing worth mentioning is that WebUIUrlLoaderFactory
rejects the HTTP range request for simplicity.
https://source.chromium.org/chromium/chromium/src/+/main:content/browser/webui/web_ui_url_loader_factory.cc;l=222;drc=c686e8f4fd379312469fe018f5c390e9c8f20d0d .
So we might need to start from here.
Maybe it means it doesn't support multi ranges in one header, but still supports range.
Yay, I think we're close to it. Succeeded in playing 24hr long video
That's...pretty "reasonable."
😆 - nice work as always!
@sangwoo108 is the WIP for this one https://github.com/brave/brave-core/pull/22304?
Yes, that's right.
PASSED
usingBrave 1.65.83 Chromium: 123.0.6312.46 (Official Build) beta (x86_64)
Revision 1ea667c8c59a4a4a327579974ec11149a738e750
OS macOS Version 11.7.10 (Build 20G1427)
1.65.83
brave://flags
youtube.com
Kept for offline playing
PASSED
usingBrave | 1.65.88 Chromium: 123.0.6312.58 (Official Build) beta (64-bit)
-- | --
Revision | e260e641e7db9e88b9b51112f4f00febf5a2f5eb
OS | Windows 10 Version 22H2 (Build 19045.4170)
https://github.com/brave/brave-browser/assets/387249/4de97147-0780-42ae-9680-e2d0f332dc29
Description
Playlist crashes when switching between large/long-running videos (cached and uncached)
Steps to Reproduce
1.62.89
brave://flags/#playlist
toEnabled
Relaunch
NOTE: It appears to be the larger videos (which are slower to cache offline) which are still downloading that might be the problem, here - but I haven't fully nailed it down
Actual result:
💥
Crash ID:
6c330f00-f35a-140b-0000-000000000000
Expected result:
No crash
Reproduces how often:
100% with: multiple large files, at least stored for offline, media playing, and switching betweeen them
Brave version (brave://version info)
Version/Channel Information:
Other Additional Information:
Miscellaneous Information:
/cc @sangwoo108 @rebron @brave/qa-team