swift video to document directory

2019-07-13 06:19发布

问题:

I need to save video captured with UIImagePicker to a custom folder in app document directory

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    picker.dismissViewControllerAnimated(true, completion: nil)
    if let fileURL = info[UIImagePickerControllerMediaURL] as? NSURL {
        if let videoData = NSData(contentsOfURL: fileURL) {
            //save file to doc dir or save NSData into Core Data binary field

        }
    }
}

alternatively I can save videoData in Core Data binary field with external storage but after I can't play the video with media player because I can't convert NSData to NSURL.

回答1:

Try this for Swift 3

    var uniqueVideoID = ""
    var videoURL:NSURL? = NSURL()
    var uniqueID = ""

    //Add this to ViewDidLoad
    uniqueID = NSUUID().UUIDString


    //Getting the path as URL and storing the data in myVideoVarData.
            videoURL = info[UIImagePickerControllerMediaURL] as? URL as NSURL?
        let myVideoVarData = try! Data(contentsOf: videoURL! as URL)

        //Now writeing the data to the temp diroctory.
        let tempPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let tempDocumentsDirectory: AnyObject = tempPath[0] as AnyObject
            uniqueVideoID = uniqueID  + "TEMPVIDEO.MOV"
        let tempDataPath = tempDocumentsDirectory.appendingPathComponent(uniqueVideoID) as String
            try? myVideoVarData.write(to: URL(fileURLWithPath: tempDataPath), options: [])

        //Getting the time value of the movie.
        let fileURL = URL(fileURLWithPath: tempDataPath)
        let asset = AVAsset(url: fileURL)
        let duration : CMTime = asset.duration
            videoAlertIdVar = duration.value // Control for the runVideoAlert function.

        //Now we remove the data from the temp Document Diroctory.
        do{
        let fileManager = FileManager.default
        try fileManager.removeItem(atPath: tempDataPath)
        } catch {
            //Do nothing
        }

        // Cheacking to see if video is under the 18500 (:30 seconds).
        if duration.value <= 18500 {
           yesOrNo = "no" //Control for the button in the mainViewController is hidden or not. The default is "yes"

        //Here we are writing the data to the Document Directory for use later on.
        let docPaths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentsDirectory: AnyObject = docPaths[0] as AnyObject
            uniqueVideoID = uniqueID  + "VIDEO.MOV"
        let docDataPath = documentsDirectory.appendingPathComponent(uniqueVideoID) as String
            try? myVideoVarData.write(to: URL(fileURLWithPath: docDataPath), options: [])
            print("docDataPath under picker ",docDataPath)

        //This creates a thumbnail image.
        let assetImageGenerate = AVAssetImageGenerator(asset: asset)
            assetImageGenerate.appliesPreferredTrackTransform = true
        let time = CMTimeMake(asset.duration.value / 3, asset.duration.timescale)

         //This adds the thumbnail to the imageview.
        if let videoImage = try? assetImageGenerate.copyCGImage(at: time, actualTime: nil) {
            videoThumbnailOutlet.image = UIImage(cgImage: videoImage)
          }
        }else{
            //Do nothing
   }

Play the video

    //Note: The _videoData_ is the same as the _uniqueID_
    var videoData = ""

     func play (){

    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let documentsDirectory = paths[0]

    let videoDataPath = documentsDirectory + "/" + videoData + "VIDEO.MOV"

    let filePathURL = URL(fileURLWithPath: videoDataPath)


    let player = AVPlayer(url: filePathURL)
    let playerController = AVPlayerViewController()
        playerController.player = player
    self.present(playerController, animated: true) {
        player.play()


    }
}


回答2:

Try this. Swift 2.2

    var uniqueVideoID = ""
    var videoURL: NSURL? = NSURL()
    var uniqueID = ""

    //Add this to ViewDidLoad
    uniqueID = NSUUID().UUIDString

            //Getting the path as URL and storing the data in myVideoVarData.
        videoURL = info[UIImagePickerControllerMediaURL] as? NSURL
        let myVideoVarData = NSData(contentsOfURL: videoURL!)!

        //Now writeing the data to the temp diroctory.
        let tempPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
        let tempDocumentsDirectory: AnyObject = tempPath[0]
            uniqueVideoID = uniqueID  + "TEMPVIDEO.MOV"
        let tempDataPath = tempDocumentsDirectory.stringByAppendingPathComponent(uniqueVideoID)
            myVideoVarData.writeToFile(tempDataPath, atomically: false)

        //Getting the time value of the movie.
        let fileURL = NSURL(fileURLWithPath: tempDataPath)
        let asset = AVAsset(URL: fileURL)
        let duration : CMTime = asset.duration


        //Now we remove the data from the temp Document Diroctory.
        do{
        let fileManager = NSFileManager.defaultManager()
        try fileManager.removeItemAtPath(tempDataPath)
        } catch {
            //Do nothing
        }

        // Cheacking to see if video is under the 18500 (:30 seconds).
        if duration.value <= 18500 {


        //Here we are writing the data to the Document Directory for use later on.
        let docPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
        let documentsDirectory: AnyObject = docPaths[0]
            uniqueVideoID = uniqueID  + "VIDEO.MOV"
        let docDataPath = documentsDirectory.stringByAppendingPathComponent(uniqueVideoID)
            myVideoVarData.writeToFile(docDataPath, atomically: false)
            print("docDataPath under picker ",docDataPath)

        //This creates a thumbnail image.
        let assetImageGenerate = AVAssetImageGenerator(asset: asset)
            assetImageGenerate.appliesPreferredTrackTransform = true
        let time = CMTimeMake(asset.duration.value / 3, asset.duration.timescale)

         //This adds the thumbnail to the imageview.
        if let videoImage = try? assetImageGenerate.copyCGImageAtTime(time, actualTime: nil) {
            videoThumbnailOutlet.image = UIImage(CGImage: videoImage)
          }
        }else{
            //Do nothing
   }

Now play the video.

    //Note: The _videoData_ is the same as the _uniqueID_
    var videoData = ""


    func play (){

    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentsDirectory = paths[0]

    let videoDataPath = documentsDirectory + "/" + videoData + "VIDEO.MOV"

    let filePathURL = NSURL.fileURLWithPath(videoDataPath)


    let player = AVPlayer(URL: filePathURL)
    let playerController = AVPlayerViewController()
        playerController.player = player
    self.presentViewController(playerController, animated: true) {
        player.play()


    }
    }