Auto capture video using Swift - ios

I'm working on this piece of code responsible for starting video recording on button click.
When I click the button camera view is opening but .startVideoCapture() function doesn't start recording.
I get this strange output every time button is pressed:
2015-08-19 16:48:09.588 Record Video With Swift[922:227442]
Snapshotting a view that has not been rendered results in an empty
snapshot. Ensure your view has been rendered at least once before
snapshotting or snapshot after screen updates.
Also, is there any way to hide the camera view and instead of it place there some progress bar or something?
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate
{
let captureSession = AVCaptureSession()
var previewLayer : AVCaptureVideoPreviewLayer?
var captureDevice : AVCaptureDevice?
var imagePicker = UIImagePickerController()
override func viewDidAppear(animated: Bool)
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
println("captureVideoPressed and camera available.")
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .Camera;
imagePicker.mediaTypes = [kUTTypeMovie!]
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = true
}
else
{
println("Camera not available.")
}
}
#IBAction func rec(sender: AnyObject)
{
self.presentViewController(imagePicker, animated: true, completion: nil)
imagePicker.startVideoCapture()
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
let tempImage = info[UIImagePickerControllerMediaURL] as! NSURL!
let pathString = tempImage.relativePath
self.dismissViewControllerAnimated(true, completion: {})
UISaveVideoAtPathToSavedPhotosAlbum(pathString, self, nil, nil)
}
}

I recently had this problem and in my case I was using Swift 3 with iOS 10. There are couple of ways to solve it:
You can call the startVideoCapture() in the completion block of present viewcontroller as following:
self.present(self.cameraController, animated: true, completion: {
self.cameraController.startVideoCapture()
if #available(iOS 10.0, *) {
Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { _ in
self.stopMovementsCapture()
}
} else {
// Fallback on earlier versions
Timer.scheduledTimer(timeInterval: 5,
target: self,
selector: #selector(self.stopMovementsCapture),
userInfo: nil,
repeats: false)
}
})
Another way to do is, is by calling startVideoCapture() only after the AVCaptureSessionDidStartRunning notification is fired.
Following is the code to observe the notification:
NotificationCenter.default.addObserver(self, selector: #selector(self.cameraIsReady), name: .AVCaptureSessionDidStartRunning, object: nil)
Following is function called by the above notification:
func cameraIsReady(notification: NSNotification) {
DispatchQueue.main.async {
self.cameraController.startVideoCapture()
if #available(iOS 10.0, *) {
Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { _ in
self.stopMovementsCapture()
}
} else {
// Fallback on earlier versions
Timer.scheduledTimer(timeInterval: 5,
target: self,
selector: #selector(self.stopMovementsCapture),
userInfo: nil,
repeats: false)
}
}
}
Basically make sure that your device is ready to capture the video. Hope this is helpful!

Try to change following:
1.
imagePicker.mediaTypes = NSArray(object: kUTTypeMovie) as! [String]
2.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let tempImage = info[UIImagePickerControllerMediaURL] as! NSURL!
let pathString = tempImage.relativePath
self.dismissViewControllerAnimated(true, completion: {})
UISaveVideoAtPathToSavedPhotosAlbum(pathString!, self, nil, nil)
}

Related

imagePickerController - didFinishPickingMediaWithInfo does not get called after picking media

converted app from swift 3 to swift 4.2.
my app had a upload your profile image feature that is not working anymore and I am trying to figure out why. For now What I see is that
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo
didFinishPickingMediaWithInfo Is not being called after media was chosen
Here is my views full code:
import UIKit
class CameraMenuViewController: BaseViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var UserID:Int = 0
#IBOutlet weak var myImageView: UIImageView!
var callback : ((UIImage) -> ())?
#IBOutlet weak var btn_end: UIButton!
#IBOutlet weak var from_camera: UIBarButtonItem!
#IBOutlet weak var from_gallery: UIBarButtonItem!
#IBAction func btn_end_pressed(_ sender: UIButton) {
//
//self.openViewControllerBasedOnIdentifier("Home")
//let data = UIImagePNGRepresentation(myImageView) as NSData?
let image = myImageView.image!.pngData() as NSData?
//if let data = UIImagePNGRepresentation(myImageView) {
print("callback data")
let userDetails:Dictionary = (UserDefaults.standard.value(forKey: "myUserDetails") as? [String:Any])!
let UserID:Int = userDetails["UserID"] as! Int
print("UserID")
print(UserID)
print("is_selfie from callback")
//save profile image as NewUserID
UserDefaults.standard.set(image, forKey: String(UserID))
UserDefaults.standard.synchronize()
self.view.removeFromSuperview()
//}
}
#IBAction func btn_closer(_ sender: UIButton) {
//self.view.removeFromSuperview()
}
#IBAction func photofromLibrary(_ sender: UIBarButtonItem) {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
picker.modalPresentationStyle = .popover
present(picker, animated: true, completion: nil)
picker.popoverPresentationController?.barButtonItem = sender
}
#IBAction func shootPhoto(_ sender: UIBarButtonItem) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
print("photo shoot")
//UserDefaults.standard.set("selfie", forKey: "is_selfie")
UserDefaults.standard.set(true, forKey: "is_selfie")
UserDefaults.standard.synchronize()
DispatchQueue.main.async {
self.picker.allowsEditing = false
self.picker.sourceType = UIImagePickerController.SourceType.camera
self.picker.cameraCaptureMode = .photo
self.picker.modalPresentationStyle = .fullScreen
self.present(self.picker,animated: true,completion: nil)
}
} else {
noCamera()
}
}
let picker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
picker.delegate = self
DispatchQueue.global(qos: .userInitiated).async
{
self.present(self.picker, animated: true, completion: nil)
}
let language = UserDefaults.standard.object(forKey: "myLanguage") as! String
if(language=="arabic"){
//from_camera.setTitle("كاميرا",for: .normal)
//from_gallery.text.setTitle("الصور",for: .normal)
btn_end.setTitle("إنهاء",for: .normal)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Delegates
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
let chosenImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.originalImage)] as! UIImage //2
myImageView.contentMode = .scaleAspectFit //3
myImageView.image = chosenImage //4
myImageView.layer.borderWidth = 1
myImageView.layer.masksToBounds = false
myImageView.layer.borderColor = UIColor.black.cgColor
myImageView.layer.cornerRadius = myImageView.frame.height/4
myImageView.clipsToBounds = true
callback?(chosenImage)
dismiss(animated:true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
}
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromUIImagePickerControllerInfoKey(_ input: UIImagePickerController.InfoKey) -> String {
return input.rawValue
}
Please help me understand why didFinishPickingMediaWithInfo isn't getting called anymore
It appears as though the function declaration changed between Swift 3 and 4.2. This mustn't have been updated for you by the Swift Migrator Tool. One trick I do when this happens, to check what the correct function declaration is, is to use multiline comment syntax to comment out your current function (didFinishPickingMediaWithInfo in your case). Then you can start typing the function out again, and use Xcode autocomplete to ensure you have it correct. You can then copy the contents of the function you commented out to this new and correct function declaration.
Or - you could just look it up the documentation! According to the documentation on imagePickerController, the function should be declared as:
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
If you replace your function declaration with the above, it should get called again.
As Craig said you need to change delegate function declaration and also afterwards you need to update the following:
let chosenImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
These two changes combined should solve your issue.
i think the name off the function is update
this is my code in My app And work greate
extension FCViewController: UIImagePickerControllerDelegate
{
internal func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
{
if let photo = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
}
// Any Code Here ...

How to sent imagedata with ImagePicker Controller using swift 4

I have tabbarController and CameraViewController. I want to show the camera after clicking on camera tab. I have done it. after open the camera i want to show that particular image selected to the next viewController, but unable to do it. i am using UIImagePickerController, please help
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
let tabBarIndex = tabBarController.selectedIndex
if tabBarIndex == 0 {
//do your stuff
print("First Tab")
} else if tabBarIndex == 1 {
print("Second Tab")
} else if tabBarIndex == 2 {
//do the camera stuff here
let imagePickerController1 = ImagePickerController()
imagePickerController1.delegate = self
imagePickerController1.imageLimit = 2
present(imagePickerController1,animated: true,completion: nil)
print("camera")
print("Third Tab")
}
}
Done button pressed code.
func doneButtonDidPress(_ imagePicker: ImagePickerController, images: [UIImage]) {
let firstVC = self.storyboard!.instantiateViewController(withIdentifier: "CameraVC") as! CameraVC
show(firstVC, sender: nil)
dismiss(animated: true, completion: nil)
print("done")
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info["UIImagePickerControllerOriginalImage"] as? UIImage {
}
dismiss(animated: true, completion: nil)
}
Your doneButtonDidPress method is implemented in TabBarController and you want selected Images in CameraVC so do 1 thing add NotificationCenter in CameraVC and Post that notification with Images array once you done with Image pick. and load selected images from that array in CameraVC.
CameraVC
NotificationCenter.default.addObserver(self, selector: #selector(updateSelectedImages(_:)), name: NSNotification.Name(rawValue: "updateSelectedImages"), object: nil)
#objc func updateSelectedImages(_ notification: Notification) {
let imagesInfo = notification.object as? NSDictionary
self.arrImages = imagesInfo?.value(forKey: "selectedIamges") as! [UIImage]
self.imageView.image = self.arrImages[0]
self.imageView1.image = self.arrImages[1]
}
UITabBarController
let dict = NSMutableDictionary()
dict.setValue(images, forKey: "selectedIamges")
NotificationCenter.default.post(name: NSNotification.Name("updateSelectedImages"), object: dict)

iOS 11 double tap on image dismisses UIImagePickerController and presenter view controller

We have a photo picker made with UIImagePickerController.
When making double tap (instead of one tap) the photo from gallery.
On iOS 10: UIImagePickerController is dismissed
On iOS 11: UIImagePickerController is dismissed and presenting view controller is dismissed as well :0
Is it iOS 11 bug or we have to adjust something?
Our code:
let vc = UIImagePickerController()
vc.delegate = self
vc.modalPresentationStyle = .overFullScreen
vc.allowsEditing = false
rootVC.present(vc, animated: true) // `rootVC` also presented modally.
Instead of self.dismiss(), use picker.dismiss()
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
//self.dismiss(animated: true, completion: nil)
picker.dismiss(animated: true, completion: nil)
}
This will only dismiss your picker view and not the view controller.
We end up with solution: Set delegate = nil right after delegate call in didFinishPickingMediaWithInfo.
public class ImagePicker: NSObject {
private lazy var viewController = setupActionSheet()
private var rootViewController: UIViewController?
private var completionHandler: (([String: Any]) -> Void)?
private var cancellationHandler: (() -> Void)?
}
extension ImagePicker {
public func present(on: UIViewController, completionHandler: #escaping (([String: Any]) -> Void)) {
rootViewController = on
self.completionHandler = completionHandler
cancellationHandler = nil
on.presentAnimated(viewController)
}
public func present(on: UIViewController,
completionHandler: #escaping (([String: Any]) -> Void),
cancellationHandler: #escaping (() -> Void)) {
rootViewController = on
self.completionHandler = completionHandler
self.cancellationHandler = cancellationHandler
on.presentAnimated(viewController)
}
}
extension ImagePicker {
private func setupActionSheet() -> UIAlertController {
let actionSheet = UIAlertController(actionSheetWithTitle: LocalizedString.Generic.ImagePicker.addPhoto)
if UIImagePickerController.isSourceTypeAvailable(.camera) {
actionSheet.addDefaultAction(LocalizedString.Generic.ImagePicker.takePhoto) { [weak self] _ in
self?.presentImagePicker(.camera)
}
}
actionSheet.addDefaultAction(LocalizedString.Generic.ImagePicker.selectPhoto) { [weak self] _ in
self?.presentImagePicker(.photoLibrary)
}
actionSheet.addCancelAction(LocalizedString.Generic.ButtonTitle.cancel) { [weak self] _ in
self?.cancellationHandler?()
}
return actionSheet
}
private func presentImagePicker(_ sourceType: UIImagePickerControllerSourceType) {
let vc = UIImagePickerController()
vc.delegate = self
vc.allowsEditing = false
vc.sourceType = sourceType
rootViewController?.present(vc, animated: true)
}
}
extension ImagePicker: UIImagePickerControllerDelegate {
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
picker.delegate = nil /// It prevents to call delegate when user taps on a few images very fast. seems iOS 11 issue only.
if picker.sourceType == .camera, let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
picker.dismiss(animated: true) {
self.completionHandler?(info)
}
}
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true) {
self.cancellationHandler?()
}
}
}
Usage:
// Somewhere in view controller code.
imagePicker = ImagePicker()
imagePicker?.present(on: self) { [weak self] in
self?.imagePicker = nil
self?.viewModel.addImage($0)
}

iOS camera freezes when previewing video when there is a camera overlay

I am attempting to overlay a view over a video capture session in UIImagePicker. The overlay works fine but when the app gets to the screen where the user can "retake", "play" or "use video", the app crashes and gives the error:
2017-04-16 21:33:04.129212-0400 ChugMug[429:59833] libMobileGestalt
MobileGestalt.c:2690: statfs(/mnt4): No such file or directory
2017-04-16 21:33:04.129871-0400 ChugMug[429:59833] libMobileGestalt
MobileGestalt.c:2587: SInt64 NANDSize(): No kIOMediaSizeKey found for
disk0! 2017-04-16 21:33:09.352085-0400 ChugMug[429:60065]
[MediaRemote] Error Operation requires a client callback to have been
registered. requesting playback queue
The code is quite simple, when the overlay is commented out, the video preview screen and buttons work fine, but when the overlay is present the app freezes at the following screen:
Here is the code for the camera and the overlay:
func startMediaBrowserFromViewController(viewController: UIViewController, usingDelegate delegate: UINavigationControllerDelegate & UIImagePickerControllerDelegate) -> Bool {
// 1
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) == false {
return false
}
// 2
let mediaUI = UIImagePickerController()
mediaUI.sourceType = .savedPhotosAlbum
mediaUI.mediaTypes = [kUTTypeMovie as NSString as String]
mediaUI.allowsEditing = true
mediaUI.delegate = delegate
// 3
present(mediaUI, animated: true, completion: nil)
return true
}
func startCameraFromViewController(viewController: UIViewController, withDelegate delegate: UIImagePickerControllerDelegate & UINavigationControllerDelegate) -> Bool {
if UIImagePickerController.isSourceTypeAvailable(.camera) == false {
return false
}
cameraController.sourceType = .camera
cameraController.mediaTypes = [kUTTypeMovie as NSString as String]
cameraController.allowsEditing = false
cameraController.delegate = delegate
cameraController.showsCameraControls = true
//customView stuff
let customViewController = CustomOverlayViewController(
nibName:"CustomOverlayViewController",
bundle: nil
)
let customView = customViewController.view //as! CustomOverlayView
customView?.frame = cameraController.view.frame
present(cameraController, animated: true, completion: {
self.cameraController.cameraOverlayView = customView
customViewController.cameraLabel.text = "Camera Label"
self.cameraController.startVideoCapture()
})
return true
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
dismiss(animated: true, completion: nil)
// Handle a movie capture
if mediaType == kUTTypeMovie {
guard let path = (info[UIImagePickerControllerMediaURL] as! NSURL).path else { return }
if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path) {
UISaveVideoAtPathToSavedPhotosAlbum(path, self, nil, nil)
}
}
}
I have no clue what is causing this strange error and cant find anything similar. I hope someone can help me.

Select video from PhotoLibrary in iOS using Swift

I am trying to select video from PhotoLibrary using following code
imageController.mediaTypes = [kUTTypeMovie: NSString]
After selecting video, when it is compressing, I am getting array out of boundary issue.
I searched online and found following line. I am unable to convert it into Swift version (link)
imageController.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil]
Please let us know the Swift version for above line. It is very useful if anyone can provide Swift version of this.
Question2:
I want to show selected video in app and need to play when it is tapped. Can we do it without external plugins and using built in libraries?
Based on Swift 2.2
Suppose you have a imagePickerController and when you want to select both images and videos:
let imagePickerController = UIImagePickerController()
var videoURL: NSURL?
#IBAction func selectImageFromPhotoLibrary(sender: UIBarButtonItem) {
imagePickerController.sourceType = .PhotoLibrary
imagePickerController.delegate = self
imagePickerController.mediaTypes = ["public.image", "public.movie"]
presentViewController(imagePickerController, animated: true, completion: nil)
}
Then after the video is selected, print out its NSURL.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
videoURL = info["UIImagePickerControllerReferenceURL"] as? NSURL
print(videoURL)
imagePickerController.dismissViewControllerAnimated(true, completion: nil)
}
For question 2:
Yes, you can do it through AVPlayer, you need import AVKit and AVFoundation, and you code may look like this:
if let videoURL = videoURL{
let player = AVPlayer(URL: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
presentViewController(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
I made a demo here you can refer, maybe not 100% what you want.
#IBOutlet weak var imgView: UIImageView!
var imagePickerController = UIImagePickerController()
var videoURL : NSURL?
#IBAction func btnSelectVideo_Action(_ sender: Any) {
imagePickerController.sourceType = .savedPhotosAlbum
imagePickerController.delegate = self
imagePickerController.mediaTypes = [kUTTypeMovie as String]
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
videoURL = info[UIImagePickerControllerMediaURL]as? NSURL
print(videoURL!)
do {
let asset = AVURLAsset(url: videoURL as! URL , options: nil)
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(0, 1), actualTime: nil)
let thumbnail = UIImage(cgImage: cgImage)
imgView.image = thumbnail
} catch let error {
print("*** Error generating thumbnail: \(error.localizedDescription)")
}
self.dismiss(animated: true, completion: nil)
}
For question 2:
let player = AVPlayer(url: videoURL)
let playerController = AVPlayerViewController()
playerController.player = player
self.present(playerController, animated: true) {
player.play()
}
Swift 5+ solution:
func openVideoGallery() {
picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .savedPhotosAlbum
picker.mediaTypes = ["public.movie"]
picker.allowsEditing = false
present(picker, animated: true, completion: nil)
}
Swift 3
import MobileCoreServices
var imagePickerController = UIImagePickerController()
var videoURL: URL?
private func openImgPicker() {
imagePickerController.sourceType = .savedPhotosAlbum
imagePickerController.delegate = self
imagePickerController.mediaTypes = ["public.movie"]
present(imagePickerController, animated: true, completion: nil)
}
extension YourViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
videoURL = info[UIImagePickerControllerMediaURL] as? URL
print("videoURL:\(String(describing: videoURL))")
self.dismiss(animated: true, completion: nil)
}
}
func openCamera() {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
println("captureVideoPressed and camera available.")
var imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .Camera
imagePicker.mediaTypes = [kUTTypeMovie!]
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = true
self.presentViewController(imagePicker, animated: true, completion: nil)
} else {
println("Camera not available.")
}
}
func imagePickerController( didFinishPickingMediaWithInfo info:NSDictionary!) {
videoUrl = info[UIImagePickerControllerMediaURL] as! NSURL!
let pathString = videoUrl.relativePath
self.dismissViewControllerAnimated(true, completion: nil)
}
Swift 4.0
Your class adopts the UIImagePickerControllerDelegate protocol
class classname: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate
After that you need to create
let imagePickerController = UIImagePickerController()
Add this in your button's action:-
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
imagePickerController.mediaTypes = ["public.image", "public.movie"]
present(imagePickerController, animated: true, completion: nil)
Delegate method
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let videoURL = info["UIImagePickerControllerReferenceURL"] as? NSURL
print(videoURL!)
imagePickerController.dismiss(animated: true, completion: nil)
}
Select a Video from Gallery using Swift 4
// Put this code where you want to pick the video from gallery
Let imagePickerController = UIImagePickerController ()
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
imagePickerController.mediaTypes = ["public.movie"]
present(imagePickerController, animated: true, completion: nil)
// UIImagePickerController Delegate Method
func imagePickerController (_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any])
{
let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL
print(videoURL!)
self.dismiss(animated: true, completion: nil)
}
try this pod that i've made :
https://github.com/jhonyourangel/ImagePickerWhatsApp
I was searching for a similar Image and Video Picker for a project and i wasn't able to find one that was able to :
1. Take picture
2. Get a Picture from the library
3. Register a Video
4. Get a video from the library
While i was looking i hopen whatsup of facebook or mabe google have a pod for this kind of needs, i realy liked the whatsapp picker, so i created this one similer to the one in whatsapp.
Prerequisites
In order to use ImageVideoPicker you need cocoapods and an xCode project already created
Installing
to install cocoapods is should be enough just to run sudo gem install cocoapods in the terminal
if this doen't work go to cocoapods
Then navigate the terminal to your project folder, where the file extension .xcodeproj is located and run pod init
this will create a file called Podfile
Open the file in a editor ( sublimeText, xCode, atom, vim ... etc ) and add the line bellow after use_frameworks!
pod 'ImagePickerWhatsApp'
or
pod 'ImagePickerWhatsApp', :path => '/Users/aiu/Documents/cocoapods/ImagePickerWhatsApp'
then just run pod install in the terminal and wait to finish instaling the lib
How to use it
add import ImagePickerWhatsApp to your viewcontroller class
then you can call the picker by calling :
let mp = ImageVideoPicker.makeVCFromStoryboard()
self.present(mp, animated: true, completion: nil)
Delegate
to implement the delegate add mp.delegate = self and the extent the class of you view controller
aso you need to import the iOS Photos framework import Photos
extension ViewController: ImageVideoPickerDelegate {
func onCancel() {
print("no picture selected")
}
func onDoneSelection(assets: [PHAsset]) {
print("selected \(assets.count) assets")
}
}
the func onDoneSelection returns an array of assets that contain the info of where the asset is located : on the device, iTunes library or iCloud.
if you just need to display the images you can use the this code in a collection view or something similar just implement this peace of code
var representedAssetIdentifier: String!
func getImageFrom(asset: Phasset) {
representedAssetIdentifier = asset?.localIdentifier
let imageManager = PHCachingImageManager()
imageManager.requestImage(for: asset!, targetSize: self.frame.size, contentMode: .default, options: nil) { (image, _) in
if(self.representedAssetIdentifier == self.asset?.localIdentifier &&
image != nil) {
self.imageView.image = image
}
}
}
this will show just the thumbnail, but is awesome because is also showing the thumbnail for live photos, and videos
Images and Videos as Data
The lib is intended to be used for sending images or videos over the network, and not to do fancy image or video editing. But this doesn't mea you can't. You can do just about anything since it returns an array of assets, but is you job to implement what you need.
in order to get the data from the asset ImageVideoPicker has one method that will return an completition handler with the data.
ImageVideoPicker.getDataFrom(asset: asset) { (data) in
if data == nil {
print(data as Any, asset.mediaType, asset.localIdentifier)
} else {
print(data!.count as Any, asset.mediaType, asset.localIdentifier)
}
}
that will be all
have fun
func startMediaBrowserFromViewController(viewController: UIViewController!, usingDelegate delegate : protocol<UINavigationControllerDelegate, UIImagePickerControllerDelegate>!) -> Bool {
if UIImagePickerController.isSourceTypeAvailable(.SavedPhotosAlbum) == false {
return false
}
let mediaUI = UIImagePickerController()
mediaUI.sourceType = .SavedPhotosAlbum
mediaUI.mediaTypes = [kUTTypeMovie as String]
mediaUI.allowsEditing = true
mediaUI.delegate = delegate
presentViewController(mediaUI, animated: true, completion: nil)
return true
}
Updated for the current version of Swift:
// Check if the asset is of video media type.
guard (asset.mediaType == PHAssetMediaType.video) else {
print("Not a valid video media type")
return
}
// Obtain the URL of the video.
PHCachingImageManager().requestAVAsset(forVideo: asset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) in
let asset = asset as! AVURLAsset
print("asset.url: ", asset.url) // Here is video URL
// Play the video.
DispatchQueue.main.async(execute: {
let player = AVPlayer(url: asset.url)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
})
})
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
println("Camera Available")
var imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
Delegate method
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
self.dismissViewControllerAnimated(true, completion: nil)
imageView.image = image
}

Resources