5

我只是在 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)")
}
4

4 回答 4

7

Xcode 10 • Swift 4.2 或更高版本

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

Xcode 8.3 • 斯威夫特 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)
        }
    }
}

斯威夫特 2

您应该使用 if let 来解开您的选项。NSData.dataWithContentsOfMappedFileiOS8也被弃用了。尝试使用 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)
    }
}
于 2015-10-17T17:03:43.087 回答
7

有几个问题:

  1. 考虑这一行:

    var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL!
    

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

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

    var videoFileURL = videoDataURL.filePathURL
    

    如果你想要一个文件 URL,你已经有了一个,所以不需要转换,只需使用videoDataURL. 如果你真的想要一条路径,你会使用path方法:

    let videoPath = videoDataURL.path
    

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

  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尽可能使用。

--

坦率地说,我建议不要将其加载到 aNSData中。只需用 复制它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, using 文件或流选项。这个请求的构造是一个单独的问题,但希望你明白:对于像照片或特别是视频这样的大型资产,NSData如果可以避免的话,不要用资产实例化 a。

于 2015-10-17T17:14:48.010 回答
1

选择视频后,将调用此方法

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    picker.dismiss(animated: true, completion: nil)
    print("in here")
    if let pickedVideo = info[UIImagePickerController.InfoKey(rawValue: UIImagePickerController.InfoKey.mediaURL.rawValue)] as? URL {
            print(pickedVideo)
        do {
            print("Converted")
           // let VideoData = try Data(contentsOf: pickedVideo)
            uploadVideo(VideoData: try Data(contentsOf: pickedVideo), URL: pickedVideo)
            
        } catch let error {
            print(error.localizedDescription)
        }
        
        }
   
}
于 2020-12-30T17:05:49.990 回答
0

找到简单的解决方案:

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    self.dismiss(animated: true, completion: nil)
    // Using just the information key value
    if let url = info[.mediaURL] as? URL {
        // Do something with the URL
        print("Media URL : ",url)
        do {
            let videoData = try Data(contentsOf: url)
        }
        catch let error {
            print(error)
        }
    }
}
于 2021-11-21T05:47:21.757 回答