カメラロールのビデオの絶対URIを取得して、アプリから変更できますか?


8

iphoneカメラロールでビデオの操作を実行したいのですが、アプリ内でffmpegをネイティブで使用するため、絶対URIが必要です。

その場でビデオを操作することは可能ですか?または、ビデオをtmpディレクトリにコピーして操作し、カメラロールに書き戻す必要がありますか?

回答:


7

私はいくつかのドキュメントとチュートリアルを読み、その研究に基づいて以下に回答しました。

その場でビデオを操作することは可能ですか?

はい(一時ディレクトリにコピーする)といいえ(ビデオが実際に保存されている元の場所に)

次の画像を見て、公式ドキュメントから引用してください

ここに画像の説明を入力してください

PhotoKitを使用すると、表示と再生のためにアセットをフェッチしてキャッシュしたり、画像やビデオのコンテンツを編集したり、アルバム、モーメント、共有アルバムなどのアセットのコレクションを管理したりできます。

画像や動画が保存されている場所に直接アクセスすることはできません。代わりに、PHAssetを使用して生データまたは表現を取得します。Assetオブジェクトは不変であるため、直接操作することはできません。Photosアセットのメタデータを作成、削除、変更、または編集するには、PHAssetChangeRequestが必要です

ビデオを一時ディレクトリにコピーして操作し、カメラロールに書き戻す必要がありますか?

うん、それは行く方法です。


もちろん、ユーザーは画像/動画をその場で編集できます。ユーザーには、変更を確認するよう警告する警告が表示されます。PHAssetクラスを参照してください。
K4747Z

4
@ K4747Z同意した。しかし、それで、ビデオが実際に保存されている元の場所を直接意味しました。
Sahil Manchanda

しかし、編集した動画を入れ替えようとすると、未編集の動画を削除する際に、削除の許可を求めてくるphotosんですよね・・・奇妙に見えるかもしれませんね?
Nayan Dave、

2
@NayanDave元のビデオを削除する必要はありません。PHAssetChangeRequestクラスを見ると、彼らは「写真アセットのコンテンツを編集する」と述べていて、これが私たちの場合です:ビデオを編集します。そのため、ユーザーは一度だけプロンプトが表示されます。
Sahil Manchanda

1
バムありがとう!!
ハンタープ

3

すでにアセットをフェッチしていて、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 video 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

    }

0

私はこのようなものを私のプロジェクトに実装します。

コレクションビューにすべてのアイテムを表示し、選択時にアクションを実行します。選択したビデオのURLを取得することもできます

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

}

私はそれがあなたのために働くことを願っています... :)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.