Posso obter o URI absoluto do vídeo no rolo da câmera e modificá-lo no meu aplicativo?

8

Quero executar uma operação em um vídeo no rolo da câmera do iphone e preciso de um URI absoluto, pois usarei o ffmpeg nativamente no meu aplicativo.

É possível operar o vídeo no local? ou precisaria copiar o vídeo para um diretório tmp, operá-lo e depois gravar novamente no rolo da câmera?

hunterp
fonte

Respostas:

7

Li alguns documentos e tutoriais e respondi abaixo com base nessa pesquisa.

É possível operar o vídeo no local?

Sim (copiando-o para temp dir) e Não (para o local original onde o vídeo está realmente armazenado)

Veja a imagem a seguir e cite documentos oficiais

insira a descrição da imagem aqui

Usando o PhotoKit, você pode buscar e armazenar em cache ativos para exibição e reprodução, editar conteúdo de imagem e vídeo ou gerenciar coleções de ativos, como álbuns, momentos e álbuns compartilhados.

Não temos acesso direto ao local em que a imagem / vídeo é armazenada. Em vez disso, obtemos dados brutos ou representação usando objetos PHAsset e Asset que são imutáveis, por isso não podemos executar operações diretamente nele. Nós precisaríamos do PHAssetChangeRequest para criar, excluir, alterar os metadados ou editar o conteúdo de um ativo do Fotos.

precisaria copiar o vídeo para um diretório temporário, operá-lo e depois gravar novamente no rolo da câmera?

Sim, esse é o caminho a percorrer.

Sahil Manchanda
fonte
Obviamente, um usuário pode editar uma imagem / vídeo no local; será solicitado um alerta ao usuário dizendo para confirmar as alterações. Veja a classe PHAsset.
K4747Z
4
@ K4747Z Concordou. Mas com isso, eu quis dizer diretamente ao local original onde o vídeo está realmente armazenado.
Sahil Manchanda
Mas se tentarmos substituir o vídeo editado, na hora de excluir o vídeo não editado, ele solicitará permissão para excluir photos, certo? ...... o que pode parecer estranho, você não acha?
Nayan Dave 12/02
2
@NayanDave, não precisamos excluir o vídeo original. se você olhar para a classe PHAssetChangeRequest, eles mencionaram "editar o conteúdo do recurso Fotos" e este é o nosso caso: edite o vídeo. para que o usuário seja solicitado apenas uma vez.
Sahil Manchanda
1
Bam obrigado !!
hunterp 16/02
3

Se você já buscou os ativos e o objeto PHFetchResult, tente:

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

        }

Ou, se você estiver usando o imagePicker padrão, podemos obter o URL do vídeo tmp usando:

 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

    }
K4747Z
fonte
0

Eu implemento algo assim no meu projeto, espero que ajude você.

Eu mostro todos os itens na visualização de coleção e realizo ações na seleção. Você também pode obter o URL do vídeo selecionado

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

}

Espero que funcione para você ... :)

Shivam Parmar
fonte