2017-12-06 16 views
0

PHAsset 개체에서 URL (file : ///var/mobile/Media/DCIM/100APPLE/IMG_0840.MOV)을 검색 중이며 동영상을 재생할 수 있습니다. 장치에 잘. 그러나, Firebase Storage에/putfile을 업로드 할 때가되면, 완성 된 Handler를 다시 얻지 못합니다.IOS 용 Firebase 스토리지가 카메라 롤에서 .MOV를 업로드하지 않습니다.

//requesting url from asset 
    PHImageManager.default().requestAVAsset(forVideo: asset, options: options, resultHandler: { (videoAsset, audioMix, info) in 

      if let assetURL = videoAsset as? AVURLAsset { 

       let url = assetURL.url 

       //upload from url 
      let storageRef = Storage.storage().reference().child("videos").child("\(memory.ID!)") 
      let uploadMetaData = StorageMetadata() 
      uploadMetaData.contentType = "video/quicktime" 
       self.storageRef.putFile(from: url, metadata: uploadMetaData) { (metaData, error) in 

       if error != nil { 
        print(error!.localizedDescription) 
       } 
      } 

내가 (파일과 같은 로컬 URL로 AVFoundation 캡처에서 .MP4 파일을 업로드하고있어 경우 : /// VAR/모바일/용기/데이터/응용 프로그램/209BB017-13C7-4432-AFE4- EC3A13469900/Documents/ff49bbc9ac794ed28d6f25944f128933.mp4) 제대로 작동합니다.

또한 Firebase Storage 콘솔에서 .MOV 파일을 업로드하려고 시도했는데 작동합니다.

답변

1

때때로 PHAssets가 URLAsset 우리를 반환하지 않습니다

덕분에 우리는 주어진 자산이 AVURLAsset 여부를 확인해야하며, 그렇지 않으면 우리는 우리의 문서 디렉토리에이 자산을 저장하고 문서 디렉토리의 URL을 받아야합니다.

func uploadVideoToFirebase(content: PHAsset) { 
    let options = PHVideoRequestOptions() 
    options.isNetworkAccessAllowed = true 
    PHImageManager.default().requestAVAsset(forVideo: content, options: options) { (asset, mix, args) in 
     if let asset = asset as? AVURLAsset { 
      let url = asset.url 
      // URL OF THE VIDEO IS GOT HERE 
     } else { 
      guard let asset = asset else {return} 
      self.startAnimating(message: "Processing.") 
      self.saveVideoInDocumentsDirectory(withAsset: asset, completion: { (url, error) in 
       if let error = error { 
        print(error.localizedDescription) 
       } 
       if let url = url { 
        // SAVED IN DOCUMENTS DIRECTORY AND URL IS GOT HERE 
       } 
      }) 
     } 
    } 
} 

문서 디렉토리에 저장 : 우리는 그 다음 앱 시작시 성공적인 업로드하거나 선택을 취소 한 후이 원하지 않는 비디오를 삭제해야

func saveVideoInDocumentsDirectory(withAsset asset: AVAsset, completion: @escaping (_ url: URL?,_ error: Error?) -> Void) { 
    let manager = FileManager.default 
    guard let documentDirectory = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {return} 
    var outputURL = documentDirectory.appendingPathComponent("output") 
    do { 
     try manager.createDirectory(at: outputURL, withIntermediateDirectories: true, attributes: nil) 
     let name = NSUUID().uuidString 
     outputURL = outputURL.appendingPathComponent("\(name).mp4") 
    }catch let error { 
     print(error.localizedDescription) 
    } 
    //Remove existing file 
    _ = try? manager.removeItem(at: outputURL) 
    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetMediumQuality) else {return} 
    exportSession.outputURL = outputURL 
    exportSession.outputFileType = AVFileTypeMPEG4 
    exportSession.exportAsynchronously { 
     switch exportSession.status { 
     case .completed: 
      print("exported at \(outputURL)") 
      completion(outputURL, exportSession.error) 
     case .failed: 
      print("failed \(exportSession.error?.localizedDescription ?? "")") 
      completion(nil, exportSession.error) 
     case .cancelled: 
      print("cancelled \(exportSession.error?.localizedDescription ?? "")") 
      completion(nil, exportSession.error) 
     default: break 
     } 
    } 
} 

. 나는 다음 앱에서이 방법을 사용하여 시작했다.

func clearDocumentsDirectory() { 
    let manager = FileManager.default 
    guard let documentDirectory = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {return} 
    let outputURL = documentDirectory.appendingPathComponent("output") 
    //Remove existing file 
    _ = try? manager.removeItem(at: outputURL) 
} 

희망이 도움이됩니다.