我目前正在尝试播放视频,有一个自定义NSURLProtocol子类中定义的自定义方案的URL。 起初,我试图做到这一点使用的MPMoviePlayerController,但遇到了问题,并检查堆栈溢出后,我发现的MPMoviePlayerController不处理NSURLProtocol子类如预期。
如何玩电影使用自定义NSURLProtocol网址?
因此,我决定看看AVFoundation框架,但是,似乎这也似乎并没有工作。 我只是想知道,如果这是可能的,还是我想要穿墙走?
使用AVFoundation,我使用的方法如下所示。 这也许值得一提的是,使用一个标准的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所以也没让我们通过cookies或头(认证)。 使用NSURLProtocol允许这一点。 我想我会在这里分享一些代码为社会的一次。
基本上,通过使用NSURLProtocol,我们可以拦截的MPMoviePlayerController和流请求之间的通信,注入饼干一路走来,或可能流离线保存,或用猫视频ECT取代它......要做到这一点,你需要创建一类新我伸出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];
文章来源: Possible to play video using a subclass of NSURLProtocol, using either MPMovieController or AVFoundation?