簡體   English   中英

如何將視頻(在圖庫中)轉換為 NSData? 在斯威夫特

[英]How to convert video (in gallery) to NSData? in Swift

我只是在 Swift imagePickerController 中沒有“信息”,所以我不知道如何獲取 url 並將其轉換為數據以發送到網絡服務。

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

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

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 • 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)
        }
    }
}

斯威夫特 2

你應該使用 if let 來解開你的選項。 此外NSData.dataWithContentsOfMappedFile已棄用 iOS8。 嘗試使用 NSData 方法初始值設定項 co​​ntentsOfURL:

注意:您還需要將 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. 考慮這一行:

     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

    如果你想要一個文件 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再現應該在帶有catch塊的do塊中完成。

  4. 順便說一句,正如您在我上面的所有示例中看到的那樣,應該盡可能使用let

——

坦率地說,我建議完全不要將其加載到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)
    }
}

如果您要將其上傳到 Web 服務,那么您將使用NSURLSessionUploadTask ,使用文件或流選項。 這個請求的構建是一個單獨的問題,但希望你能明白:對於像照片或特別是視頻這樣的大型資產,如果可以避免的話,不要用資產實例化NSData

選擇視頻后,此方法將被調用

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)
        }
        
        }
   
}

找到簡單的解決方案:

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)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM