Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 944
NKurapati Avatar asked Jun 08 '15 17:06

NKurapati


7 Answers

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.

like image 116
XueYu Avatar answered Oct 02 '22 17:10

XueYu


@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()

}
like image 33
Aayushi Avatar answered Oct 02 '22 17:10

Aayushi


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)
}
like image 25
Shakeel Ahmed Avatar answered Oct 04 '22 17:10

Shakeel Ahmed


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)
    }
}
like image 42
Giang Avatar answered Oct 01 '22 17:10

Giang


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)
}
like image 40
bluemobi Avatar answered Oct 04 '22 17:10

bluemobi


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)
}
like image 37
V.Kumar Avatar answered Oct 03 '22 17:10

V.Kumar


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

like image 26
ion Avatar answered Oct 04 '22 17:10

ion