[英]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.