Reputation: 312
I have a video chat messaging app using AVFoundation
and Firebase
to record, store, and playback 1 minute-length videos.
Everything works accordingly, but there is a...
Ideally...
AVPlayer
where the loading and play happen only when the method .play()
is invoked.Firebase Storage
work where once the network call to upload the video is first triggered, the app can enter the background and still complete?I am admittedly a complete beginner in managing videos and I haven't found any concrete guides on how to eliminate or optimize the reduction of the delay for a better UX (i.e. Instagram playing and uploading an Instagram video story). Any help would be appreciated..
func playVideo(with outputFileURL: URL) {
DispatchQueue.main.async {
self.setView(view: self.progressBar, hidden: true)
self.progressBar.progress = 0
let asset = AVAsset(url: outputFileURL)
let item = AVPlayerItem(asset: asset)
self.avPlayer.replaceCurrentItem(with: item)
let previewLayer = AVPlayerLayer(player: self.avPlayer)
previewLayer.frame = self.view.bounds
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.previewView.layer.addSublayer(previewLayer)
self.view.layoutIfNeeded()
self.avPlayer.play()
}
}
func uploadVideo(_ url: URL) {
let filename = "x"
let ref = Storage.storage().reference().child("videos").child("xyz").child(filename)
let uploadTask = ref.putFile(from: url, metadata: nil, completion: { (_, err) in
if let err = err {
print("Failed to upload movie:", err)
return
}
ref.downloadURL(completion: { (downloadUrl, err) in
if let err = err {
print("Failed to get download url:", err)
return
}
guard let downloadUrl = downloadUrl else { return }
if let thumbnailImage = self.thumbnailImageForFileUrl(url) {
self.uploadToFirebaseStorageUsingImage(thumbnailImage, completion: { (imageUrl) in
print("saved video url: \(downloadUrl) and saved image url: \(imageUrl)")
})
}
})
})
uploadTask.observe(.progress) { (snapshot) in
print("In Progress")
}
uploadTask.observe(.success) { (snapshot) in
print("Done")
}
}
func thumbnailImageForFileUrl(_ fileUrl: URL) -> UIImage? {
let asset = AVAsset(url: fileUrl)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true
do {
let thumbnailCGImage = try imageGenerator.copyCGImage(at: CMTimeMake(value: 2, timescale: 60), actualTime: nil)
return UIImage(cgImage: thumbnailCGImage)
} catch let err {
print(err)
}
return nil
}
Upvotes: 1
Views: 172
Reputation: 312
As a temporary workaround, I looked into compressing the file.
The upload is much faster, but the quality is worse, which ideally should not have to be compromised.
If anyone has a better solution, would really appreciate and love to hear it!
Upvotes: 0