Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom NSURLProtocol class for WebView doesn't work when loading video in HTML5 document

I'm working with WebView which loads its contents from certain location like sandbox. So I added simple child class of NSURLProtocol to handle those files. The protocol handler will manage URL scheme like "dummy:". When I tried custom url like dummy:///index.html, this should load index.html from a local directory. Htmls and embedded images etc. worked fine.

But when I tried an html file includes HTML5 video player using tag, it doesn't work. WebView even didn't tried the method canInitWithRequest:request in my custom class for the video file.

@interface DummyURLProtocol : NSURLProtocol {
}

+ (BOOL)canInitWithRequest:(NSURLRequest *)request;
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b;
- (void)startLoading;
- (void)stopLoading;

@end

@implementation DummyURLProtocol

+(BOOL)canInitWithRequest:(NSURLRequest *)request {
    return [[[request URL] scheme] isEqualToString:@"dummy"];
}

+(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}

+(BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {
    return [[[a URL] resourceSpecifier] isEqualToString:[[b URL] resourceSpecifier]];
}

-(void)startLoading {
    NSURL *url = [[self request] URL];
    NSString *pathString = [url resourceSpecifier];
    NSString *path = [NSString stringWithFormat:@"/Users/cronos/tmp/video_demo/%@", pathString];
    NSString *fullFilename = [pathString lastPathComponent];
    NSString *extention = [fullFilename pathExtension];
    NSString *mimeType = [[SSGHTMLUtil sharedUtil] mimeTypeForExtension:extention];
    NSLog(@"DummyURLProtocol:FILEPATH: %@ EXTENSION: %@ MIME-TYPE: %@", path, extention, mimeType);


    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:url MIMEType:mimeType expectedContentLength:-1 textEncodingName:nil];
    FILE *fp = fopen([path UTF8String], "r");
    if (fp) {
        char buf[32768];
        size_t len;
        [[self client] URLProtocol:self
                didReceiveResponse:response
                cacheStoragePolicy:NSURLCacheStorageNotAllowed];
        while ((len = fread(buf,1,sizeof(buf),fp))) {
            [[self client] URLProtocol:self didLoadData:[NSData dataWithBytes:buf length:len]];
        }
        fclose(fp);
    }
    [[self client] URLProtocolDidFinishLoading:self];
}

-(void)stopLoading {
}

@end

I registered the protocol handler in applicationDidFinishLaunching: in AppDelegate.m

if ([NSURLProtocol registerClass:[DummyURLProtocol class]]) {
    NSLog(@"URLProtocol registration successful.");
} else {
    NSLog(@"URLProtocol registration failed.");
}

then I tried my WebView with the url "dummy:///HTML5_Video.html". Other resources like javascript files, css files, images are loaded successfully but mp4 file wasn't passed to the DummyURLProtocol. The HTML5_Video.html includes following.

  <video preload="metadata"> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=676422 -->
    <source src="assets/dizzy.mp4" type="video/mp4" />
    <source src="assets/dizzy.webm" type="video/webm" />
    <source src="assets/dizzy.ogv" type="video/ogv" />
  </video>

Any ideas or good starting point to solve this problem?

Thank you.

like image 640
cronos Avatar asked Nov 09 '11 09:11

cronos


1 Answers

Yup. It won't work.

I've filed bugs with Apple over a year ago.

Video and other multimedia types including SVG do not go through the NSURLProtocol mechanism

See http://openradar.appspot.com/8446587

and http://openradar.appspot.com/8692954

like image 127
schwa Avatar answered Oct 26 '22 04:10

schwa