如何将视频(在图库中)转换为NSData?在斯威夫特

时间:2015-10-17 16:39:25

标签: ios swift swift3

我只是没有" info"在Swift imagePickerController中,所以我不知道如何获取url并将其转换为数据以发送到Web服务。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {

  var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL!
  var videoFileURL = videoDataURL.filePathURL
  var video = NSData.dataWithContentsOfMappedFile("\(videoDataURL)")
}

3 个答案:

答案 0 :(得分:6)

Xcode 8.3•Swift 3.1

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
    let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    if let fileURL =  info[UIImagePickerControllerMediaURL] as? URL {
        do {
            try  FileManager.default.moveItem(at: fileURL, to: documentsDirectoryURL.appendingPathComponent("videoName.mov")
            print("movie saved")
        } catch {
            print(error)
        }
    }
}

Swift 2

如果让我们打开您的选项,您应该使用。 iOS [8}也弃用NSData.dataWithContentsOfMappedFile。尝试使用NSData方法初始化程序contentsOfURL:

注意:您还需要将didFinishPickingMediaWithInfo声明从[NSObject : AnyObject]更改为[String : AnyObject]

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    if let fileURL = info[UIImagePickerControllerMediaURL] as? NSURL {
        if let videoData = NSData(contentsOfURL: fileURL) {
            print(videoData.length)
        }
    }
}
如上所述,Rob的数据可能非常大,但不是复制文件,而是应该将文件移动到文档文件夹,如下所示:

let documentsDirectoryURL =  try! NSFileManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
if let fileURL =  info[UIImagePickerControllerMediaURL] as? NSURL {
    do {
        try  NSFileManagerdefaultManager().moveItemAtURL(fileURL, toURL: documentsDirectoryURL.URLByAppendingPathComponent("videoName").URLByAppendingPathExtension("mov"))
        print("movie saved")
    } catch {
        print(error)
    }
}

答案 1 :(得分:4)

有几个问题:

  1. 考虑这一行:

    var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL!
    

    这会强制展开info[UIImagePickerControllerMediaURL](这很糟糕,因为如果它是nil,应用程序会崩溃)并将其强制转换为隐式展开的可选NSURL!。这没有意义。只需进行条件展开(并展开到NSURL,而不是NSURL!):

    if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL { ... }
    
  2. 下一行调用filePathURL

    var videoFileURL = videoDataURL.filePathURL
    

    如果您想要一个文件网址,那么您已经拥有一个文件网址,因此无需转换,只需使用videoDataURL即可。如果您真的想要一条路径,请使用path方法:

    let videoPath = videoDataURL.path
    

    坦率地说,Apple正试图让我们远离使用字符串路径,因此只需使用原始videoDataURL并避免同时使用pathfilePathURL

    < / LI>
  3. 您正在使用dataWithContentsOfMappedFile

    var video = NSData.dataWithContentsOfMappedFile("\(videoDataURL)")
    

    如果你真的想使用dataWithContentsOfMappedFile,那么正确的Swift语法是:

    let video = NSData(contentsOfMappedFile: videoPath!)
    

    dataWithContentsOfMappedFile已弃用,因此您应该使用:

    let video = try NSData(contentsOfFile: videoPath!, options: .DataReadingMappedIfSafe)
    

    或者,完全绕过videoPath,你可以:

    let video3 = try NSData(contentsOfURL: videoDataURL, options: .DataReadingMappedIfSafe)
    

    显然,这些try版本应该在do块内catch块内完成。

  4. 顺便说一下,正如您在上面的所有示例中看到的那样,应尽可能使用let

  5. -

    坦率地说,我建议不要将它加载到NSData。只需使用NSFileManager复制它,这是一种更有效的内存使用。如果视频很长,它可能会很大,你应该避免在任何给定的时间点将整个内容加载到内存中。

    所以你可以:

    if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL {
        do {
            // build your destination URL however you want
            //
            // let tempFolder = NSURL(fileURLWithPath: NSTemporaryDirectory())
            // let destinationURL = tempFolder.URLByAppendingPathComponent("test.mov")
    
            // or 
    
            let documents = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
            let destinationURL = documents.URLByAppendingPathComponent("test.mov")
    
            // but just copy from the video URL to the destination URL
    
            try NSFileManager.defaultManager().copyItemAtURL(videoDataURL, toURL: destinationURL)
        } catch {
            print(error)
        }
    }
    

    如果您要将此内容上传到网络服务,则可以使用NSURLSessionUploadTask,使用文件或信息流选项。这个请求的构建是一个单独的问题,但希望你能得到这样的想法:对于像照片这样的大型资产,特别是视频,如果你可以避免它,就不要用资产实例NSData

答案 2 :(得分:0)

选择视频后将调用此方法

id 
title