标签: nsurlsessiondownloadtask

下载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万
查看次数

通过NSURLSession/NSURLSessionDownloadTask下载完成时发送本地通知

我正在使用NSURLSessionDownloadTask对象NSURLSession允许用户在应用程序处于后台/设备锁定状态时下载文档.我还想告知用户个人下载已通过本地通知完成.

为此,我在-URLSession:downloadTask:didFinishDownloadingToURL:下载任务委托方法中触发本地通知,但是我想知道是否有更好的地方添加触发通知的代码,因为Apple解释它的方式,下载任务将传递给系统,从中我得出的是,一旦(或不久之后)应用程序背景化,下载任务的代理将不会再调用这些代理.

我的问题:添加触发本地通知的代码的最佳位置是什么?有没有人在他们的应用程序中添加这种功能有任何经验?

objective-c ios uilocalnotification nsurlsession nsurlsessiondownloadtask

11
推荐指数
1
解决办法
1946
查看次数

Swift:URLSessionDownload文件说它存在,但它不存在?

好的,我已成功下载各种m4a文件,并通过URLSession删除它们.我的问题是在URLSessionDownloadDelegate要求的最终"完成"功能中,我有时会将以下内容打印到控制台,即使我在下载func(下载之前)检查文件是否存在于目录中.非常困惑.这是消息:

File download succesfully
    “CFNetworkDownload_1wGgxs.tmp” couldn’t be moved to “Documents” because an item with the same name already exists.
    The task finished successfully
Run Code Online (Sandbox Code Playgroud)

这是下载功能,我检查显示文件是否存在:

func goDownload()
    {
        if let audioUrl = downloadUrl { //set at beginning

            let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
            print(destinationUrl)

            // to check if it exists before downloading it
            if FileManager.default.fileExists(atPath: destinationUrl.path) {
                print("********** The file already exists at path")

                // if the file doesn't exist
            } else {

                print("---------------> Starting Download") …
Run Code Online (Sandbox Code Playgroud)

ios nsurlsession nsurlsessiondownloadtask swift

11
推荐指数
1
解决办法
689
查看次数

如何检查NSData blob是否有效作为NSURLSessionDownloadTask的resumeData?

我有一个使用新NSURLSessionAPI 下载后台的应用程序.当下载以NSURLSessionDownloadTaskResumeData提供的方式取消或失败时,我存储数据blob以便以后可以恢复.我注意到野外崩溃的时间非常少:

Fatal Exception: NSInvalidArgumentException
Invalid resume data for background download. Background downloads must use http or https and must download to an accessible file.
Run Code Online (Sandbox Code Playgroud)

这里出现的错误,这里resumeDataNSDatablob和session是一个实例NSURLSession:

if (resumeData) {
    downloadTask = [session downloadTaskWithResumeData:resumeData];
    ...
Run Code Online (Sandbox Code Playgroud)

数据由Apple API提供,序列化,然后在以后进行反序列化.它可能已损坏,但它永远不会为零(如if语句检查).

如何提前检查resumeData无效,以免我让应用程序崩溃?

ios ios7 nsurlsession nsurlsessiondownloadtask

10
推荐指数
1
解决办法
4122
查看次数

Swift - 使用downloadTaskWithURL下载视频

我正在下载一个视频,感谢downloadTaskWithURL,我用这段代码将它保存到我的画廊:

    func saveVideoBis(fileStringURL:String){

    print("saveVideoBis");

    let url = NSURL(string: fileStringURL);
    (NSURLSession.sharedSession().downloadTaskWithURL(url!) { (location:NSURL?, r:NSURLResponse?, e:NSError?) -> Void in

        let mgr = NSFileManager.defaultManager()

        let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0];

        print(documentsPath);

        let destination = NSURL(string: NSString(format: "%@/%@", documentsPath, url!.lastPathComponent!) as String);

        print(destination);

        try? mgr.moveItemAtPath(location!.path!, toPath: destination!.path!)

        PHPhotoLibrary.requestAuthorization({ (a:PHAuthorizationStatus) -> Void in
            PHPhotoLibrary.sharedPhotoLibrary().performChanges({
                PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(destination!);
                }) { completed, error in
                    if completed {
                        print(error);
                        print("Video is saved!");
                        self.sendNotification();
                    }
            }
        })
    }).resume()
}
Run Code Online (Sandbox Code Playgroud)

它在我的模拟器上工作得非常好,但在我的iPad上,即使print("Video is saved!");显示,视频也不会保存.你知道为什么吗?

我的控制台中也出现了该消息

无法从文件创建数据(null)

iphone ipad ios nsurlsessiondownloadtask swift

10
推荐指数
1
解决办法
8849
查看次数

从完成处理程序中获取NSURLSession DownloadTaskWithRequest中的数据

所以我很难理解某些东西.这是我对NSURSession的理解:

  • 一般来说,我有2个选项(据我所知)DataTask(ex dataTaskWithRequest)DownloadTask(ex DownloadTaskWithRequest) - 使用他们的委托方法,使用完成处理程序,不能两者兼顾.我已经设法使用dataTaskWithRequest接收DATA,如下所示:

    let request = NSMutableURLRequest(URL: dataSourceURL!)
    request.HTTPMethod = "POST"
    
    let postString = "lastid=\(id)"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
    
        if error != nil {
            println("error=\(error)")
            return
        }
        if data != nil {
            println("works")
            //Handle data
    
    
        }
        //println("response = \(response)")
    
    
    }
    task.resume()      
    
    Run Code Online (Sandbox Code Playgroud)

它完美地运作.问题是我需要将数据下载到磁盘而不是下载到内存(我正在下载图像).所以我尝试使用DownloadTaskWithRequest +他的完成处理程序,我注意到他所采用的参数是相同的,期望第一个是NSURL,而DataTaskWithRequestNSData,因此它使事情变得非常简单.恩.

 let task2 = NSURLSession.sharedSession().downloadTaskWithRequest(request, completionHandler: { (location : NSURL!, response : …
Run Code Online (Sandbox Code Playgroud)

nsdata ios nsurlsession nsurlsessiondownloadtask swift

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

以优先顺序下载背景中的许多文件(照片,视频)

在应用程序的第一次启动我想从服务器下载所有文件,我想继续下载,即使用户离开应用程序(它不在前台).我需要下载的文件是缩略图,原始大小的照片,其他文件和视频.我想按照我之前写的顺序下载它们.

我正在使用Alamofire并设置会话管理器:

let backgroundManager: Alamofire.SessionManager = {
    let bundleIdentifier = "com....."
    return Alamofire.SessionManager(
      configuration: URLSessionConfiguration.background(withIdentifier: bundleIdentifier + ".background")
    )
  }()
Run Code Online (Sandbox Code Playgroud)

然后我像这样使用它:

  self.backgroundManager.download(fileUrl, to: destination)
    .downloadProgress { progress in
      //print("Download Progress: \(progress.fractionCompleted)")
    }
    .response(completionHandler: result)
Run Code Online (Sandbox Code Playgroud)

它在downloadPhoto方法中,我称之为:

for item in items {
      self.downloadPhoto(item: item, isThumbnail: true, shouldReloadData: false, indexPath: nil)
      self.downloadPhoto(item: item, isThumbnail: false, shouldReloadData: false, indexPath: nil)
}
Run Code Online (Sandbox Code Playgroud)

然后我可以添加文件下载和视频下载等呼叫.但所有这些请求具有相同的优先级,我想首先下载缩略图(因为这是用户最初看到的)然后下载全尺寸图像,然后下载所有图像,然后下载文件和视频.但所有必须在队列中,因为如果用户启动应用程序,然后将其设置为后台并将其保留几个小时,则必须全部下载.这可能吗?我怎么能这样做?

我正在寻找alamofire,它有组件库AlamofireImage,它具有基于优先级的下载,但图像只是我想要优先考虑的文件的一部分.感谢帮助

background ios nsurlsessiondownloadtask swift alamofire

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

NSURLSession后台下载无法正常工作

我正在尝试使用NSURL后台会话下载大量文件 nsurlsessiontask.当应用程序在调试模式下运行时(当设备连接到Xcode时),一切都像魅力一样,当从Xcode上拔下设备(iPad)时不起作用.

我正在使用Xcode 7.3.1和iOS 9.3.5.我已经花了几周时间跟踪这个奇怪的行为,但没有任何突破.可能是我遗漏了一些实现后台下载的东西.最近将Xcode升级到8.1.2,将iOS升级到10.2.1,假设升级可能会解决问题,但事实并非如此.

objective-c ipad ios nsurlsessiondownloadtask

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

如果应用程序从任务管理器中被杀死,NSUrlSession是否继续文件传输?

我已经尝试过网上的各种样本(最后一个是这个样本),以便更好地理解NSUrlSession.

我希望看到的内容:即使触发它们的应用程序被杀死(例如用户通过任务管理器),文件下载仍将继续.然而,这似乎并没有发生.

如果应用程序被终止,这是配置问题还是后台文件传输不起作用?我认为整个想法是iOS将重启应用程序.

objective-c ios nsurlsession nsurlsessiondownloadtask

8
推荐指数
1
解决办法
4104
查看次数

URLSessionDidFinishEventsForBackgroundURLSession Not Calling- Objective-C

NSURLSession委托方法
URLSessionDidFinishEventsForBackgroundURLSession不是Calling?

我已在项目功能设置中启用了后台模式.

这是代码

AppDelegate.h方法

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (nonatomic, copy) void(^backgroundTransferCompletionHandler)();

@end
Run Code Online (Sandbox Code Playgroud)

AppDelegate.m方法

-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{

    self.backgroundTransferCompletionHandler = completionHandler;

}
Run Code Online (Sandbox Code Playgroud)

ViewController.m方法

- (void)viewDidLoad
{
    [super viewDidLoad];
    //Urls
    [self initializeFileDownloadDataArray];

    NSArray *URLs = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    self.docDirectoryURL = [URLs objectAtIndex:0];

    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.GACDemo"];
    sessionConfiguration.HTTPMaximumConnectionsPerHost = 5;


    self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
                                                 delegate:self
                                            delegateQueue:nil];
}
Run Code Online (Sandbox Code Playgroud)

NSUrlSession方法

-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
    AppDelegate *appDelegate = [UIApplication …
Run Code Online (Sandbox Code Playgroud)

xcode objective-c ios nsurlsession nsurlsessiondownloadtask

8
推荐指数
1
解决办法
4949
查看次数