【问题标题】:How to play movie with a URL using a custom NSURLProtocol?如何使用自定义 NSURLProtocol 播放带有 URL 的电影?
【发布时间】:2011-05-21 23:14:47
【问题描述】:

如您所知,使用 MPMoviePlayerController 对象播放电影

[[MPMoviePlayerController alloc] initWithContentURL: aURL];

现在,我想实现一个自定义的 NSURLProtocol,我将在其中解密已由 AlgorithmDES 加密的电影源。 有这种可能吗?感谢您提供任何想法。需要您的帮助~

【问题讨论】:

  • 嗨,我想实现和你一样的功能。我在服务器上加密了视频文件。我想用流媒体播放相同的视频。怎么可能?谢谢

标签: ios url mpmovieplayercontroller nsurlprotocol


【解决方案1】:
@property AVPlayerViewController *avPlayerVC;
@property NSData *yourDataSource

// initialise avPlayerVC
    NSURL *dummyURL     = [NSURL URLWithString:@"foobar://dummy.mov"];// a non-reachable URL will force the use of the resourceLoader
    AVURLAsset *asset   = [AVURLAsset assetWithURL:dummyURL];
    [asset.resourceLoader setDelegate:self queue:dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)];

    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];

    self.avPlayerVC.player = [AVPlayer playerWithPlayerItem:item];
    self.avPlayerVC.player.actionAtItemEnd  = AVPlayerActionAtItemEndNone;



// implement AVAssetResourceLoaderDelegate

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {

    loadingRequest.contentInformationRequest.contentType    = (__bridge NSString *)kUTTypeQuickTimeMovie;
    loadingRequest.contentInformationRequest.contentLength  = self.yourDataSource.length;
    loadingRequest.contentInformationRequest.byteRangeAccessSupported   = YES;

    NSRange range = NSMakeRange((NSUInteger)loadingRequest.dataRequest.requestedOffset, loadingRequest.dataRequest.requestedLength);
    [loadingRequest.dataRequest respondWithData:[self.yourDataSource subdataWithRange:range]];

    [loadingRequest finishLoading];
    return YES;
}

注意使用虚拟 URL 来强制 AVPlayer 使用 AVAssetResourceLoaderDelegate 方法而不是直接访问 URL。

【讨论】:

    【解决方案2】:

    从 iOS 7 开始,还有一种解决方案。您可以将 AVAssetResourceLoaderDelegate 用于 AVAssetResourceLoader。但这仅适用于 AVPlayer。

    苹果有一个名为 AVARLDelegateDemo 的演示项目,看看它,你应该会找到你需要的。 (我认为链接到它不是一个好主意,所以只需在 developer.apple.com 上的开发人员库中搜索它)然后使用任何自定义 URL 方案(不声明 NSURLProtocol)并在 AVAssetResourceLoaderDelegate 中处理该 URL 方案。

    如果有很大的兴趣,我可以提供概念证明要点。

    【讨论】:

    • 将此与 iOS8 AVPlayerViewController 结合起来,这是我找到的最佳解决方案。很好地找到了这个。
    【解决方案3】:

    解决方案是通过本地 HTTP 服务器代理请求。我已经使用CocoaHTTPServer 完成了这项工作。

    查看HTTPAsyncFileResponse 示例。

    【讨论】:

    • 我要实现一个本地服务器来流式传输视频。但我不知道如何开始:(。你能分享我如何创建它吗。非常感谢
    • 我尝试了 AVAssetResourceLoader 方法,但无法正常工作。对于一些简单的事情来说似乎工作量太大(我只想要 AVPlayer URL 请求中的自定义标头)。您能否提供有关如何使用 CocoaHTTPServer 实现此功能的指南?
    【解决方案4】:

    更新:我与 Apple 谈过此事,目前无法将 MPMoviePlayerController 与 NSURLProtocol 子类一起使用!


    嘿嘿,

    我不确定,但有可能。我目前正在做类似的事情,但还没有完全发挥作用。我发现 MPMoviePlayerController 与我的自定义 NSURLProtocol 子类交互,但考虑到 NSURLRequest 的 HTTPHeaders 似乎很重要,因为它们定义了 MPMoviePlayerController 需要的字节范围。

    如果你将它们转储到你的 NSURLProtocol 子类中,你会在开始时得到两次这样的东西:

    2011-01-16 17:00:47.287 iPhoneApp[1177:5f03] Start loading from request: {
    Range = "bytes=0-1";
    

    }

    所以我的猜测是,只要你能提供正确的范围并返回一个可以由 MPMoviePlayerController 播放的 mp4 文件,它应该是可能的!

    编辑:这是一个有趣的链接:Protecting resources in iPhone and iPad apps

    【讨论】:

    • 我发现播放器需要自己解析url,好像我找到播放器解析url的方法一样无法解决,但苹果不会提供给我们。
    • 我在 NSURLProtocol 中看不到任何包含此自定义开始加载范围的方法。可能是私有方法。有人对此有线索吗?
    • 在你的 NSURLProtocol 子类的 startLoading 方法中调用NSDictionary* headers = [self.request allHTTPHeaderFields]; if([[headers allKeys] containsObject:@"Range"]) { NSLog(@"Range: %@",[headers objectForKey:@"Range"]); }
    • 我编写了一个自定义协议,它实现范围请求并返回相同的数据和标头,但仍然出现 -11850 错误(服务器配置不正确)-知道 AVPlayer/MPMoviePlayer 如何确定服务器是配置了范围请求?
    • @auibrian 我向 Apple 发送了 DTS 票证,他们回复说仍然无法使用 NSURLProtocol 在 iOS 7 中提供视频文件。他们建议在雷达上提交功能增强请求。
    猜你喜欢
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 2011-02-18
    • 2016-05-02
    相关资源
    最近更新 更多