2017-12-06 8 views
0

PHAssetオブジェクトからURL(file:///var/mobile/Media/DCIM/100APPLE/IMG_0840.MOV)を取得していて、ビデオを再生できるデバイス上で細かい。しかし、Firebase Storageに/ putfileをアップロードする時が来たら、私はcompletionHandlerを返すことさえできません。 /// VAR /モバイル/コンテナ/データ/アプリケーション/ 209BB017-13C7-4432-AFE4-: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) 
       } 
      } 

私はAVFoundationから.MP4ファイルをアップロードしていた場合には、このようなローカルURLで(ファイルを取り込みます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) 
} 

これが役立ちます。

関連する問題