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

Very slow to load large local video #673

Open
richpixel opened this issue Dec 8, 2022 · 4 comments
Open

Very slow to load large local video #673

richpixel opened this issue Dec 8, 2022 · 4 comments

Comments

@richpixel
Copy link

On iOS - I'm attempting to use the HTML5 video player to play a 'large' video (~200mb). When the video is played from a remote URL - my server - it begins playing quickly and quality is good. When the video is played from an app folder on the local device or simulator, it takes about 20 seconds to begin playing and is somewhat choppy at the beginning. The file is stored in the 'dataDirectory' retrieved from window.cordova.file.dataDirectory

I suspect this has something to do with trying to buffer in the entire file before playing, but I have no idea - any ideas would be appreciated.

@jbgtmartin
Copy link

Maybe it's the same issue as this one?
It seems to be fixed since iOS 15.6 at least.

The only fix I've found so far is to use version 2 of this plugin, which handles the files differently, and to wait 1 or 2 years for our users to update their iOS before switching to the last version...

@richpixel
Copy link
Author

richpixel commented Dec 12, 2022

Thanks for your reply - I'm actually using iOS 16 on my device so I don't think this is it. I do notice there's some code in IONAssetHandler that's responsible for 'serving' the video - it appears to load the entire contents of the media file (into virtual memory which is good) and then somehow serve it through the response. This gets called repeatedly as the video is buffering/before play starts. I think this must have something to do with the issue. I suspect there must be some way to stream the data here, but I'm not sure how:

- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask
{
    NSString * startPath = @"";
    NSURL * url = urlSchemeTask.request.URL;
    NSString * stringToLoad = url.path;
    NSString * scheme = url.scheme;

    if ([scheme isEqualToString:self.scheme]) {
        if ([stringToLoad hasPrefix:@"/_app_file_"]) {
            startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_app_file_" withString:@""];
        } else {
            startPath = self.basePath ? self.basePath : @"";
            if ([stringToLoad isEqualToString:@""] || [url.pathExtension isEqualToString:@""]) {
                startPath = [startPath stringByAppendingString:@"/index.html"];
            } else {
                startPath = [startPath stringByAppendingString:stringToLoad];
            }
        }
    }
    NSError * fileError = nil;
    NSData * data = nil;
    if ([self isMediaExtension:url.pathExtension]) {
        // ENTIRE CONTENTS OF MEDIA FILE IS LOADED:
        data = [NSData dataWithContentsOfFile:startPath options:NSDataReadingMappedIfSafe error:&fileError];
    }
    if (!data || fileError) {
        data =  [[NSData alloc] initWithContentsOfFile:startPath];
    }
    NSInteger statusCode = 200;
    if (!data) {
        statusCode = 404;
    }
    NSURL * localUrl = [NSURL URLWithString:url.absoluteString];
    NSString * mimeType = [self getMimeType:url.pathExtension];
    id response = nil;
    if (data && [self isMediaExtension:url.pathExtension]) {
        response = [[NSURLResponse alloc] initWithURL:localUrl MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil];
    } else {
        NSDictionary * headers = @{ @"Content-Type" : mimeType, @"Cache-Control": @"no-cache"};
        response = [[NSHTTPURLResponse alloc] initWithURL:localUrl statusCode:statusCode HTTPVersion:nil headerFields:headers];
    }
    
    [urlSchemeTask didReceiveResponse:response];
    [urlSchemeTask didReceiveData:data]; // DATA IS "SERVED" , BUT THIS GETS CALLED REPEATEDLY
    [urlSchemeTask didFinish];

}

A potential hint at a solution:
https://stackoverflow.com/questions/58217566/how-to-serve-big-files-using-wkurlschemehandler

@ghenry22
Copy link
Contributor

ghenry22 commented Feb 6, 2023

could be missing range headers when fetching from local file system, without range headers the entire file will be loaded.

@richpixel
Copy link
Author

Thanks for the reply, that sounds promising. Do you have an idea for how to have the ionic webview accept range headers? Or supply them in the request somehow? It might actually need to happen somewhere in the code I posted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants