使用MPMovieController或AVFoundation可以使用NSURLProtocol的子类播放video?

我目前正试图播放一个具有在自定义NSURLProtocol子类中定义的自定义scheme的URL。 最初我使用MPMoviePlayerController试图完成这个工作,但是在遇到问题并检查堆栈溢出后,我发现MPMoviePlayerController不能按预期处理NSURLProtocol子类。

如何使用自定义NSURLProtocol来播放电影?

因此,我决定看看AVFoundation框架,但是,似乎这似乎并不奏效。 我只想知道这是可能的,还是我想穿过墙壁?

使用AVFoundation,我使用的方法如下所示。 可能值得一提的是,这对于在互联网上托pipe的video使用标准URL时有效,但不适用于自定义NSURLProtocol。

// this doesn't work //AVPlayer *player = [[AVPlayer alloc] initWithURL:[NSURL urlWithString:@"custom URL scheme"]]; // this works AVPlayer *player = [[AVPlayer alloc] initWithURL:[NSURL urlWithString:@"some url to video on remote server"]]; AVPlayerLayer *layer = [AVAVPlayerLayer playerLayerWithPlayer:player]; // configure the layer [self.view.layer addSublayer:layer]; [player play]; 

为了从定义的NSURLProtocol子类中播放,是否有不同的东西需要完成?

最近,我设法让NSURLProtocol与MPMoviePlayerController一起工作。 这主要是有用的,因为MPMoviePlayerController只接受一个NSURL,所以它不让我们通过cookie或头(用于身份validation)。 使用NSURLProtocol允许。 我以为我会在这里为社区分享一些代码。

基本上,通过使用NSURLProtocol,我们可以拦截MPMoviePlayerController与stream式传输请求之间的通信,沿途注入cookie,或者可能保存stream离线,或者用catvideo等代替它。为此,您需要创build一个新的类我的扩展NSURLProtocol:

MyURLProtocol.h:

 #import <Foundation/Foundation.h> @interface MyURLProtocol : NSURLProtocol + (void) register; + (void) injectURL:(NSString*) urlString cookie:(NSString*)cookie; @end 

MyURLProtocol.m:

 #import "MyURLProtocol.h" @interface MyURLProtocol() <NSURLConnectionDelegate> { NSMutableURLRequest* myRequest; NSURLConnection * connection; } @end static NSString* injectedURL = nil; static NSString* myCookie = nil; @implementation MyURLProtocol // register the class to intercept all HTTP calls + (void) register { [NSURLProtocol registerClass:[self class]]; } // public static function to call when injecting a cookie + (void) injectURL:(NSString*) urlString cookie:(NSString*)cookie { injectedURL = urlString; myCookie = cookie; } // decide whether or not the call should be intercepted + (BOOL)canInitWithRequest:(NSURLRequest *)request { if([[[request allHTTPHeaderFields] objectForKey:@"BANANA"] isEqualToString:@"DELICIOUS"]) { return NO; } return [[[request URL] absoluteString] isEqualToString:injectedURL]; } // required (don't know what this means) + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { return request; } // intercept the request and handle it yourself - (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client { if (self = [super initWithRequest:request cachedResponse:cachedResponse client:client]) { myRequest = request.mutableCopy; [myRequest setValue:@"DELICIOUS" forHTTPHeaderField:@"BANANA"]; // add your own signature to the request } return self; } // load the request - (void)startLoading { // inject your cookie [myRequest setValue:myCookie forHTTPHeaderField:@"Cookie"]; connection = [[NSURLConnection alloc] initWithRequest:myRequest delegate:self]; } // overload didReceive data - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [[self client] URLProtocol:self didLoadData:data]; } // overload didReceiveResponse - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response { [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:[myRequest cachePolicy]]; } // overload didFinishLoading - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [[self client] URLProtocolDidFinishLoading:self]; } // overload didFail - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [[self client] URLProtocol:self didFailWithError:error]; } // handle load cancelation - (void)stopLoading { [connection cancel]; } @end 

用法:

 [MyURLProtocol register]; [MyURLProtocol injectURL:@"http://server/your-video-url.mp4" cookie:@"mycookie=123"]; MPMoviePlayerController* moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:@"http://server/your-video-url.mp4"]; [moviePlayer play];