Могу ли я получить абсолютный URI видео на рулон камеры и изменить его из моего приложения? - PullRequest
8 голосов
/ 06 февраля 2020

Я хочу выполнить операцию с видео в ролике iphone, и мне требуется абсолютный URI, поскольку я буду использовать ffmpeg в своем приложении.

Возможно ли работать с видео на месте? или мне нужно будет скопировать видео в tmp dir, поработать с ним, а затем записать обратно в рулон камеры?

Ответы [ 3 ]

7 голосов
/ 11 февраля 2020

Я прочитал несколько документов и учебных пособий и ответил ниже на основе этого исследования.

Можно ли работать с видео на месте?

Да (скопировав его в temp dir) и Нет (в исходное место, где фактически хранится видео)

Взгляните на следующее изображение и цитату из официальных документов

enter image description here

Используя PhotoKit, вы можете извлекать и кэшировать ресурсов для отображения и воспроизведения, редактировать изображения и видеоконтент или управлять коллекциями ресурсов, такими как альбомы, моменты и общие альбомы.

У нас нет прямого доступа к месту, где хранится изображение / видео, вместо этого мы получаем необработанные данные или представление, используя PHAsset и объекты Asset являются неизменяемыми, поэтому мы не можем выполнять операции непосредственно над ним. Нам потребуется PHAssetChangeRequest для создания, удаления, изменения метаданных или редактирования содержимого ресурса Photos.

, если мне потребуется скопировать видео во временную папку, работать с ним, а затем записать обратно в рулон камеры?

Да, это путь к go.

3 голосов
/ 10 февраля 2020

Если вы уже получили активы и у вас есть объект 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
               })
            })

        }

Или если вы используя defaultPicker по умолчанию, мы можем получить URL видео tmp используя:

 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 голосов
/ 10 февраля 2020

Я реализую нечто подобное в своем проекте, надеюсь, это поможет вам.

Я показываю все элементы в виде коллекции и выполняю действия по выделению, вы также можете получить 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
 })

}

Надеюсь, это сработает для вас ...:)

...