Select video from PhotoLibrary in iOS using Swift
Asked Answered
C

11

29

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?

Curricle answered 8/6, 2015 at 17:11 Comment(0)
P
43

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.

Pya answered 20/6, 2016 at 21:22 Comment(1)
Is it possible to save the video in our app itself? So that instead of selecting it again and again they can directly view the video from a shortcut from the app itself.Tundra
I
18

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)
}
Ideality answered 4/4, 2019 at 12:39 Comment(2)
Instead of using mediaType "public.movie", consider importing UniformTypeIdentifiers and then use UTType.movie.identifier.Mayenne
The UTType identifiers are only available in iOS 14 and later. It's not a big deal for most, but it does affect library maintainers that support older iOS versions.Displayed
G
17
@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()

}
Gun answered 7/4, 2017 at 7:58 Comment(1)
This really helped me out. Thank you so much.Gasify
G
12

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)
    }
}
Grammatical answered 21/7, 2017 at 3:16 Comment(1)
change info[UIImagePickerControllerMediaURL] to info[UIImagePickerController.InfoKey.mediaURL]Metallography
N
4

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)
    }
Nl answered 25/10, 2018 at 7:58 Comment(0)
D
3
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)
}
Desouza answered 8/6, 2015 at 18:32 Comment(1)
I already tried all these. Application is closing automatically after compressing video. Unable to find the issue.Curricle
N
3

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)
}
Nl answered 29/10, 2018 at 5:24 Comment(0)
S
1

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

Scourings answered 13/6, 2018 at 6:48 Comment(4)
is open source, the framework is made by one main file. just implement into your appScourings
@StackUnderflow I don't believe your comment has a place on StackOverflow. It's an opinion, factually wrong, and unnecessarily negative. OP is providing a useful piece of software to the open-source community and cocoapods is a very well-established package manager.Marjorymarjy
@Marjorymarjy i am the op :DScourings
That's true. There was another comment here before, but it was deleted for community guideline violations I guess. All good!Marjorymarjy
Q
0
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
}
Quattrocento answered 29/2, 2016 at 1:33 Comment(0)
I
0

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()
        }
    })
})
Integrate answered 20/10, 2017 at 4:42 Comment(0)
B
-1
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
}
Bores answered 8/6, 2015 at 19:22 Comment(2)
I already tried all these. Application is closing automatically after compressing video. Unable to find the issue.Curricle
is that App crashing ?Bores

© 2022 - 2024 — McMap. All rights reserved.