Search code examples
iosswiftavfoundationuistoryboardsegue

How to read a URL into an AVURLAsset


I am trying to create an AVURLAsset like so:

class TrimFootageViewController: UIViewController {
    var movieURL:URL?

    override func viewWillAppear(_ animated: Bool) {
        playerView.playerLayer.player = player

        super.viewWillAppear(animated)
        self.thumbnailImage = setThumbnailFrom(path: movieURL!)
        print(type(of: self.movieURL!))     
        asset = AVURLAsset(url: self.movieURL!, options: nil)
        print(asset ?? "couldn't get asset")

    }

This does not work throwing an Error (lldb) on a another class: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x100318b4c). Additionally it doesn't print the asset so I don't believe its being set right.

However when I use:

class TrimFootageViewController: UIViewController {
        var movieURL:URL?

        override func viewWillAppear(_ animated: Bool) {
            playerView.playerLayer.player = player

            super.viewWillAppear(animated)
            self.thumbnailImage = setThumbnailFrom(path: movieURL!)
            print(type(of: self.movieURL!))  
            guard let movieURL = URL(string: "https://devimages-cdn.apple.com/samplecode/avfoundationMedia/AVFoundationQueuePlayer_HLS2/master.m3u8") else {
            return
             }   
            asset = AVURLAsset(url: movieURL, options: nil)
            print(asset ?? "couldn't get asset")

        }

it works and correctly prints <AVURLAsset: 0x101b00210, URL = https://devimages-cdn.apple.com/samplecode/avfoundationMedia/AVFoundationQueuePlayer_HLS2/master.m3u8>

self.movieURL! and movieURL both have the same type of URL when printed. Also note that I am settings self.movieURL like so in the previous controller's segue:

override func prepare(for segue: UIStoryboardSegue, sender: Any?){
        if segue.identifier == "TrimFootage_Segue" {
            let controller = segue.destination as! TrimFootageViewController
            controller.movieURL = self.videoRecorded
        }
    }

how do I properly set the movieURL asset in the AVURLAsset call such that it can be instantiated?


Solution

  • By looking at your code it seems like movieURL is filePath as setThumbnailFrom(path: movieURL!) is working fine. May be this could be the reason.

    You can avoid crashing by applying if-let check as:

    class TrimFootageViewController: UIViewController {
        var movieURL: URL?
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            playerView.playerLayer.player = player   
    
            // Just check whether self.movieURL is filePath or URL
            // For "setThumbnailFrom" passing as file path
            // For "AVURLAsset(url: movURL, options: nil)" passing as URL
    
            self.thumbnailImage = setThumbnailFrom(path: self.movieURL!) // Passing as filePath 
    
            if let movURL = self.movieURL as? URL, let asset = AVURLAsset(url: movURL, options: nil) {
                print(asset)
            } else {
                print("Not able to load asset")
            }
        }
    } 
    

    Make sure you are sending URL from previous screen:

    let controller = segue.destination as! TrimFootageViewController
    controller.movieURL = self.videoRecorded