Record Video and upload to Firebase - ios

Anybody know how to upload a video to firebase?
I used this link: record video in swift
I managed to record and have a playback in same view Gif of my video on giphy
The code to play the video I just recorded is:
#IBAction func playVideo(sender: AnyObject) {
print("Play a video")
// Find the video in the app's document directory
let paths = NSSearchPathForDirectoriesInDomains(
NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let documentsDirectory: AnyObject = paths[0]
let dataPath = documentsDirectory.stringByAppendingPathComponent(saveFileName)
let videoAsset = (AVAsset(URL: NSURL(fileURLWithPath: dataPath)))
let playerItem = AVPlayerItem(asset: videoAsset)
print(playerItem)
let videoView = UIView(frame: CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.width, self.view.bounds.height))
let pathURL = NSURL.fileURLWithPath(dataPath)
moviePlayer = MPMoviePlayerController(contentURL: pathURL)
if let player = moviePlayer {
player.view.frame = videoView.bounds
player.prepareToPlay()
player.scalingMode = .AspectFill
videoView.addSubview(player.view)
}
moviePlayer!.view.frame = videoPreview.bounds
moviePlayer!.view.center = CGPointMake(CGRectGetMidX(videoPreview.bounds), CGRectGetMidY(videoPreview.bounds))
videoPreview.addSubview((moviePlayer?.view)!)
}
And I know how to upload a PICTURE to Firebase I need to use NSStringlike this:
var base64String : NSString!
//let pic = UIImagePNGRepresentation(UIImage(named: "3")!)
let picture = UIImageJPEGRepresentation(self.profilePictureImageView.image!, 0.1)!
self.base64String = picture.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
let updatedProfileInfo = [
"provider": USER_REF.authData.provider,
"email": self.emailTextfield.text!,
"Username": self.usernameTextfield.text!,
"ProfilePicture" : self.base64String,
"ProfileDescription" : self.bioDescriptionTextfield.text
]
USER_REF.updateChildValues(updatedProfileInfo)
But how do you do with videos?
Thank you

This was my solution on using the UIImagePicker object class to select a video or image in my device and upload it to Fireabase:
#IBAction func uploadButton(_ sender: Any) {
// Configuration
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
picker.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String]
// Present the UIImagePicker Controller
present(picker, animated: true, completion: nil)
}
// The didFinishPickingMediaWithInfo let's you select an image/video and let's you decide what to do with it. In my example, I decided to convert the selected data into video and upload it to Firebase Storage
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL {
// we selected a video
print("Here's the file URL: ", videoURL)
// Where we'll store the video:
let storageReference = FIRStorage.storage().reference().child("video.mov")
// Start the video storage process
storageReference.putFile(videoURL as URL, metadata: nil, completion: { (metadata, error) in
if error == nil {
print("Successful video upload")
} else {
print(error?.localizedDescription)
}
})
}
//Dismiss the controller after picking some media
dismiss(animated: true, completion: nil)
}

Related

Unable to generate thumbnail from video in gallery

I'm displaying to the user an image picker to select a video from the gallery. That works, i pass the mediatype ["public.movie"] and all the videos of the gallery are displayed to pick up. When the user picks it i receive in my dellegate:
extension VNInventoryCollectionVC: UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let info = convertFromUIImagePickerControllerInfoKeyDictionary(info)
if let pickedImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.originalImage)] as? UIImage
{
pickImageCallback?(pickedImage)
}
if let videoURL = info["UIImagePickerControllerReferenceURL"] as? URL
{
print(videoURL)
pickImageCallback?(videoURL)
}
dismiss(animated: true)
}
}
After the callback i'm trying to create a image thumbnail from that video, and that is where i'm not able to do it:
let thumbnail = getThumbnailFrom(path: multimedia.video!)
cell.image.image = thumbnail
The function that generates the thumbnail is:
func getThumbnailFrom(path: URL) -> UIImage? {
do {
print("Video URL: \(path)")
print("Video absolute URL: \(path.absoluteURL)")
//let asset = AVURLAsset(url: path.absoluteURL! , options: nil)
var asset : AVAsset = AVAsset(url: path.absoluteURL) as! AVAsset
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
let thumbnail = UIImage(cgImage: cgImage)
return thumbnail
} catch let error {
print("*** Error generating thumbnail: \(error.localizedDescription)")
return nil
}
}
In the console the video url displayed is:
Video URL: assets-library://asset/asset.MP4?id=84D1CEDD-7AE4-4FE5-897E-47608DC2CFF0&ext=MP4
Video absolute URL: assets-library://asset/asset.MP4?id=84D1CEDD-7AE4-4FE5-897E-47608DC2CFF0&ext=MP4
The displayed error is that is unable to open the file. The line that breaks is:
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
I suppose the problem is with the url, that i have an assets url and i would require an absolute file path or something like that.
Use UIImagePickerController.InfoKey.mediaURL to key into the info dictionary. UIImagePickerController.InfoKey.referenceURL is deprecated.
func didSelectVideo(at url: URL) {
let asset = AVAsset(url: url)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
let cgImage = try! generator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
let thumbnail = UIImage(cgImage: cgImage)
cell.image.image = thumbnail
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
dismiss(animated: true) {
guard let url = info[.mediaURL] as? URL else { return }
self.didSelectVideo(at: url)
}
}

Generating thumbnail from Video ends up always rotated in an UIImageView

I'm using UIImagePickerController to select a video or an image from the user's gallery. With the photos, there's no problem, everything is displayed the way it should be. The problem comes when I'm trying to generate a thumbnail for a video.
Basically, the thumbnail image could end up being displayed upside down or 90 degrees to the left or right. I'm not sure why it happens. Am I missing something or doing something wrong?
extension PostVC : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let videoUrl = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
if let thumbnail = self.generateThumbnailForImage(videoUrl) {
self.videoUrl = videoUrl
self.photoImageView.image = thumbnail
self.selectedImage = thumbnail
}
}
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
selectedImage = image
photoImageView.image = image
shareButton.isEnabled = true
}
dismiss(animated: true, completion: nil)
}
func generateThumbnailForImage(_ fileUrl: URL) -> UIImage? {
let asset = AVAsset(url: fileUrl)
let imageGenerator = AVAssetImageGenerator(asset: asset)
do {
let thumbnailCGImage = try imageGenerator.copyCGImage(at: CMTimeMake(value: 1, timescale: 10), actualTime: nil) // 1 sec
return UIImage(cgImage: thumbnailCGImage)
} catch let err {
SVProgressHUD.showError(withStatus: err.localizedDescription)
}
return nil
}
}
It seems like setting the imageGenerator.appliesPreferredTrackTransform = true solves this issue.

Swift 4 didFinishPickingMediaWithInfo save image

I am using UIImagePickerController to use my camera like so:
#objc func toggle() {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
//Define UIImagePickerController variable
let imagePicker = UIImagePickerController()
//Assign the delegate
imagePicker.delegate = self
//Set image picker source type
imagePicker.sourceType = .camera
//Allow Photo Editing
imagePicker.allowsEditing = true
//Present camera
UIApplication.topViewController()?.present(imagePicker, animated: true, completion: nil)
}
}
Now I am trying to capture the image taken using the didFinishPickingMediaWithInfo method, I got this example online:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageUrl = info[UIImagePickerControllerOriginalImage] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
let image = info[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
do
{
try data?.write(to: localPath!, options: Data.WritingOptions.atomic)
}
catch
{
// Catch exception here and act accordingly
}
UIApplication.topViewController()?.dismiss(animated: true, completion: nil);
}
But I changed UIImagePickerControllerReferenceURL to UIImagePickerControllerOriginalImage as UIImagePickerControllerReferenceURL is nil. but after I change that I get this fatal error:
Could not cast value of type 'UIImage' (0x1b6b02b58) to 'NSURL'
How do I save the image take from the camera? What am I doing wrong?
Write your code as following this will give you image.
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
UIImagePickerControllerOriginalImage return image not NSURL
Write following code to get image url in iOS 11. From iOS 11 UIImagePickerControllerImageURL is available, earlier there are UIImagePickerControllerMediaURL key to get image url.
if #available(iOS 11.0, *) {
if let imageURL = info[UIImagePickerControllerImageURL] as? URL {
print(imageURL)
}
} else {
if let imageUrl = info[UIImagePickerControllerMediaURL] as? URL {
print(imageUrl)
}
}
I hope this will help you.
The one who are searching for complete method to implement for Swift 4.2+
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
imageView.image = pickedImage
}
imgPicker.dismiss(animated: true, completion: nil)
}
This will return you the original image according to new syntax
For Image URL and Media URL, Use the respective
let imgURL = info[UIImagePickerController.InfoKey.imageURL]
let mediaURL = info[UIImagePickerController.InfoKey.mediaURL]

How to play video file from documentdirectory using avplayer

I am creating video player application in ios,if i store mp4 file in bundle resource or if i stream url it is working fine but if i store a file in document direcory and i am trying to play with avplayer it is not playing should i handle differently with offline file in document directory
code:
let fileManager = FileManager()
let destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/myvideo.mp4"))
self.playVideo(filePath: destinationURLForFile.path)
func playVideo(filePath:String)
{
var playerItem = AVPlayerItem.init(url:URL.init(string: filePath)!)
var player = AVPlayer(playerItem: playerItem)
var playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.frame
self.view.layer.addSublayer(playerLayer)
player.play()
}
Try this, written in Swift 3.0,
let fm = FileManager.default
let docsurl = try! fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let path = docsurl.appendingPathComponent("myvideo.mp4")
playVideo(filePath: path)
func playVideo(filePath:String)
{
var playerItem = AVPlayerItem(url: URL(fileURLWithPath: filePath)
var player = AVPlayer(playerItem: playerItem)
var playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.frame
self.view.layer.addSublayer(playerLayer)
player.play()
}
swift 3/4 100%%%%%%% workable
Recorder open video camera
#IBAction func RecordAction(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera){
print("CameraAvailable")
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = true
self.present(imagePicker,animated: true, completion: nil)
}
else{
print("CameraNotAvailable")
}
}
save to document directory
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// recover video URL
let url = info[UIImagePickerControllerMediaURL] as? URL
// check if video is compatible with album
let compatible: Bool = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum((url?.path)!)
// save
if compatible {
UISaveVideoAtPathToSavedPhotosAlbum((url?.path)!, self, nil, nil)
print("saved!!!! \(String(describing: url?.path))")
}
videopath = url //save url to send next function play video
dismiss(animated: true, completion: nil)
}
// error
func video(_ videoPath: String, didFinishSavingWithError error: Error?, contextInfo: UnsafeMutableRawPointer) {
}
play video from Document directory
#IBAction func playvideo(_ sender: Any)
{
let player = AVPlayer(url: videopath!) // video path coming from above function
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
I tried several methods including the above, but found that the documents path changes for the app each time it is launched, which changes the first part of the URL.
This helped me to get the current location of my file:
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let playerItem = AVPlayerItem(url: URL(fileURLWithPath: documentsPath.appendingFormat("/\(clipId).mp4")))
player = AVPlayer(playerItem: playerItem)

Swift: AVPlayerViewController will not play video from device

URL
// What prints below for selectedMedia.videoPath
file:///private/var/mobile/Containers/Data/Application/9A7E21B7-81E7-4F4A-97FB-019AB99A3407/tmp/trim.4B1C07A3-0139-4AC3-B6DE-EB90F8CF582D.MOV
CODE
// From UIPickerViewController didFinishPickingMediaWithInfo
// To Populate a media
media.videoPath = info[UIImagePickerControllerMediaURL] as? URL
// To Load Player
self.selectedMedia = self.media[indexPath.row]
if self.selectedMedia?.isVideo == true {
let moviePlayer = AVPlayerViewController()
moviePlayer.delegate = self
print(self.selectedMedia!.videoPath!)
let url = URL(fileURLWithPath: self.selectedMedia!.videoPath! )
let player = AVPlayer(url: url)
moviePlayer.player? = player
self.present(moviePlayer, animated: true, completion: {
player.play()
})
}
else {
self.showMediaImage()
}
// Result of above code = AVPlayerViewController is displayed with no content.
QUESTION
Why is the video not playing?

Resources