使用 Swift 从 iOS 中的 PhotoLibrary 中选择视频

Posted

技术标签:

【中文标题】使用 Swift 从 iOS 中的 PhotoLibrary 中选择视频【英文标题】:Select video from PhotoLibrary in iOS using Swift 【发布时间】:2015-06-08 17:11:21 【问题描述】:

我正在尝试使用以下代码从 PhotoLibrary 中选择视频

imageController.mediaTypes = [kUTTypeMovie: NSString]

选择视频后,压缩时出现数组超出边界的问题。

我在网上搜索并找到以下行。我无法将其转换为 Swift 版本 (link) imageController.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil]

请让我们知道上述行的 Swift 版本。如果有人能提供this 的Swift 版本,那将非常有用。

问题2

我想在应用中显示选定的视频,并且需要在点击时播放。我们可以在没有外部插件和使用内置库的情况下做到这一点吗?

【问题讨论】:

【参考方案1】:

基于 Swift 2.2

假设你有一个 imagePickerController,当你想同时选择图像和视频时:

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)    

然后在选择视频后,打印出它的 NSURL。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) 
  videoURL = info["UIImagePickerControllerReferenceURL"] as? NSURL
  print(videoURL)
  imagePickerController.dismissViewControllerAnimated(true, completion: nil)

对于问题 2:

是的,你可以通过 AVPlayer 来实现,你需要导入 AVKit 和 AVFoundation,你的代码可能是这样的:

if let videoURL = videoURL
  let player = AVPlayer(URL: videoURL)

  let playerViewController = AVPlayerViewController()
  playerViewController.player = player

  presentViewController(playerViewController, animated: true) 
    playerViewController.player!.play()
  

我在这里做了一个demo,你可以参考,也许不是100%你想要的。

【讨论】:

是否可以将视频保存在我们的应用程序本身中?这样他们就可以从应用程序本身的快捷方式直接查看视频,而不是一次又一次地选择它。【参考方案2】:
@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)

对于问题 2:

let player = AVPlayer(url: videoURL)
let playerController = AVPlayerViewController()
playerController.player = player
self.present(playerController, animated: true) 
    player.play()


【讨论】:

这真的帮助了我。非常感谢。【参考方案3】:

Swift 5+ 解决方案:

func openVideoGallery() 
    picker = UIImagePickerController()
    picker.delegate = self
    picker.sourceType = .savedPhotosAlbum
    picker.mediaTypes = ["public.movie"]      
    picker.allowsEditing = false
    present(picker, animated: true, completion: nil)

【讨论】:

不要使用 mediaType "public.movi​​e",而是考虑导入 UniformTypeIdentifiers,然后使用 UTType.movi​​e.identifier。【参考方案4】:

斯威夫特 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)
    

【讨论】:

将 info[UIImagePickerControllerMediaURL] 更改为 info[UIImagePickerController.InfoKey.mediaURL]【参考方案5】:
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)

【讨论】:

我已经尝试了所有这些。压缩视频后应用程序自动关闭。找不到问题。【参考方案6】:

使用 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)
    

【讨论】:

【参考方案7】:

Swift 4.0

你的类采用 UIImagePickerControllerDelegate 协议

class classname: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate

之后你需要创建

let imagePickerController = UIImagePickerController()

在按钮的操作中添加这个:-

imagePickerController.sourceType = .photoLibrary

imagePickerController.delegate = self

imagePickerController.mediaTypes = ["public.image", "public.movie"]

present(imagePickerController, animated: true, completion: nil)

委托方法

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) 

 let videoURL = info["UIImagePickerControllerReferenceURL"] as? NSURL
 print(videoURL!)
 imagePickerController.dismiss(animated: true, completion: nil)

【讨论】:

【参考方案8】:

试试我做的这个豆荚:

https://github.com/jhonyourangel/ImagePickerWhatsApp

我正在为一个项目搜索类似的图像和视频选择器,但我找不到能够: 1. 拍照 2.从图书馆获取图片 3.注册视频 4. 从库中获取视频

当我在寻找时,我希望 facebook 或 mabe google 的 whatsup 有一个可以满足这种需求的 pod,我真的很喜欢 whatsapp 选择器,所以我创建了这个类似于 whatsapp 中的选择器。

先决条件

要使用 ImageVideoPicker,您需要 cocoapods 和已创建的 xCode 项目

安装

安装 cocoapods 应该足以在终端中运行 sudo gem install cocoapods 如果这不起作用,请转到cocoapods

然后将终端导航到您的项目文件夹,文件扩展名 .xcodeproj 所在的文件夹并运行 pod init 这将创建一个名为 Podfile 的文件 在编辑器中打开文件(sublimeText、xCode、atom、vim ...等)并在use_frameworks!之后添加下面的行

pod 'ImagePickerWhatsApp'

或 pod 'ImagePickerWhatsApp', :path => '/Users/aiu/Documents/cocoapods/ImagePickerWhatsApp'

然后只需在终端中运行pod install 并等待完成安装库

如何使用

import ImagePickerWhatsApp 添加到您的视图控制器类

然后你可以通过调用来调用选择器: 让 mp = ImageVideoPicker.makeVCFromStoryboard() self.present(mp, 动画: true, 完成: nil)

委托

要实现委托添加mp.delegate = self 和视图控制器的类的范围 所以你需要导入 ios Photos 框架import Photos

extension ViewController: ImageVideoPickerDelegate 
    func onCancel() 
        print("no picture selected")
    

    func onDoneSelection(assets: [PHAsset]) 
       print("selected \(assets.count) assets")
    

func onDoneSelection 返回一个资产数组,其中包含资产所在位置的信息:在设备、iTunes 库或 iCloud 上。

如果您只需要显示图像,您可以在集合视图中使用此代码或类似的东西,只需实现此代码和平

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
        
    

这将只显示缩略图,但很棒,因为它还显示实时照片和视频的缩略图

图像和视频作为数据

该库旨在用于通过网络发送图像或视频,而不是进行花哨的图像或视频编辑。但这并不意味着你不能。你可以做任何事情,因为它返回一个资产数组,但是你的工作是实现你需要的。

为了从资产中获取数据,ImageVideoPicker 有一种方法可以返回带有数据的完成处理程序。

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)
    

这就是全部 玩得开心

【讨论】:

是开源的,框架由一个主文件组成。只需在您的应用中实施 @StackUnderflow 我不相信您的评论在 *** 上占有一席之地。这是一种观点,实际上是错误的,而且是不必要的负面。 OP 正在为开源社区提供一个有用的软件,而 cocoapods 是一个非常成熟的包管理器。 @yspreen 我是操作:D 确实如此。之前这里还有一条评论,但我猜是因为违反社区准则而被删除。一切顺利!【参考方案9】:
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

【讨论】:

【参考方案10】:

针对当前版本的 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()
        
    )
)

【讨论】:

【参考方案11】:
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)

委托方法

func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) 
  self.dismissViewControllerAnimated(true, completion: nil)
  imageView.image = image

【讨论】:

我已经尝试了所有这些。压缩视频后应用程序自动关闭。找不到问题。 那个应用程序崩溃了吗?

以上是关于使用 Swift 从 iOS 中的 PhotoLibrary 中选择视频的主要内容,如果未能解决你的问题,请参考以下文章

使用 getdatainbackground 从 Parse 检索多个图像(IOS - Swift)

使用 Swift 3 在 iOS 10 中将图像从服务器加载到 Apple Map 中的注释视图

如何以编程方式从 iOS Swift 3 中的 XIB 推送和呈现给 UIViewController

如何从 iOS swift 中的日期获取 1 小时前?

无视频输出和 [MC] 从公共有效用户设置中读取。 Swift/iOS 11 中的错误

如何使用swift从ios应用程序调用苹果钱包