《IOS视频录制,本地视频播放,剪切,合并》系列(1)本地视频播放

前言:

Recently 公司项目里用到了一些视频的剪辑操作,所以就找了很多这方面的资料,发现了一个问题就是国内这方面的资料非常少 =_=|| ,有的也只是一些很基础的知识讲解和demo,能够运行不崩溃,并且可以匹配详细讲解让我们学习的demo太少了!因为公司里面的项目时间都会催得很紧,这个时候我们这些非常苦逼的工程师想要找到一个拿来就可以用的东西就更难了!

在一位前辈的指导下找到了一篇外国网站上的技术指导,把demo真机运行了一下发现非常好用,然后就想着把这篇篇幅很长的指导翻译过来,并且文章是2012年的了,很多方法都已经被废弃了,所以就想着改进一下,一步一步来吧,写一个系列博客,把这个文章的demo剖析一下。但是我自己对于demo的改动就不分享了,因为涉及到公司的商业机密。

原文翻译并coding演示:

原文链接如下:http://www.raywenderlich.com/13418/how-to-play-record-edit-videos-in-ios
题目是《How to Play, Record, and Edit Videos in iOS》

原文翻译:

这篇博客的原作者是我们ios指导团队成员Abdul Azeem,他/她是一家名为Datainvent Systems的提供IT服务的软件开发公司的工程师兼合作创立者。

这篇文章的修改和更正者是Joseph Neuman,更新于2012/8/14。

录制视频并且写一些视频编辑代码是你可以用你的iphone做的最酷的事情之一了,但是令人诧异的事情是只有非常非常少的app做了这方面的开发。

原因很简单,大家都知道,学习视频录制并在录制完成之后利用AVFoundation框架对视频进行编辑难度非常大。

更糟的是,没有多少可以供你参考的关于如何使用AVFoundation的技术文章。屈指可数的资源中有一篇是WWDC 2010 AVFoundation session video(可以去英文原文打开链接),但是这样的指导只能把你搞晕。

在这样恶劣的情况之下,本篇指导就横空出世了!(翻译略夸张)

在这篇指导中,我们会给你提供一个你拿来就可以用在你自己项目中的demo,这个demo用到的是AVFoundation的API。你将学会如何:

  • 从本地图库中选择视频并播放
  • 录制视频并保存到本地图库
  • 把多个视频合并成一个视频,而且可以添加配乐!:)

    准备好了吗?灯光,镜头,卡!

开始创建工程:

让我们一起来开发一个很简单的支持播放,录制,保存视频到本地的app吧!

打开XCode并且新建一个iOS\Application\Single View Application 类型应用。(我的测试环境是xcode7,ios9.1)输入“NewPlayVideo”作为工程名称,(我的示例工程名称是NewPlayVideo,原文有一些是过时的操作,我在这里就不翻译了,以我的新版本为准)。

这里写图片描述

下一步,向你的工程中添加一些必要的框架依赖。

当前面板分为左中右3块,选择左边栏的文件夹标志按钮,在工程导航中点击根目录即”NewPlayVideo”,这样中间栏会显示工程信息,如果工程TARGETS没有被选中,选中,接着切换到”Build Phases” tab页面。

现在点击”Link Binary With Libraries”旁边的小三角展开它。你就可以在这里向工程中添加依赖的库或者框架了。

这里写图片描述

点击(+)按钮添加框架,你可以选择点击添加多个框架。添加以下框架到你的工程中:
-AssetsLibrary
-AVFoundation
-CoreMedia
-MediaPlayer
-MobileCoreServices
-QuartzCore

在这个工程中,你将要创建有4个页面的app。第一个页面里有3个按钮,点击按钮导航到如下3个页面:
-Video Play
-Video Record
-Video Merge

进入正题:

选择MainStoryboard.storyboard,可以在右边栏看到默认绑定的class是MainViewController,你需要让MainViewController被嵌入到一个navigation controller中,因为我们的app是要多页面跳转的。

要嵌入到navigation controller中,首先点击选中storyboard,然后点击菜单中Editor\Embed In\Navigation Controller选项。现在,navigation Controller和MainViewController之间就有了一个连线。

接着,从Object Library(位于右边栏下半部分-如果Object Library没有被选中,那么它就是第3个tab选项,圆中带方的图标)拖拽3个UIButton到MainViewController中。当你把它们3个在你的view中摆放到让你自己满意得位置之后,就可以这样设置这些button的title了:
-Select and Play Video
-Record and Save Video
-Merge Video

你可以在点击按钮选中它的时候,在右边栏上方的第4个tab:属性设置中设置title属性。

接着,创建让3个按钮跳转的3个viewController。创建方式是创建iOS\Cocoa Touch\UIViewController的子类。分别命名为PlayVideoViewController, RecordVideoViewController, 和MergeVideoViewController。

现在打开MainStoryboard.storyboard并从Object Library拖拽3个UIViewController到你的storyboard。依次选中这些view controller然后在右边栏上方的第3个tab设置这些视图控制器对应的class name,设置如下:

  1. PlayVideoViewController
  2. RecordVideoViewController
  3. MergeVideoViewController

这里写图片描述

现在我们要把所有的这4个页面组合在一起形成一个完整框架,可以为每个按钮和它要加载的视图控制器之间创建一个连线。

选择连线的方式是选中按钮,按住control,拖动鼠标到对应的视图控制器,松开会出现一个黑色选择框,在框中选择show,如图:

这里写图片描述

这样为3个按钮和3个视图控制器就设置好了关联,如图:

这里写图片描述

干得不错哦,你已经搭好了基本的UI,现在来编译并运行一下,看看这三个按钮是否可以成功跳转到二级页面。

如果你不熟悉stroryboard,不知道如何搭建界面,不用担心,这里有一篇指导:Beginning Storyboards in iOS 5(可以跳到原文打开链接,但是现在版本已经是ios9了,所以建议可以上网找找最新的关于故事板的用法)。

现在UI已经搭好了,该为这些二级页面添加一些实质性的内容了!

Select and Play Video:(选取并播放视频)

切换到storyboard,在Play Video View Controller创建一个title为”Play Video”的按钮,并且为该按钮添加消息响应,步骤如下:(有改动,以我的xcode7版本为准)

1.在xcode窗口顶部右上方有两个小的工具栏,中间位置有一个两个圆圈相套的按钮,点击之后会出现一个view controller对应的.m文件,同时按住control,command,上下方向键会跳到对应的.h文件

2.然后在stroryboard中选中按钮,按住control键,拖动连线到.h文件中@end上面,松开鼠标会出现一个对话框,按照如图填写该对话框

这里写图片描述

(对话框中依次选择Action, Name填写playVideo)

3.最后点击”Connect”,生成消息响应函数。

你刚刚只是在PlayVideoViewController中定义了一个名为playVideo的消息响应函数,但是你还要实现这个消息响应函数。

在PlayVideoViewController.h上方引入如下头文件

#import <MobileCoreServices/UTCoreTypes.h>
#import <MediaPlayer/MediaPlayer.h>

MediaPlayer.h头文件提供了MediaPlayer类型对象,这个类型对象是用来播放视频的。UTCoreTypes.h定义了名为”kUTTypeMovie”的常量,在选择媒体的时候会用到。

现在添加如下代码到#import语句下面的@interface句尾:

<UIImagePickerControllerDelegate, UINavigationControllerDelegate>

这样,PlayVideoViewController就成为了UIImagePickerController, UINavigationController的代理,你就可以在PlayVideoController中使用UIImagePickerController了。具体来讲,就是你可以用UIImagePickerController在你的本地图库中浏览视频了。那么,苹果提供的UIImagePickerController类究竟是什么呢?它提供了一个选取图片,选取录制好的视频的基础可定制化的用户接口。它也提供了一些简单的编辑功能。如果你不需要完全自定义的UI,那么使用UIImagePickerController从媒体库中选取音视频文件比较好。

为了浏览媒体文件,你需要在顶层视图打开一个UIImagePickeController的实例。在PlayVideoViewController.h中添加一个方法的声明,添加到@end这一行上面。

// For opening UIImagePickerController
-(BOOL)startMediaBrowserFromViewController:(UIViewController*)controller usingDelegate:(id )delegate;

现在跳到PlayVideoViewController.m文件,并且添加如下代码到”playVideo”方法:

[self startMediaBrowserFromViewController:self usingDelegate:self];

以上代码确保了当点击到”PlayVideo”按钮的时候会打开UIImagePickerController,允许从本地媒体库中选择一个视频文件。

接下来,添加startMediaBrowserFromViewController的实现到文件末尾(但是在最后的@end上面):

-(BOOL)startMediaBrowserFromViewController:(UIViewController*)controller usingDelegate:(id )delegate {
    // 1 - Validations
    if (([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum] == NO)
        || (delegate == nil)
        || (controller == nil)) {
        return NO;
    }
    // 2 - Get image picker
    UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
    mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    mediaUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
    // Hides the controls for moving & scaling pictures, or for
    // trimming movies. To instead show the controls, use YES.
    mediaUI.allowsEditing = YES;
    mediaUI.delegate = delegate;
    // 3 - Display image picker
    [controller presentModalViewController:mediaUI animated:YES];
    return YES;
}

上面的代码做了这些事儿:

1.检查是否UIImagePickerControllerSourceTypeSavedPhotosAlbum源在本地设备上是可获取到的,这一步检查在当你用UIImagePickerController选取媒体文件时时至关重要的。如果你不这么做,也许你会从一个不存在的媒体库中选取媒体文件,就会导致应用程序崩溃或者其它无法料想的状况。

2.如果你想要获取的源是可以获取到的,你就创建一个UIImagePickerController对象并且设置它的源和媒体类型。如果你只要视频,那就只在mediaTypes 数组中包括kUTTypeMovie类型。如果你想选取图片,就可以在mediaTypes数组中添加kUTTypeImage类型。

3.最后,你在当前视图上方弹出一个UIImagePickerController。

现在你的工程又添加了非常炫目的功能!编译运行一下试试咯

如果你在本地媒体库中有视频文件,那么当你在首页点击”Select and Play Video”,接着在弹出的二级页面中点击”Play Video”的时候,你就可以看到它们被显示出来,就像下图一样:

这里写图片描述

注意:当你在模拟器上运行的时候,是无法获取到视频的。所以,你不得不找到向模拟器上添加视频到媒体库的方法。所以,我建议你还是在真机上运行测试。

当你看到这样的视频列表,选择一个。你将会会跳转到另外一个播放视频的页面,点击”Choose”按钮来选择。

如果你点击了”Choose”,但是然并卵,什么事情都没发生….除了app回到了显示着”Play Video”的页面!这是因为你并没有实现任何代理方法来执行你要完成的操作。

UIImagePickerController有一个回调代理方法可以执行当媒体被选中时候执行的操作。在PlayVideoViewController.m文件末尾添加如下代码来实现该代理方法:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
   // 1 - Get media type
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
    // 2 - Dismiss image picker
    [self dismissViewControllerAnimated:NO completion:nil];
    // Handle a movie capture
    if (CFStringCompare ((__bridge_retained CFStringRef)mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
        // 3 - Play the video
//        改变1
        AVPlayerViewController *theMovie = [[AVPlayerViewController alloc]init]
                                                 ;
//        改变2
        [theMovie setPlayer:[AVPlayer playerWithURL:[info objectForKey:UIImagePickerControllerMediaURL]]];


//        改变3
        [self presentViewController:theMovie animated:NO completion:nil];
        // 4 - Register for the playback finished notification

//       改变4 删除掉这个调用
//        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMovieFinishedCallback:)
//                                                     name:AVPlayerItemDidPlayToEndTimeNotification object:theMovie];
    }
}

注意 : 上面的这一段代码中用到播放器是MPMoviePlayerController,这个类在IOS 9.0中就已经被废弃,不推荐使用了,推荐使用的是AVPlayerViewController,所以我在代码中就使用AVPlayerViewController了。我代码中和原代码中不一样的地方我已标注。

以上代码的作用如下:
1. 获取到媒体类型从而可以确保被选取的文件是video
2. 关闭image picker
3. 当确认了被选取媒体类型为video后,创建一个AVPlayerViewController来播放该视频

最后一件事情就是当用户在image picker界面没有选取视频,只是点击了cancel按钮时候的消息响应,将以下代码添加到imagePickerController:didFinishPickingMediaWithInfo:方法后面:

// For responding to the user tapping Cancel.
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [self dismissModalViewControllerAnimated: YES];
}

添加了这个方法之后,当user点击了image picker界面的cancel按钮时候,image picker会退出。

现在可以编译并运行代码了,点击”Select and Play Video” 按钮,接着”Play Video”按钮,最后从列表中选择一个video,你可以选择截取该video的一部分来播放。
这里写图片描述

注意:原文中写了一个方法是在播放完成时候释放播放器的,但是经过我的修改和测试,发现该方法没有什么用,所以我就把这个方法注释掉了,大家在我的代码里面可以看到。可以去掉注释运行一下。。。。。。= =
(
//改变5 删除掉该方法
// When the movie is done, release the controller.
//-(void)myMovieFinishedCallback:(NSNotification*)aNotification {
// [self dismissViewControllerAnimated:NO completion:nil];
// 改变5
// AVPlayerViewController *theMovie = [aNotification object];
改变6
// [[NSNotificationCenter defaultCenter] removeObserver:self
// name:AVPlayerItemDidPlayToEndTimeNotification object:theMovie];
//
//}
)

这样第一部分本地视频的播放,就暂时写到这里,下一篇会翻译并改动视频录制保存。

欢迎大家纠错!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值