簡體   English   中英

我可以在相機膠卷上獲取視頻的絕對 URI 並從我的應用程序中對其進行變異嗎?

[英]Can I get absolute URI of video on camera roll and mutate it from my app?

我想對 iphone 相機膠卷中的視頻執行操作,我需要一個絕對 URI,因為我將在我的應用程序中本地使用 ffmpeg。

是否可以就地對視頻進行操作? 或者我是否需要將視頻復制到 tmp 目錄,對其進行操作,然后寫回相機膠卷?

我已經閱讀了一些文檔和教程,並根據該研究進行了回答。

是否可以就地對視頻進行操作?

是(通過將其復制到臨時目錄)和否(到實際存儲視頻的原始位置)

看看下面的圖片並引用官方文檔

在此處輸入圖片說明

使用 PhotoKit,您可以獲取和緩存用於顯示和播放的資產、編輯圖像和視頻內容或管理資產集合,例如相冊、時刻和共享相冊。

我們無法直接訪問存儲圖像/視頻的位置,而是使用PHAsset獲取原始數據或表示,並且 Asset 對象是不可變的,因此我們無法直接對其執行操作。 我們需要PHAssetChangeRequest來創建、刪除、更改照片資產的元數據或編輯照片資產的內容。

我是否需要將視頻復制到臨時目錄,對其進行操作,然后寫回相機膠卷?

是的,這就是要走的路。

如果您已經獲取了資產,並且有 PHFetchResult 對象,請嘗試:

var video = PHAsset() // the video to be edited 

 if video.canPerform(.content) {  // check if the selected PHAsset can be edited

  video.requestContentEditingInput(with: nil, completionHandler: { editingInput, _ in

  let videoAsset = editingInput?.audiovisualAsset // get tracks and metadata of the video and start editing
  let videoURL = (videoAsset as? AVURLAsset)?.url // This might be nil so better use videoAsset

        /*
         Start editing your video here


        */

  guard let input = editingInput else { return }
  let output = PHContentEditingOutput(contentEditingInput: input)
  let outputURL = output.renderedContentURL // URL at which you write/export the edited video, it must be a .mov file
  let editedVideo = NSData()  // suppose your video fileName is editedVideo.mov, I used NSData since I don't know what final edited object will be.
  editedVideo.write(to: outputURL, atomically: false)

  PHPhotoLibrary.shared().performChanges({
  let changeRequest = PHAssetChangeRequest(for: video)
  changeRequest.contentEditingOutput = output
               })
            })

        }

或者,如果您使用默認的 imagePicker,我們可以使用以下方法獲取 tmp 視頻 url:

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

    let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as! NSURL
    print(videoURL)  // file is already in tmp folder


     let video = info[UIImagePickerController.InfoKey.phAsset] as! PHAsset
        // implement the above code using this PHAsset 

   // your will still need to request photo library changes, and save the edited video and/or delete the older one

    }

我在我的項目中實現了這樣的東西,希望對你有所幫助。

我在收藏視圖中顯示所有項目並對選擇執行操作,您還可以獲取所選視頻的網址

func getVideoFromCameraRoll() {
    let options = PHFetchOptions()
    options.sortDescriptors = [ NSSortDescriptor(key: "creationDate", ascending: false) ]
    options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
    videos = PHAsset.fetchAssets(with: options)
    videoLibraryCV.reloadData()
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return videos.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    let asset = videos!.object(at: indexPath.row)
    let width: CGFloat = 150
    let height: CGFloat = 150
    let size = CGSize(width:width, height:height)
    cell.layer.borderWidth = 0.5
    cell.layer.borderColor = UIColor.lightGray.cgColor
    PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: PHImageContentMode.aspectFit, options: nil)
    {   (image, userInfo) -> Void in

        let imageView = cell.viewWithTag(1) as! UIImageView
        imageView.image = image

        let labelView = cell.viewWithTag(2) as! UILabel
        labelView.text = String(format: "%02d:%02d",Int((asset.duration / 60)),Int(asset.duration) % 60)
    }
    return cell
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
 let asset = photos!.object(at: indexPath.row)
 guard(asset.mediaType == PHAssetMediaType.Video)
 else {
  print("Not a valid video media type")
  return
 }

 PHCachingImageManager().requestAVAssetForVideo(asset, options: nil, resultHandler: {
  (asset: AVAsset ? , audioMix : AVAudioMix ? , info : [NSObject: AnyObject] ? ) in
  let asset = asset as!AVURLAsset
  print(asset.URL) // Here is video URL
 })

}

我希望它對你有用...:)

暫無
暫無

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

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