相关疑难解决方法(0)

下载iOS时流视频

我正在使用iOS 7,我有一个.mp4视频,我需要在我的应用程序中下载.视频很大(约1 GB),这就是为什么它不包含在应用程序中的原因.我希望用户能够在开始下载后立即开始观看视频.我还希望视频能够在iOS设备上缓存,以便用户以后不需要再次下载.播放视频的常规方法(渐进式下载和实时流式传输)似乎都不允许您缓存视频,因此我创建了自己的Web服务,将视频文件分块并将字节流式传输到客户端.我使用NSURLConnection启动流式HTTP调用:

self.request = [[NSMutableURLRequest alloc] initWithURL:self.url];
[self.request setTimeoutInterval:10]; // Expect data at least every 10 seconds
[self.request setHTTPMethod:@"GET"];
self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:YES];
Run Code Online (Sandbox Code Playgroud)

当我收到数据块时,我将它附加到文件的本地副本的末尾:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
     NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:[self videoFilePath]];
     [handle truncateFileAtOffset:[handle seekToEndOfFile]];
     [handle writeData:data];
}
Run Code Online (Sandbox Code Playgroud)

如果我让设备运行,文件下载成功,我可以使用MPMoviePlayerViewController播放它:

NSURL *url=[NSURL fileURLWithPath:self.videoFilePath];
MPMoviePlayerViewController *controller = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
controller.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
[self presentMoviePlayerViewControllerAnimated:controller];
Run Code Online (Sandbox Code Playgroud)

但是,如果我在文件完全下载之前启动播放器,则视频开始播放就好了.它甚至可以在顶部擦洗条上显示正确的视频长度.但是当用户到达视频中我在视频开始之前完成下载的位置时,视频就会挂起.如果我关闭并重新打开MPMoviePlayerViewController,那么视频会播放,直到它到达我再次启动MPMoviePlayerViewController时的任何位置.如果我等到整个视频下载完毕,那么视频播放没有问题.

我没有收到任何事件,或者在发生这种情况时打印到控制台的错误消息(视频启动后永远不会发送MPMoviePlayerPlaybackStateDidChangeNotification和MPMoviePlayerPlaybackDidFinishNotification).似乎还有其他东西告诉控制器视频的长度是什么,而不是洗涤器使用的...

有谁知道可能导致这个问题的原因是什么?我不一定要使用MPMoviePlayerViewController,所以如果在这种情况下使用不同的视频播放方法,我就是为了它.

相关未解决的问题:

使用AVURLAssets进行AVPlayer和逐行视频下载

iOS上的渐进式视频下载

如何在IOS中下载进度视频文件

更新1 我发现视频停顿确实是因为视频开始播放时的文件大小.我可以通过在开始下载之前创建一个归零文件来解决这个问题,并在我去的时候覆盖它.由于我可以控制视频流服务器,因此我添加了一个自定义标头,因此我知道正在流式传输的文件的大小(流式文件的默认文件大小标头为-1).我在didReceiveResponse方法中创建文件,如下所示:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{        
    // Retrieve the size …
Run Code Online (Sandbox Code Playgroud)

video-streaming progressive-download mpmovieplayer ios nsurlsessiondownloadtask

12
推荐指数
2
解决办法
1万
查看次数

使用AVPlayer和AVAssetExportSession进行缓存

我想使用AVPlayer缓存渐进式下载视频.如何将AVPlayer的项目保存到磁盘?我正在尝试在播放器的currentItem(完全加载)上使用AVAssetExportSession.这段代码给了我" AVAssetExportSessionStatusFailed(操作无法完成) ":

    AVAsset *mediaAsset = self.player.currentItem.asset;

    AVAssetExportSession *es = [[AVAssetExportSession alloc] initWithAsset:mediaAsset presetName:AVAssetExportPresetLowQuality];

    NSString *outPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"out.mp4"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtPath:outPath error:NULL];

    es.outputFileType = @"com.apple.quicktime-movie";
    es.outputURL = [[[NSURL alloc] initFileURLWithPath:outPath] autorelease];
    NSLog(@"exporting to %@",outPath);
    [es exportAsynchronouslyWithCompletionHandler:^{
        NSString *status = @"";

        if( es.status == AVAssetExportSessionStatusUnknown ) status = @"AVAssetExportSessionStatusUnknown";
        else if( es.status == AVAssetExportSessionStatusWaiting ) status = @"AVAssetExportSessionStatusWaiting";
        else if( es.status == AVAssetExportSessionStatusExporting ) status = @"AVAssetExportSessionStatusExporting";
        else if( es.status == AVAssetExportSessionStatusCompleted ) status = @"AVAssetExportSessionStatusCompleted"; …
Run Code Online (Sandbox Code Playgroud)

iphone avfoundation video-streaming ios avplayer

9
推荐指数
1
解决办法
8924
查看次数

AVPlayer不在渐进式下载和流式传输之间切换

我有一个处理流媒体视频的应用程序.从.m3u8播放列表开始,它会创建一个AVAssets数组,并通过它们翻转

[player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:[assetItems objectAtIndex:index]]]
Run Code Online (Sandbox Code Playgroud)

这很好,但在此之前,我想用渐进式下载播放短的mp4视频.我使用加载AVPlayer

AVAsset *prerollAsset = [AVAsset assetWithURL:prerollURL];
[player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:prerollAsset]];
Run Code Online (Sandbox Code Playgroud)

它播放,但当我像以前一样继续播放流视频时,我得到AVPlayerStatusFailed的状态,AVPlayerItem中的错误 The operation could not be completed

为了它的工作,我需要为(渐进式下载)预卷创建一个AVPlayer对象,然后创建一个全新的AVPlayer对象来开始播放流式视频.

是否有可能单个AVPlayer实例无法播放渐进式下载视频,然后是流式视频?或者可能还有别的我做错了?

video streaming ios avplayer

6
推荐指数
1
解决办法
3134
查看次数