2 Replies
      Latest reply: Dec 12, 2017 2:37 PM by hgnd RSS
      giuscapo Level 1 Level 1 (0 points)

        Hi everyone!

         

        I'm developing an application that will show a stream video feed (Instagram like feed) and I was thinking about how to make it.

        Actually I am using a CollectionViewController and instantiating AVPlayers inside each cell.

        I'm also managing pause/resume task on scroll view scrolling.

         

        Videos come from cdn and are m3u8 format (for HLS).

        When I play with

        let player = AVPlayer(url: videoURL)
        

        Everything works good.

         

        But what I really need is to cache this video in order to improve performance and reactivity.

         

        I tried with AVAssetDownloadURLSession, following this guide https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/MediaPlaybackGuide/Contents/Resources/en.lproj/HTTPLiveStreaming/HTTPLiveStreaming.html

         

        Strange behavior: the first time I launched the app, it worked! Now, it does not.

        I also found out that downloading is not monitored (print (percentageComplete) does not work!)

         

        This is the code I used:

        func setupAssetDownload(url:URL) {
                /
                let configuration = URLSessionConfiguration.background(withIdentifier: "streamVideo")
               
                /
                let downloadSession = AVAssetDownloadURLSession(configuration: configuration,
                                                            assetDownloadDelegate: self,
                                                            delegateQueue: OperationQueue.main)
               
                let asset = AVURLAsset(url: url)
               
                /
                let downloadTask = downloadSession.makeAssetDownloadTask(asset: asset,
                                                                         assetTitle: "",
                                                                         assetArtworkData: nil,
                                                                         options: nil)
                /
                downloadTask?.resume()
            }
           
            func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didLoad timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange) {
                var percentComplete = 0.0
                /
                for value in loadedTimeRanges {
                    /
                    let loadedTimeRange = value.timeRangeValue
                    /
                    percentComplete += loadedTimeRange.duration.seconds / timeRangeExpectedToLoad.duration.seconds
                }
                percentComplete *= 100
                print("Percent complete \(percentComplete)")
                /
            }
           
            func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
                /
                UserDefaults.standard.set(location.relativePath, forKey: "assetPath")
            }
        

         

        What's wrong with this code?

         

        Thanks for your help, it's very urgent!

        • Re: Save HLS m3u8 on disk - Swift
          lucien Level 1 Level 1 (0 points)

          I have the same problem.

           

          I've download the demo from Apple and noticed that the download there is not working also.

          AVAssetDownloadDelegate methods are not called after task.resume().

           

          If you send the asset directly to AVPlayerViewController, the video plays without problem.

          • Re: Save HLS m3u8 on disk - Swift
            hgnd Level 1 Level 1 (0 points)

            without seeing the entire code, it's hard to tell where the issue is.

            I would suggest implmenting

            func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
            

             

            and see if it gets called.