我用 后台拍摄 这个软件拍摄的手机录视频软件哪个好只能播放几秒就卡住了,似乎需要解码什么之类的,哪位大神解释一下

快剪辑是360浏览器推出的一款小视频制作剪辑软件,这款软件相比其他视频制作软件剪辑视频更加快速高效,剪辑完成就可以发布上传,非常方便,录制完成后,还可以添加特效字幕、水印签名等多种效果,赶快下载体验吧!
快剪辑截图
  1.本软件是提供给用户录制小视频及剪辑等功能的技术服务工具。包含录制小视频功能、剪辑...
魔法视频特效是一款很酷的虚拟摄像头软件。它可以为您的摄像头增加视频特效,从而很轻松的做出很多摄像头视频的魔幻效果,同时,它还是一个虚拟的软件摄像头,可以把视频文件,屏幕,图片,flash等做为虚拟摄像头的输出,配合摄像头软件,如Skype, QQ等或视频网站使用。针对英特尔超极本,MagicCamera特别订制了支持触摸屏操控的版本,并对软件性...
Clone2Go DVD Ripper是DVD转换器,视频转换器,高清视频转换器,YouTube下载的完美结合。
Clone2Go DVD Ripper是强大的所有功能于一身的软件,使您可以轻松抓取DVD(包括CSS加密的DVD)和转换视频文件。
有了这个优秀的DVD Ripper,你可以快速翻录DVD到AVI,WMV,MP4,FLV,MOV,WMA,MP3,M4A,iTunes等等。
此外,它可以让你转换所有流行格式的视频文件,包...
FixVideo是修复视频的工具,支持多种格式视频修复
如果视频看不了,或者没下载完全,或者丢失一些重要信息,它可以帮到你
只需轻松的一次点击就可以修复不能拖动的或者不能播放的divx avi asf wmv wma rm rmvb文件。
Divx Avi Asf Wmv Wma Rm Rmvb 修复器可以修复你通过http,ftp,mms,rtsp方式由于某些原因没有下载完全的...
网上下载的avi等视频音频交错格式影片,有部分是多音轨(如:中英双语、国粤双语)和外挂字幕的,有没有办法只保留一条音轨(如:只有中国话或只有普通话)和将字幕封入文件中以方便观看呢?答案是肯定的,用VirtualDubMod即可实现,但VirtualDubMod转换所费时间较长,在这里向大家介绍一个更方便、更快捷的工具&AVI-Mux GUI。
AVI-MUX GUI是...
VirtualDubMod是VirtualDub的改进版本,除了界面有稍许不同外,似乎还可以支持直接的Mpeg2文件导入。压缩音频视频的功能都有,字幕也可以通过插件实现。导入rmvb等&不支持&的文件可以通过建立avs文件实现。
VirtualDub是一套免费的多媒体剪辑软件,但它的功能可一点也不输给Premiere以及Media Studio等专业等级产品的功...
视频旋转软件(x2x free video flip and rotate)是一款免费的视频旋转工具,可以翻转和旋转视频。7个预设的设置,可以将视频顺时针旋转90、180度等其他任意角度。
使用方法也非常简单,打开要旋转的视频,然后按下面的方向箭头最后设置保存即可。
After Effects CC是非常高端的视频特效处理软件,像钢铁侠、幽灵骑士、加勒比海盗、绿灯侠等大片都使用After Effects制作各种特效。After Effects CC使用技能也似乎成为影视后期编辑人员必备的技能之一。同时,Adobe After Effects CC也是Adobe公司首次直接内置官方简体中文语言,安装即中文。可以看得到Adobe开始对中国的市场非...
  XV是迅雷看看播放器独有的视频缓存格式,用于在本地存储在线播放的视频文件,该软件可帮助您提取在本地已经缓冲好的迅雷XV视频,方便您的观看。
相信很多朋友都跟我一样!最近在迅雷下了电影或者电视剧只能在迅雷看看里面播放而且还必须是连网的!(我住的地方没连网)因为他加壳了格式变成XV的格式!除了迅雷看看所有播放器都不行!我基...
Video Booth是一款有趣的摄像头特效软件。Video Booth可采集内置或计算机连接的摄像机的快照,只要启动此应用程序,定位图像,并点击。可采集单一图片或采取四个连续图片,使用&连续拍摄&模式,使您的图片更特殊。Video Booth可使您的摄像头录制视频剪辑顺利和稳定。使用Video Booth,是相当容易,只需点击即可。更重要的是,Vi...
All Free Video Joiner是一种简单易用的免费视频合并软件。有几个视频格式被预置提供来改进你加入了的文件。你可以加入或者合并多个视频文件到一个(AVI、MP4、FLV,WMV等)并没有任何质量损失。它也可以被用来转换成一个单一的文件。具有超强的转换速度,可以节省很多时间。
AimOne MP4 Cutter & Joiner(MP4剪切合并大师)是一个非常专业强大的免费MP4剪切软件。MP4 Cutter 允许您分割、剪切 MP4 视频或音频文件为小的mp4文件,或手动解压MP4文件中所选片断为新的MP4文件。
1.流媒体直接剪切、克隆,不需要重新编码。支持 MP4 视频和音频文件,.MP4、.M4V、.M4A。
2.支持大体积 3GP 视频、音频...
SWF Decompiler Magic是一款SWF反编译软件可供程序员进行Flash技术处理。
它主要功能可以对SWF格式文件和EXE格式之间进行转换,还可以编辑SWF 电影(动态文本、 图像等) 。这种几乎逆天的强大功能使用户可以将一个swf文件导出资源并保存为其他格式的声音、图像、形状、框架、逐渐、字体、文本、按钮、动画层和Action...
Media Cope是一款免费的多功能的媒体合成软件。Media Cope融合了几乎所有的普通家庭用户所需求多媒体功能,图片切割可在几分钟内切成照片100份。让您查看您的照片与电影的效果(放大+音乐)在实时。可以保存在任何时间采取十分之一幻灯片其他制造商和大小的文件格式,弄得像在其他的十分之一wmv的电影制造商的插件。
BDtoAVCHD是一个视频压缩软件,创建蓝光或HD MKV的AVCHD光碟文件。由于我们得到的输出文件夹结构准备刻录到DVD5或DVD9转。该软件的视频压缩与实现尽可能高的质量所需的4.7 GB的总体规模。
AVCHD格式允许您播放同一类型的内容,相当于蓝光高清分辨(1080p),但却基于DVD5或DVD9媒体。理想的情况是,具有更小的尺寸和保持高蓝光品质。
Muvid Converter是一款专业强大的视频声音提取软件,软件可帮助用户方便的进行各类格式的影片视频中的声音提取,并且支持将提取后的文件直接转换为MP3格式,同时支持影片格式相互转换。
mp4、mov、wmv、avi、mkv、flv及webm
1.解压缩下载的档案后,执行&Muvid.exe&便可开启,无须安装。开启后,点击 Inp...
Engelmann Media Videomizer是一款视频优化软件,具备视频图像自动处理功能。视频优化软件(Engelmann Media Videomizer)将图片自动处理技术应用到了视频图像处理上,可以自动识别物体;全自动重新调整色调,重新锐化和优化对比度;全自动系统控制色调和饱和度等功能,非常强大的视频软件。
Videomizer可以自动识别物体;全自动重新...
ffDiaporama是一个简单实用且免费的视频编辑软件,支持导入图片和视频片断并进行简单加工。
软件提供了数十个视频和图片转场特效,还能为视频添加字幕和背景音乐,特别适合用来保存个人节假日拍摄的回忆。支持所有图像格式、大多数摄像头和视频编码格式。可以选择多种智能设备格式和分辨率来渲染视频。这些序列组装到一...
佳能MXF视频恢复软件一款专业的佳能高清数码MXF视频文件恢复,可以恢复佳能EOS高清硬盘摄像机上误删除和误格式化丢失的MXF录像文件。
  佳能MXF视频恢复软件专门用来恢复佳能(EOS)摄像机常见型号(XF100、XF105、XF300、XF305、C100、C300等)中误删除或者误格式化导致丢失的MXF视频文件,是碎片级的文件恢复软件,能...
SparkoCam是一款电脑摄像头增强软件,就算没有摄像头也没事,pc6推荐的这款软件也可以做为虚拟摄像头使用!如果你有数码相机的话,这款软件还可以将佳能或者尼康的单反相机直接做为高清摄像头来使用!程序可以为你的摄像头添加有趣的图形和特效,还可以将你的摄像头拆分,同时在多个应用程序中使用!
1、直接将佳能/尼康的...
AVI Toolbox是一款能够提供AVI视频文件支持的软件。能够提供诸如文件分割,声音与图象的提取等功能。AVI Toolbox支持播放AVI格式影片,并且可以进行视频分割、提取音频、抓取影片截图等功能,AVI Toolbox用户界面友好,使用方便。
友好的用户界面;提取部分视频文件;提取音轨;图片捕捉;多国语言支持等等。
该软件只...
作曲大师是一个持续开发了十年的国产音乐软件,它界面友好,直观易用而又功能强大的,它支持128种音色和16声部交响乐的编辑,拥有最强大的简谱诠释能力,包括演奏非常复杂的反复记号和跳房子记号和鼓谱,是唯一一套可为您原样演奏市面歌本上大多数曲目的简谱软件,让不识简谱和五线谱的人立即识谱,迈入音乐殿堂,并可读取和输出midi文件,可处...
Icaros Shell Extensions 是一款视频资源扩展插件,Icaros Shell Extensions 让你的 Windows 支持显示大部分主流视频格式文件的预览缩略图,其中包括 mkv、flv、avi、mp4、mov、rmvb、m2ts、ogm 等,可以说Icaros Shell Extensions是一款很好转换工具
caros 中文版的功能很简单,就是让 Windows 资源管理器能支持更多视频...
GiliSoft Video Editor是一款视频编辑软件。使您可以编辑像流行的iPod,iPhone,PSP,PS3游戏机等格式,也可以编辑 如:AVI,MPEG,H.264,SWF,MOV,WMV等各种格式的视频文件。
共三道工序,加入视频,分割和剪裁,可以在后台运行,不占用太多空间。 可以改变帧速率或文件大小,让你轻松实现分裂和切割视频编辑。
1.强大的视频...
  Wondershare Filmora是一款非常好用的电影故事视频制作软件。使用Filmora视频编辑器来表达你的创意和惊奇与美丽的结果。一个现代的和直观的设计,你将会高兴地再次使用。
  文本 & 标题
  现在你可以从我们的文字 & 标题库创建动画的美丽消息
  音乐库
  将你最喜欢的音乐 dircectly 添加到您的电影打...
首页 上一页
软件分类推荐KCMainViewController.m
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &KCMainViewController.h&
#import &AudioToolbox/AudioToolbox.h&
@interface KCMainViewController ()
@implementation KCMainViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self playSoundEffect:@&videoRing.caf&];
播放完成回调函数
@param soundID
系统声音ID
@param clientData 回调时传递的数据
void soundCompleteCallback(SystemSoundID soundID,void * clientData){
NSLog(@&播放完成...&);
播放音效文件
@param name 音频文件名称
-(void)playSoundEffect:(NSString *)name{
NSString *audioFile=[[NSBundle mainBundle] pathForResource:name ofType:nil];
NSURL *fileUrl=[NSURL fileURLWithPath:audioFile];
//1.获得系统声音ID
SystemSoundID soundID=0;
* inFileUrl:音频文件url
* outSystemSoundID:声音id(此函数会将音效文件加入到系统音频服务中并返回一个长整形ID)
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
//如果需要在播放完之后执行某些操作,可以调用如下方法注册一个播放完成回调函数
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
//2.播放音频
AudioServicesPlaySystemSound(soundID);//播放音效
AudioServicesPlayAlertSound(soundID);//播放音效并震动
ViewController.m
KCAVAudioPlayer
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
#define kMusicFile @&刘若英 - 原来你也在这里.mp3&
#define kMusicSinger @&刘若英&
#define kMusicTitle @&原来你也在这里&
@interface ViewController ()&AVAudioPlayerDelegate&
@property (nonatomic,strong) AVAudioPlayer *audioP//播放器
@property (weak, nonatomic) IBOutlet UILabel *controlP //控制面板
@property (weak, nonatomic) IBOutlet UIProgressView *playP//播放进度
@property (weak, nonatomic) IBOutlet UILabel *musicS //演唱者
@property (weak, nonatomic) IBOutlet UIButton *playOrP //播放/暂停按钮(如果tag为0认为是暂停状态,1是播放状态)
@property (weak ,nonatomic) NSTimer *//进度更新定时器
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
-(void)setupUI{
self.title=kMusicT
self.musicSinger.text=kMusicS
-(NSTimer *)timer{
if (!_timer) {
_timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateProgress) userInfo:nil repeats:true];
创建播放器
@return 音频播放器
-(AVAudioPlayer *)audioPlayer{
if (!_audioPlayer) {
NSString *urlStr=[[NSBundle mainBundle]pathForResource:kMusicFile ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
NSError *error=
//初始化播放器,注意这里的Url参数只能时文件路径,不支持HTTP Url
_audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
//设置播放器属性
_audioPlayer.numberOfLoops=0;//设置为0不循环
_audioPlayer.delegate=
[_audioPlayer prepareToPlay];//加载音频文件到缓存
if(error){
NSLog(@&初始化播放器过程发生错误,错误信息:%@&,error.localizedDescription);
return _audioP
-(void)play{
if (![self.audioPlayer isPlaying]) {
[self.audioPlayer play];
self.timer.fireDate=[NSDate distantPast];//恢复定时器
-(void)pause{
if ([self.audioPlayer isPlaying]) {
[self.audioPlayer pause];
self.timer.fireDate=[NSDate distantFuture];//暂停定时器,注意不能调用invalidate方法,此方法会取消,之后无法恢复
点击播放/暂停按钮
@param sender 播放/暂停按钮
- (IBAction)playClick:(UIButton *)sender {
if(sender.tag){
sender.tag=0;
[sender setImage:[UIImage imageNamed:@&playing_btn_play_n&] forState:UIControlStateNormal];
[sender setImage:[UIImage imageNamed:@&playing_btn_play_h&] forState:UIControlStateHighlighted];
[self pause];
sender.tag=1;
[sender setImage:[UIImage imageNamed:@&playing_btn_pause_n&] forState:UIControlStateNormal];
[sender setImage:[UIImage imageNamed:@&playing_btn_pause_h&] forState:UIControlStateHighlighted];
[self play];
更新播放进度
-(void)updateProgress{
float progress= self.audioPlayer.currentTime /self.audioPlayer.
[self.playProgress setProgress:progress animated:true];
#pragma mark - 播放器代理方法
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(@&音乐播放完成...&);
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
ViewController.m
KCAVAudioPlayer
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
AVAudioSession 音频会话
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
#define kMusicFile @&刘若英 - 原来你也在这里.mp3&
#define kMusicSinger @&刘若英&
#define kMusicTitle @&原来你也在这里&
@interface ViewController ()&AVAudioPlayerDelegate&
@property (nonatomic,strong) AVAudioPlayer *audioP//播放器
@property (weak, nonatomic) IBOutlet UILabel *controlP //控制面板
@property (weak, nonatomic) IBOutlet UIProgressView *playP//播放进度
@property (weak, nonatomic) IBOutlet UILabel *musicS //演唱者
@property (weak, nonatomic) IBOutlet UIButton *playOrP //播放/暂停按钮(如果tag为0认为是暂停状态,1是播放状态)
@property (weak ,nonatomic) NSTimer *//进度更新定时器
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
显示当面视图控制器时注册远程事件
@param animated 是否以动画的形式显示
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//开启远程控制
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
//作为第一响应者
//[self becomeFirstResponder];
当前控制器视图不显示时取消远程控制
@param animated 是否以动画的形式消失
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
//[self resignFirstResponder];
-(void)setupUI{
self.title=kMusicT
self.musicSinger.text=kMusicS
-(NSTimer *)timer{
if (!_timer) {
_timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateProgress) userInfo:nil repeats:true];
创建播放器
@return 音频播放器
-(AVAudioPlayer *)audioPlayer{
if (!_audioPlayer) {
NSString *urlStr=[[NSBundle mainBundle]pathForResource:kMusicFile ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
NSError *error=
//初始化播放器,注意这里的Url参数只能时文件路径,不支持HTTP Url
_audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
//设置播放器属性
_audioPlayer.numberOfLoops=0;//设置为0不循环
_audioPlayer.delegate=
[_audioPlayer prepareToPlay];//加载音频文件到缓存
if(error){
NSLog(@&初始化播放器过程发生错误,错误信息:%@&,error.localizedDescription);
//设置后台播放模式
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
[audioSession setActive:YES error:nil];
//添加通知,拔出耳机后暂停播放
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil];
return _audioP
-(void)play{
if (![self.audioPlayer isPlaying]) {
[self.audioPlayer play];
self.timer.fireDate=[NSDate distantPast];//恢复定时器
-(void)pause{
if ([self.audioPlayer isPlaying]) {
[self.audioPlayer pause];
self.timer.fireDate=[NSDate distantFuture];//暂停定时器,注意不能调用invalidate方法,此方法会取消,之后无法恢复
点击播放/暂停按钮
@param sender 播放/暂停按钮
- (IBAction)playClick:(UIButton *)sender {
if(sender.tag){
sender.tag=0;
[sender setImage:[UIImage imageNamed:@&playing_btn_play_n&] forState:UIControlStateNormal];
[sender setImage:[UIImage imageNamed:@&playing_btn_play_h&] forState:UIControlStateHighlighted];
[self pause];
sender.tag=1;
[sender setImage:[UIImage imageNamed:@&playing_btn_pause_n&] forState:UIControlStateNormal];
[sender setImage:[UIImage imageNamed:@&playing_btn_pause_h&] forState:UIControlStateHighlighted];
[self play];
更新播放进度
-(void)updateProgress{
float progress= self.audioPlayer.currentTime /self.audioPlayer.
[self.playProgress setProgress:progress animated:true];
一旦输出改变则执行此方法
@param notification 输出改变通知对象
-(void)routeChange:(NSNotification *)notification{
NSDictionary *dic=notification.userI
int changeReason= [dic[AVAudioSessionRouteChangeReasonKey] intValue];
//等于AVAudioSessionRouteChangeReasonOldDeviceUnavailable表示旧输出不可用
if (changeReason==AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
AVAudioSessionRouteDescription *routeDescription=dic[AVAudioSessionRouteChangePreviousRouteKey];
AVAudioSessionPortDescription *portDescription= [routeDescription.outputs firstObject];
//原设备为耳机则暂停
if ([portDescription.portType isEqualToString:@&Headphones&]) {
[self pause];
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@&%@:%@&,key,obj);
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil];
#pragma mark - 播放器代理方法
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(@&音乐播放完成...&);
//根据实际情况播放完成可以将会话关闭,其他音频应用继续播放
[[AVAudioSession sharedInstance]setActive:NO error:nil];
ViewController.m
MPMusicPlayerController
Created by Kenshin Cui 14/03/30
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &MediaPlayer/MediaPlayer.h&
@interface ViewController ()&MPMediaPickerControllerDelegate&
@property (nonatomic,strong) MPMediaPickerController *mediaP//媒体选择控制器
@property (nonatomic,strong) MPMusicPlayerController *musicP //音乐播放器
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
-(void)dealloc{
[self.musicPlayer endGeneratingPlaybackNotifications];
获得音乐播放器
@return 音乐播放器
-(MPMusicPlayerController *)musicPlayer{
if (!_musicPlayer) {
_musicPlayer=[MPMusicPlayerController systemMusicPlayer];
[_musicPlayer beginGeneratingPlaybackNotifications];//开启通知,否则监控不到MPMusicPlayerController的通知
[self addNotification];//添加通知
//如果不使用MPMediaPickerController可以使用如下方法获得音乐库媒体队列
//[_musicPlayer setQueueWithItemCollection:[self getLocalMediaItemCollection]];
return _musicP
创建媒体选择器
@return 媒体选择器
-(MPMediaPickerController *)mediaPicker{
if (!_mediaPicker) {
//初始化媒体选择器,这里设置媒体类型为音乐,其实这里也可以选择视频、广播等
_mediaPicker=[[MPMediaPickerController alloc]initWithMediaTypes:MPMediaTypeMusic];
_mediaPicker=[[MPMediaPickerController alloc]initWithMediaTypes:MPMediaTypeAny];
_mediaPicker.allowsPickingMultipleItems=YES;//允许多选
_mediaPicker.showsCloudItems=YES;//显示icloud选项
_mediaPicker.prompt=@&请选择要播放的音乐&;
_mediaPicker.delegate=//设置选择器代理
return _mediaP
取得媒体队列
@return 媒体队列
-(MPMediaQuery *)getLocalMediaQuery{
MPMediaQuery *mediaQueue=[MPMediaQuery songsQuery];
for (MPMediaItem *item in mediaQueue.items) {
NSLog(@&标题:%@,%@&,item.title,item.albumTitle);
return mediaQ
取得媒体集合
@return 媒体集合
-(MPMediaItemCollection *)getLocalMediaItemCollection{
MPMediaQuery *mediaQueue=[MPMediaQuery songsQuery];
NSMutableArray *array=[NSMutableArray array];
for (MPMediaItem *item in mediaQueue.items) {
[array addObject:item];
NSLog(@&标题:%@,%@&,item.title,item.albumTitle);
MPMediaItemCollection *mediaItemCollection=[[MPMediaItemCollection alloc]initWithItems:[array copy]];
return mediaItemC
#pragma mark - MPMediaPickerController代理方法
//选择完成
-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{
MPMediaItem *mediaItem=[mediaItemCollection.items firstObject];//第一个播放音乐
//注意很多音乐信息如标题、专辑、表演者、封面、时长等信息都可以通过MPMediaItem的valueForKey:方法得到,但是从iOS7开始都有对应的属性可以直接访问
NSString *title= [mediaItem valueForKey:MPMediaItemPropertyAlbumTitle];
NSString *artist= [mediaItem valueForKey:MPMediaItemPropertyAlbumArtist];
MPMediaItemArtwork *artwork= [mediaItem valueForKey:MPMediaItemPropertyArtwork];
//UIImage *image=[artwork imageWithSize:CGSizeMake(100, 100)];//专辑图片
NSLog(@&标题:%@,表演者:%@,专辑:%@&,mediaItem.title ,mediaItem.artist,mediaItem.albumTitle);
[self.musicPlayer setQueueWithItemCollection:mediaItemCollection];
[self dismissViewControllerAnimated:YES completion:nil];
//取消选择
-(void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker{
[self dismissViewControllerAnimated:YES completion:nil];
#pragma mark - 通知
-(void)addNotification{
NSNotificationCenter *notificationCenter=[NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(playbackStateChange:) name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object:self.musicPlayer];
播放状态改变通知
@param notification 通知对象
-(void)playbackStateChange:(NSNotification *)notification{
switch (self.musicPlayer.playbackState) {
case MPMusicPlaybackStatePlaying:
NSLog(@&正在播放...&);
case MPMusicPlaybackStatePaused:
NSLog(@&播放暂停.&);
case MPMusicPlaybackStateStopped:
NSLog(@&播放停止.&);
#pragma mark - UI事件
- (IBAction)selectClick:(UIButton *)sender {
[self presentViewController:self.mediaPicker animated:YES completion:nil];
- (IBAction)playClick:(UIButton *)sender {
[self.musicPlayer play];
- (IBAction)puaseClick:(UIButton *)sender {
[self.musicPlayer pause];
- (IBAction)stopClick:(UIButton *)sender {
[self.musicPlayer stop];
- (IBAction)nextClick:(UIButton *)sender {
[self.musicPlayer skipToNextItem];
- (IBAction)prevClick:(UIButton *)sender {
[self.musicPlayer skipToPreviousItem];
ViewController.m
AVAudioRecorder
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
#define kRecordAudioFile @&myRecord.caf&
@interface ViewController ()&AVAudioRecorderDelegate&
@property (nonatomic,strong) AVAudioRecorder *audioR//音频录音机
@property (nonatomic,strong) AVAudioPlayer *audioP//音频播放器,用于播放录音文件
@property (nonatomic,strong) NSTimer *//录音声波监控(注意这里暂时不对播放进行监控)
@property (weak, nonatomic) IBOutlet UIButton *//开始录音
@property (weak, nonatomic) IBOutlet UIButton *//暂停录音
@property (weak, nonatomic) IBOutlet UIButton *//恢复录音
@property (weak, nonatomic) IBOutlet UIButton *//停止录音
@property (weak, nonatomic) IBOutlet UIProgressView *audioP//音频波动
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
[self setAudioSession];
#pragma mark - 私有方法
设置音频会话
-(void)setAudioSession{
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
//设置为播放和录音状态,以便可以在录制完之后播放录音
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
取得录音文件保存路径
@return 录音文件路径
-(NSURL *)getSavePath{
NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
urlStr=[urlStr stringByAppendingPathComponent:kRecordAudioFile];
NSLog(@&file path:%@&,urlStr);
NSURL *url=[NSURL fileURLWithPath:urlStr];
取得录音文件设置
@return 录音设置
-(NSDictionary *)getAudioSetting{
NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
//设置录音格式
[dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
//设置录音采样率,8000是电话采样率,对于一般录音已经够了
[dicM setObject:@(8000) forKey:AVSampleRateKey];
//设置通道,这里采用单声道
[dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
//每个采样点位数,分为8、16、24、32
[dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
//是否使用浮点数采样
[dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
//....其他设置等
return dicM;
获得录音机对象
@return 录音机对象
-(AVAudioRecorder *)audioRecorder{
if (!_audioRecorder) {
//创建录音文件保存路径
NSURL *url=[self getSavePath];
//创建录音格式设置
NSDictionary *setting=[self getAudioSetting];
//创建录音机
NSError *error=
_audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];
_audioRecorder.delegate=
_audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES
if (error) {
NSLog(@&创建录音机对象时发生错误,错误信息:%@&,error.localizedDescription);
return _audioR
创建播放器
@return 播放器
-(AVAudioPlayer *)audioPlayer{
if (!_audioPlayer) {
NSURL *url=[self getSavePath];
NSError *error=
_audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
_audioPlayer.numberOfLoops=0;
[_audioPlayer prepareToPlay];
if (error) {
NSLog(@&创建播放器过程中发生错误,错误信息:%@&,error.localizedDescription);
return _audioP
录音声波监控定制器
@return 定时器
-(NSTimer *)timer{
if (!_timer) {
_timer=[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(audioPowerChange) userInfo:nil repeats:YES];
录音声波状态设置
-(void)audioPowerChange{
[self.audioRecorder updateMeters];//更新测量值
float power= [self.audioRecorder averagePowerForChannel:0];//取得第一个通道的音频,注意音频强度范围时-160到0
CGFloat progress=(1.0/160.0)*(power+160.0);
[self.audioPower setProgress:progress];
#pragma mark - UI事件
点击录音按钮
@param sender 录音按钮
- (IBAction)recordClick:(UIButton *)sender {
if (![self.audioRecorder isRecording]) {
[self.audioRecorder record];//首次使用应用时如果调用record方法会询问用户是否允许使用麦克风
self.timer.fireDate=[NSDate distantPast];
点击暂定按钮
@param sender 暂停按钮
- (IBAction)pauseClick:(UIButton *)sender {
if ([self.audioRecorder isRecording]) {
[self.audioRecorder pause];
self.timer.fireDate=[NSDate distantFuture];
点击恢复按钮
恢复录音只需要再次调用record,AVAudioSession会帮助你记录上次录音位置并追加录音
@param sender 恢复按钮
- (IBAction)resumeClick:(UIButton *)sender {
[self recordClick:sender];
点击停止按钮
@param sender 停止按钮
- (IBAction)stopClick:(UIButton *)sender {
[self.audioRecorder stop];
self.timer.fireDate=[NSDate distantFuture];
self.audioPower.progress=0.0;
#pragma mark - 录音机代理方法
录音完成,录音完成后播放录音
@param recorder 录音机对象
@param flag
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
if (![self.audioPlayer isPlaying]) {
[self.audioPlayer play];
NSLog(@&录音完成!&);
ViewController.m
AudioQueueServices
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
使用FreeStreamer实现网络音频播放
#import &ViewController.h&
#import &FSAudioStream.h&
@interface ViewController ()
@property (nonatomic,strong) FSAudioStream *audioS
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.audioStream play];
取得本地文件路径
@return 文件路径
-(NSURL *)getFileUrl{
NSString *urlStr=[[NSBundle mainBundle]pathForResource:@&刘若英 - 原来你也在这里.mp3& ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
-(NSURL *)getNetworkUrl{
NSString *urlStr=@&http://192.168.1.102/liu.mp3&;
NSURL *url=[NSURL URLWithString:urlStr];
创建FSAudioStream对象
@return FSAudioStream对象
-(FSAudioStream *)audioStream{
if (!_audioStream) {
NSURL *url=[self getNetworkUrl];
//创建FSAudioStream对象
_audioStream=[[FSAudioStream alloc]initWithUrl:url];
_audioStream.onFailure=^(FSAudioStreamError error,NSString *description){
NSLog(@&播放过程中发生错误,错误信息:%@&,description);
_audioStream.onCompletion=^(){
NSLog(@&播放完成!&);
[_audioStream setVolume:0.5];//设置声音
return _audioS
ViewController.m
MPMoviePlayerController
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &MediaPlayer/MediaPlayer.h&
@interface ViewController ()
@property (nonatomic,strong) MPMoviePlayerController *movieP//视频播放控制器
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
[self.moviePlayer play];
//添加通知
[self addNotification];
-(void)dealloc{
//移除所有通知监控
[[NSNotificationCenter defaultCenter] removeObserver:self];
#pragma mark - 私有方法
取得本地文件路径
@return 文件路径
-(NSURL *)getFileUrl{
NSString *urlStr=[[NSBundle mainBundle] pathForResource:@&The New Look of OS X Yosemite.mp4& ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
取得网络文件路径
@return 文件路径
-(NSURL *)getNetworkUrl{
NSString *urlStr=@&http://192.168.1.161/The New Look of OS X Yosemite.mp4&;
urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlStr];
创建媒体播放控制器
@return 媒体播放控制器
-(MPMoviePlayerController *)moviePlayer{
if (!_moviePlayer) {
NSURL *url=[self getNetworkUrl];
_moviePlayer=[[MPMoviePlayerController alloc]initWithContentURL:url];
_moviePlayer.view.frame=self.view.
_moviePlayer.view.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleH
[self.view addSubview:_moviePlayer.view];
return _movieP
添加通知监控媒体播放控制器状态
-(void)addNotification{
NSNotificationCenter *notificationCenter=[NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(mediaPlayerPlaybackStateChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer];
[notificationCenter addObserver:self selector:@selector(mediaPlayerPlaybackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];
播放状态改变,注意播放完成时的状态是暂停
@param notification 通知对象
-(void)mediaPlayerPlaybackStateChange:(NSNotification *)notification{
switch (self.moviePlayer.playbackState) {
case MPMoviePlaybackStatePlaying:
NSLog(@&正在播放...&);
case MPMoviePlaybackStatePaused:
NSLog(@&暂停播放.&);
case MPMoviePlaybackStateStopped:
NSLog(@&停止播放.&);
NSLog(@&播放状态:%li&,self.moviePlayer.playbackState);
@param notification 通知对象
-(void)mediaPlayerPlaybackFinished:(NSNotification *)notification{
NSLog(@&播放完成.%li&,self.moviePlayer.playbackState);
ViewController.m
MPMoviePlayerController
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &MediaPlayer/MediaPlayer.h&
@interface ViewController ()
@property (nonatomic,strong) MPMoviePlayerController *movieP//视频播放控制器
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
[self.moviePlayer play];
//添加通知
[self addNotification];
//获取缩略图
[self thumbnailImageRequest];
-(void)dealloc{
//移除所有通知监控
[[NSNotificationCenter defaultCenter] removeObserver:self];
#pragma mark - 私有方法
取得本地文件路径
@return 文件路径
-(NSURL *)getFileUrl{
NSString *urlStr=[[NSBundle mainBundle] pathForResource:@&The New Look of OS X Yosemite.mp4& ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
取得网络文件路径
@return 文件路径
-(NSURL *)getNetworkUrl{
NSString *urlStr=@&http://192.168.1.161/The New Look of OS X Yosemite.mp4&;
urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlStr];
创建媒体播放控制器
@return 媒体播放控制器
-(MPMoviePlayerController *)moviePlayer{
if (!_moviePlayer) {
NSURL *url=[self getNetworkUrl];
_moviePlayer=[[MPMoviePlayerController alloc]initWithContentURL:url];
_moviePlayer.view.frame=self.view.
_moviePlayer.view.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleH
[self.view addSubview:_moviePlayer.view];
return _movieP
获取视频缩略图
-(void)thumbnailImageRequest{
//获取13.0s、21.5s的缩略图
[self.moviePlayer requestThumbnailImagesAtTimes:@[@13.0,@21.5] timeOption:MPMovieTimeOptionNearestKeyFrame];
#pragma mark - 控制器通知
添加通知监控媒体播放控制器状态
-(void)addNotification{
NSNotificationCenter *notificationCenter=[NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(mediaPlayerPlaybackStateChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer];
[notificationCenter addObserver:self selector:@selector(mediaPlayerPlaybackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];
[notificationCenter addObserver:self selector:@selector(mediaPlayerThumbnailRequestFinished:) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:self.moviePlayer];
播放状态改变,注意播放完成时的状态是暂停
@param notification 通知对象
-(void)mediaPlayerPlaybackStateChange:(NSNotification *)notification{
switch (self.moviePlayer.playbackState) {
case MPMoviePlaybackStatePlaying:
NSLog(@&正在播放...&);
case MPMoviePlaybackStatePaused:
NSLog(@&暂停播放.&);
case MPMoviePlaybackStateStopped:
NSLog(@&停止播放.&);
NSLog(@&播放状态:%li&,self.moviePlayer.playbackState);
@param notification 通知对象
-(void)mediaPlayerPlaybackFinished:(NSNotification *)notification{
NSLog(@&播放完成.%li&,self.moviePlayer.playbackState);
缩略图请求完成,此方法每次截图成功都会调用一次
@param notification 通知对象
-(void)mediaPlayerThumbnailRequestFinished:(NSNotification *)notification{
NSLog(@&视频截图完成.&);
UIImage *image=notification.userInfo[MPMoviePlayerThumbnailImageKey];
//保存图片到相册(首次调用会请求用户获得访问相册权限)
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
ViewController.m
AVAssetImageGenerator
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//获取第13.0s的缩略图
[self thumbnailImageRequest:13.0];
#pragma mark - 私有方法
取得本地文件路径
@return 文件路径
-(NSURL *)getFileUrl{
NSString *urlStr=[[NSBundle mainBundle] pathForResource:@&The New Look of OS X Yosemite.mp4& ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
取得网络文件路径
@return 文件路径
-(NSURL *)getNetworkUrl{
NSString *urlStr=@&http://192.168.1.161/The New Look of OS X Yosemite.mp4&;
urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlStr];
截取指定时间的视频缩略图
@param timeBySecond 时间点
-(void)thumbnailImageRequest:(CGFloat )timeBySecond{
NSURL *url=[self getNetworkUrl];
//根据url创建AVURLAsset
AVURLAsset *urlAsset=[AVURLAsset assetWithURL:url];
//根据AVURLAsset创建AVAssetImageGenerator
AVAssetImageGenerator *imageGenerator=[AVAssetImageGenerator assetImageGeneratorWithAsset:urlAsset];
* requestTime:缩略图创建时间
* actualTime:缩略图实际生成的时间
NSError *error=
CMTime time=CMTimeMakeWithSeconds(timeBySecond, 10);//CMTime是表示电影时间信息的结构体,第一个参数表示是视频第几秒,第二个参数表示每秒帧数.(如果要活的某一秒的第几帧可以使用CMTimeMake方法)
CMTime actualT
CGImageRef cgImage= [imageGenerator copyCGImageAtTime:time actualTime:&actualTime error:&error];
if(error){
NSLog(@&截取视频缩略图时发生错误,错误信息:%@&,error.localizedDescription);
CMTimeShow(actualTime);
UIImage *image=[UIImage imageWithCGImage:cgImage];//转化为UIImage
//保存到相册
UIImageWriteToSavedPhotosAlbum(image,nil, nil, nil);
CGImageRelease(cgImage);
ViewController.m
MPMoviePlayerViewController
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
MPMoviePlayerViewController使用
#import &ViewController.h&
#import &MediaPlayer/MediaPlayer.h&
@interface ViewController ()
//播放器视图控制器
@property (nonatomic,strong) MPMoviePlayerViewController *moviePlayerViewC
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
-(void)dealloc{
//移除所有通知监控
[[NSNotificationCenter defaultCenter] removeObserver:self];
#pragma mark - 私有方法
取得本地文件路径
@return 文件路径
-(NSURL *)getFileUrl{
NSString *urlStr=[[NSBundle mainBundle] pathForResource:@&The New Look of OS X Yosemite.mp4& ofType:nil];
NSURL *url=[NSURL fileURLWithPath:urlStr];
取得网络文件路径
@return 文件路径
-(NSURL *)getNetworkUrl{
NSString *urlStr=@&http://192.168.1.161/The New Look of OS X Yosemite.mp4&;
urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlStr];
-(MPMoviePlayerViewController *)moviePlayerViewController{
if (!_moviePlayerViewController) {
NSURL *url=[self getNetworkUrl];
_moviePlayerViewController=[[MPMoviePlayerViewController alloc]initWithContentURL:url];
[self addNotification];
return _moviePlayerViewC
#pragma mark - UI事件
- (IBAction)playClick:(UIButton *)sender {
self.moviePlayerViewController=//保证每次点击都重新创建视频播放控制器视图,避免再次点击时由于不播放的问题
[self presentViewController:self.moviePlayerViewController animated:YES completion:nil];
//注意,在MPMoviePlayerViewController.h中对UIViewController扩展两个用于模态展示和关闭MPMoviePlayerViewController的方法,增加了一种下拉展示动画效果
[self presentMoviePlayerViewControllerAnimated:self.moviePlayerViewController];
#pragma mark - 控制器通知
添加通知监控媒体播放控制器状态
-(void)addNotification{
NSNotificationCenter *notificationCenter=[NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(mediaPlayerPlaybackStateChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayerViewController.moviePlayer];
[notificationCenter addObserver:self selector:@selector(mediaPlayerPlaybackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayerViewController.moviePlayer];
播放状态改变,注意播放完成时的状态是暂停
@param notification 通知对象
-(void)mediaPlayerPlaybackStateChange:(NSNotification *)notification{
switch (self.moviePlayerViewController.moviePlayer.playbackState) {
case MPMoviePlaybackStatePlaying:
NSLog(@&正在播放...&);
case MPMoviePlaybackStatePaused:
NSLog(@&暂停播放.&);
case MPMoviePlaybackStateStopped:
NSLog(@&停止播放.&);
NSLog(@&播放状态:%li&,self.moviePlayerViewController.moviePlayer.playbackState);
@param notification 通知对象
-(void)mediaPlayerPlaybackFinished:(NSNotification *)notification{
NSLog(@&播放完成.%li&,self.moviePlayerViewController.moviePlayer.playbackState);
ViewController.m
Created by Kenshin Cui on 14/03/30.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
@interface ViewController ()
@property (nonatomic,strong) AVPlayer *//播放器对象
@property (weak, nonatomic) IBOutlet UIView * //播放器容器
@property (weak, nonatomic) IBOutlet UIButton *playOrP //播放/暂停按钮
@property (weak, nonatomic) IBOutlet UIProgressView *//播放进度
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
[self.player play];
-(void)dealloc{
[self removeObserverFromPlayerItem:self.player.currentItem];
[self removeNotification];
#pragma mark - 私有方法
-(void)setupUI{
//创建播放器层
AVPlayerLayer *playerLayer=[AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame=self.container.
//playerLayer.videoGravity=AVLayerVideoGravityResizeA//视频填充模式
[self.container.layer addSublayer:playerLayer];
截取指定时间的视频缩略图
@param timeBySecond 时间点
初始化播放器
@return 播放器对象
-(AVPlayer *)player{
if (!_player) {
AVPlayerItem *playerItem=[self getPlayItem:0];
_player=[AVPlayer playerWithPlayerItem:playerItem];
[self addProgressObserver];
[self addObserverToPlayerItem:playerItem];
根据视频索引取得AVPlayerItem对象
@param videoIndex 视频顺序索引
@return AVPlayerItem对象
-(AVPlayerItem *)getPlayItem:(int)videoIndex{
NSString *urlStr=[NSString stringWithFormat:@&http://192.168.1.161/%i.mp4&,videoIndex];
urlStr =[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlStr];
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url];
return playerI
#pragma mark - 通知
添加播放器通知
-(void)addNotification{
//给AVPlayerItem添加播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
-(void)removeNotification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
播放完成通知
@param notification 通知对象
-(void)playbackFinished:(NSNotification *)notification{
NSLog(@&视频播放完成.&);
#pragma mark - 监控
给播放器添加进度更新
-(void)addProgressObserver{
AVPlayerItem *playerItem=self.player.currentI
UIProgressView *progress=self.
//这里设置每秒执行一次
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
float current=CMTimeGetSeconds(time);
float total=CMTimeGetSeconds([playerItem duration]);
NSLog(@&当前已经播放%.2fs.&,current);
if (current) {
[progress setProgress:(current/total) animated:YES];
给AVPlayerItem添加监控
@param playerItem AVPlayerItem对象
-(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{
//监控状态属性,注意AVPlayer也有一个status属性,通过监控它的status也可以获得播放状态
[playerItem addObserver:self forKeyPath:@&status& options:NSKeyValueObservingOptionNew context:nil];
//监控网络加载情况属性
[playerItem addObserver:self forKeyPath:@&loadedTimeRanges& options:NSKeyValueObservingOptionNew context:nil];
-(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{
[playerItem removeObserver:self forKeyPath:@&status&];
[playerItem removeObserver:self forKeyPath:@&loadedTimeRanges&];
通过KVO监控播放器状态
@param keyPath 监控属性
@param object
@param change
@param context 上下文
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayerItem *playerItem=
if ([keyPath isEqualToString:@&status&]) {
AVPlayerStatus status= [[change objectForKey:@&new&] intValue];
if(status==AVPlayerStatusReadyToPlay){
NSLog(@&正在播放...,视频总长度:%.2f&,CMTimeGetSeconds(playerItem.duration));
}else if([keyPath isEqualToString:@&loadedTimeRanges&]){
NSArray *array=playerItem.loadedTimeR
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval totalBuffer = startSeconds + durationS//缓冲总长度
NSLog(@&共缓冲:%.2f&,totalBuffer);
#pragma mark - UI事件
点击播放/暂停按钮
@param sender 播放/暂停按钮
- (IBAction)playClick:(UIButton *)sender {
AVPlayerItemDidPlayToEndTimeNotification
//AVPlayerItem *playerItem= self.player.currentI
if(self.player.rate==0){ //说明时暂停
[sender setImage:[UIImage imageNamed:@&player_pause&] forState:UIControlStateNormal];
[self.player play];
}else if(self.player.rate==1){//正在播放
[self.player pause];
[sender setImage:[UIImage imageNamed:@&player_play&] forState:UIControlStateNormal];
切换选集,这里使用按钮的tag代表视频名称
@param sender 点击按钮对象
- (IBAction)navigationButtonClick:(UIButton *)sender {
[self removeNotification];
[self removeObserverFromPlayerItem:self.player.currentItem];
AVPlayerItem *playerItem=[self getPlayItem:sender.tag];
[self addObserverToPlayerItem:playerItem];
//切换视频
[self.player replaceCurrentItemWithPlayerItem:playerItem];
[self addNotification];
ViewController.m
UIImagePickerController
Created by Kenshin Cui on 14/04/05.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &MobileCoreServices/MobileCoreServices.h&
#import &AVFoundation/AVFoundation.h&
@interface ViewController ()&UIImagePickerControllerDelegate,UINavigationControllerDelegate&
@property (assign,nonatomic) int isV//是否录制视频,如果为1表示录制视频,0代表拍照
@property (strong,nonatomic) UIImagePickerController *imageP
@property (weak, nonatomic) IBOutlet UIImageView *//照片展示视图
@property (strong ,nonatomic) AVPlayer *//播放器,用于录制完视频后播放视频
@implementation ViewController
#pragma mark - 控制器视图事件
- (void)viewDidLoad {
[super viewDidLoad];
//通过这里设置当前程序是拍照还是录制视频
_isVideo=YES;
#pragma mark - UI事件
//点击拍照按钮
- (IBAction)takeClick:(UIButton *)sender {
[self presentViewController:self.imagePicker animated:YES completion:nil];
#pragma mark - UIImagePickerController代理方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType=[info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {//如果是拍照
//如果允许编辑则获得编辑后的照片,否则获取原始照片
if (self.imagePicker.allowsEditing) {
image=[info objectForKey:UIImagePickerControllerEditedImage];//获取编辑后的照片
image=[info objectForKey:UIImagePickerControllerOriginalImage];//获取原始照片
[self.photo setImage:image];//显示照片
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);//保存到相簿
}else if([mediaType isEqualToString:(NSString *)kUTTypeMovie]){//如果是录制视频
NSLog(@&video...&);
NSURL *url=[info objectForKey:UIImagePickerControllerMediaURL];//视频路径
NSString *urlStr=[url path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(urlStr)) {
//保存视频到相簿,注意也可以使用ALAssetsLibrary来保存
UISaveVideoAtPathToSavedPhotosAlbum(urlStr, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);//保存视频到相簿
[self dismissViewControllerAnimated:YES completion:nil];
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
NSLog(@&取消&);
#pragma mark - 私有方法
-(UIImagePickerController *)imagePicker{
if (!_imagePicker) {
_imagePicker=[[UIImagePickerController alloc]init];
_imagePicker.sourceType=UIImagePickerControllerSourceTypeC//设置image picker的来源,这里设置为摄像头
_imagePicker.cameraDevice=UIImagePickerControllerCameraDeviceR//设置使用哪个摄像头,这里设置为后置摄像头
if (self.isVideo) {
_imagePicker.mediaTypes=@[(NSString *)kUTTypeMovie];
_imagePicker.videoQuality=UIImagePickerControllerQualityTypeIFrame;
_imagePicker.cameraCaptureMode=UIImagePickerControllerCameraCaptureModeV//设置摄像头模式(拍照,录制视频)
_imagePicker.cameraCaptureMode=UIImagePickerControllerCameraCaptureModeP
_imagePicker.allowsEditing=YES;//允许编辑
_imagePicker.delegate=//设置代理,检测操作
return _imageP
//视频保存后的回调
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
if (error) {
NSLog(@&保存视频过程中发生错误,错误信息:%@&,error.localizedDescription);
NSLog(@&视频保存成功.&);
//录制完之后自动播放
NSURL *url=[NSURL fileURLWithPath:videoPath];
_player=[AVPlayer playerWithURL:url];
AVPlayerLayer *playerLayer=[AVPlayerLayer playerLayerWithPlayer:_player];
playerLayer.frame=self.photo.
[self.photo.layer addSublayer:playerLayer];
[_player play];
@interface ViewController ()
@property (strong,nonatomic) AVCaptureSession *captureS//负责输入和输出设备之间的数据传递
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceI//负责从AVCaptureDevice获得输入数据
@property (strong,nonatomic) AVCaptureStillImageOutput *captureStillImageO//照片输出流
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewL//相机拍摄预览图层
@property (weak, nonatomic) IBOutlet UIView *viewC
@property (weak, nonatomic) IBOutlet UIButton *takeB//拍照按钮
@property (weak, nonatomic) IBOutlet UIButton *flashAutoB//自动闪光灯按钮
@property (weak, nonatomic) IBOutlet UIButton *flashOnB//打开闪光灯按钮
@property (weak, nonatomic) IBOutlet UIButton *flashOffB//关闭闪光灯按钮
@property (weak, nonatomic) IBOutlet UIImageView *focusC //聚焦光标
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//初始化会话
_captureSession=[[AVCaptureSession alloc]init];
if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset]) {//设置分辨率
_captureSession.sessionPreset=AVCaptureSessionPreset;
//获得输入设备
AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置摄像头
if (!captureDevice) {
NSLog(@&取得后置摄像头时出现问题.&);
NSError *error=
//根据输入设备初始化设备输入对象,用于获得输入数据
_captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error];
if (error) {
NSLog(@&取得设备输入对象时出错,错误原因:%@&,error.localizedDescription);
//初始化设备输出对象,用于获得输出数据
_captureStillImageOutput=[[AVCaptureStillImageOutput alloc]init];
NSDictionary *outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
[_captureStillImageOutput setOutputSettings:outputSettings];//输出设置
//将设备输入添加到会话中
if ([_captureSession canAddInput:_captureDeviceInput]) {
[_captureSession addInput:_captureDeviceInput];
//将设备输出添加到会话中
if ([_captureSession canAddOutput:_captureStillImageOutput]) {
[_captureSession addOutput:_captureStillImageOutput];
//创建视频预览层,用于实时展示摄像头状态
_captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];
CALayer *layer=self.viewContainer.
layer.masksToBounds=YES;
_captureVideoPreviewLayer.frame=layer.
_captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectF//填充模式
//将视频预览层添加到界面中
//[layer addSublayer:_captureVideoPreviewLayer];
[layer insertSublayer:_captureVideoPreviewLayer below:self.focusCursor.layer];
[self addNotificationToCaptureDevice:captureDevice];
[self addGenstureRecognizer];
[self setFlashModeButtonStatus];
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.captureSession startRunning];
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[self.captureSession stopRunning];
改变设备属性的统一操作方法
@param propertyChange 属性改变操作
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{
AVCaptureDevice *captureDevice= [self.captureDeviceInput device];
//注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁
if ([captureDevice lockForConfiguration:&error]) {
propertyChange(captureDevice);
[captureDevice unlockForConfiguration];
NSLog(@&设置设备属性过程发生错误,错误信息:%@&,error.localizedDescription);
设置闪光灯模式
@param flashMode 闪光灯模式
-(void)setFlashMode:(AVCaptureFlashMode )flashMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFlashModeSupported:flashMode]) {
[captureDevice setFlashMode:flashMode];
#pragma mark 切换前后摄像头
- (IBAction)toggleButtonClick:(UIButton *)sender {
AVCaptureDevice *currentDevice=[self.captureDeviceInput device];
AVCaptureDevicePosition currentPosition=[currentDevice position];
[self removeNotificationFromCaptureDevice:currentDevice];
AVCaptureDevice *toChangeD
AVCaptureDevicePosition toChangePosition=AVCaptureDevicePositionF
if (currentPosition==AVCaptureDevicePositionUnspecified||currentPosition==AVCaptureDevicePositionFront) {
toChangePosition=AVCaptureDevicePositionB
toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition];
[self addNotificationToCaptureDevice:toChangeDevice];
//获得要调整的设备输入对象
AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil];
//改变会话的配置前一定要先开启配置,配置完成后提交配置改变
[self.captureSession beginConfiguration];
//移除原有输入对象
[self.captureSession removeInput:self.captureDeviceInput];
//添加新的输入对象
if ([self.captureSession canAddInput:toChangeDeviceInput]) {
[self.captureSession addInput:toChangeDeviceInput];
self.captureDeviceInput=toChangeDeviceI
//提交会话配置
[self.captureSession commitConfiguration];
[self setFlashModeButtonStatus];
设置聚焦点
@param point 聚焦点
-(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFocusModeSupported:focusMode]) {
[captureDevice setFocusMode:AVCaptureFocusModeAutoFocus];
if ([captureDevice isFocusPointOfInterestSupported]) {
[captureDevice setFocusPointOfInterest:point];
if ([captureDevice isExposureModeSupported:exposureMode]) {
[captureDevice setExposureMode:AVCaptureExposureModeAutoExpose];
if ([captureDevice isExposurePointOfInterestSupported]) {
[captureDevice setExposurePointOfInterest:point];
添加点按手势,点按时聚焦
-(void)addGenstureRecognizer{
UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)];
[self.viewContainer addGestureRecognizer:tapGesture];
-(void)tapScreen:(UITapGestureRecognizer *)tapGesture{
CGPoint point= [tapGesture locationInView:self.viewContainer];
//将UI坐标转化为摄像头坐标
CGPoint cameraPoint= [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point];
[self setFocusCursorWithPoint:point];
[self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint];
#pragma mark 拍照
- (IBAction)takeButtonClick:(UIButton *)sender {
//根据设备输出获得连接
AVCaptureConnection *captureConnection=[self.captureStillImageOutput connectionWithMediaType:AVMediaTypeVideo];
//根据连接取得设备输出的数据
[self.captureStillImageOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer) {
NSData *imageData=[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image=[UIImage imageWithData:imageData];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc]init];
[assetsLibrary writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];
ViewController.m
AVFoundationCamera
Created by Kenshin Cui on 14/04/05.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
#import &AssetsLibrary/AssetsLibrary.h&
typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);
@interface ViewController ()
@property (strong,nonatomic) AVCaptureSession *captureS//负责输入和输出设备之间的数据传递
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceI//负责从AVCaptureDevice获得输入数据
@property (strong,nonatomic) AVCaptureStillImageOutput *captureStillImageO//照片输出流
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewL//相机拍摄预览图层
@property (weak, nonatomic) IBOutlet UIView *viewC
@property (weak, nonatomic) IBOutlet UIButton *takeB//拍照按钮
@property (weak, nonatomic) IBOutlet UIButton *flashAutoB//自动闪光灯按钮
@property (weak, nonatomic) IBOutlet UIButton *flashOnB//打开闪光灯按钮
@property (weak, nonatomic) IBOutlet UIButton *flashOffB//关闭闪光灯按钮
@property (weak, nonatomic) IBOutlet UIImageView *focusC //聚焦光标
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//初始化会话
_captureSession=[[AVCaptureSession alloc]init];
if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset]) {//设置分辨率
_captureSession.sessionPreset=AVCaptureSessionPreset;
//获得输入设备
AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置摄像头
if (!captureDevice) {
NSLog(@&取得后置摄像头时出现问题.&);
NSError *error=
//根据输入设备初始化设备输入对象,用于获得输入数据
_captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error];
if (error) {
NSLog(@&取得设备输入对象时出错,错误原因:%@&,error.localizedDescription);
//初始化设备输出对象,用于获得输出数据
_captureStillImageOutput=[[AVCaptureStillImageOutput alloc]init];
NSDictionary *outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
[_captureStillImageOutput setOutputSettings:outputSettings];//输出设置
//将设备输入添加到会话中
if ([_captureSession canAddInput:_captureDeviceInput]) {
[_captureSession addInput:_captureDeviceInput];
//将设备输出添加到会话中
if ([_captureSession canAddOutput:_captureStillImageOutput]) {
[_captureSession addOutput:_captureStillImageOutput];
//创建视频预览层,用于实时展示摄像头状态
_captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];
CALayer *layer=self.viewContainer.
layer.masksToBounds=YES;
_captureVideoPreviewLayer.frame=layer.
_captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectF//填充模式
//将视频预览层添加到界面中
//[layer addSublayer:_captureVideoPreviewLayer];
[layer insertSublayer:_captureVideoPreviewLayer below:self.focusCursor.layer];
[self addNotificationToCaptureDevice:captureDevice];
[self addGenstureRecognizer];
[self setFlashModeButtonStatus];
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.captureSession startRunning];
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[self.captureSession stopRunning];
-(void)dealloc{
[self removeNotification];
#pragma mark - UI方法
#pragma mark 拍照
- (IBAction)takeButtonClick:(UIButton *)sender {
//根据设备输出获得连接
AVCaptureConnection *captureConnection=[self.captureStillImageOutput connectionWithMediaType:AVMediaTypeVideo];
//根据连接取得设备输出的数据
[self.captureStillImageOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer) {
NSData *imageData=[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image=[UIImage imageWithData:imageData];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc]init];
[assetsLibrary writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];
#pragma mark 切换前后摄像头
- (IBAction)toggleButtonClick:(UIButton *)sender {
AVCaptureDevice *currentDevice=[self.captureDeviceInput device];
AVCaptureDevicePosition currentPosition=[currentDevice position];
[self removeNotificationFromCaptureDevice:currentDevice];
AVCaptureDevice *toChangeD
AVCaptureDevicePosition toChangePosition=AVCaptureDevicePositionF
if (currentPosition==AVCaptureDevicePositionUnspecified||currentPosition==AVCaptureDevicePositionFront) {
toChangePosition=AVCaptureDevicePositionB
toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition];
[self addNotificationToCaptureDevice:toChangeDevice];
//获得要调整的设备输入对象
AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil];
//改变会话的配置前一定要先开启配置,配置完成后提交配置改变
[self.captureSession beginConfiguration];
//移除原有输入对象
[self.captureSession removeInput:self.captureDeviceInput];
//添加新的输入对象
if ([self.captureSession canAddInput:toChangeDeviceInput]) {
[self.captureSession addInput:toChangeDeviceInput];
self.captureDeviceInput=toChangeDeviceI
//提交会话配置
[self.captureSession commitConfiguration];
[self setFlashModeButtonStatus];
#pragma mark 自动闪光灯开启
- (IBAction)flashAutoClick:(UIButton *)sender {
[self setFlashMode:AVCaptureFlashModeAuto];
[self setFlashModeButtonStatus];
#pragma mark 打开闪光灯
- (IBAction)flashOnClick:(UIButton *)sender {
[self setFlashMode:AVCaptureFlashModeOn];
[self setFlashModeButtonStatus];
#pragma mark 关闭闪光灯
- (IBAction)flashOffClick:(UIButton *)sender {
[self setFlashMode:AVCaptureFlashModeOff];
[self setFlashModeButtonStatus];
#pragma mark - 通知
给输入设备添加通知
-(void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{
//注意添加区域改变捕获通知必须首先设置设备允许捕获
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
captureDevice.subjectAreaChangeMonitoringEnabled=YES;
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
//捕获区域发生改变
[notificationCenter addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
-(void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
移除所有通知
-(void)removeNotification{
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self];
-(void)addNotificationToCaptureSession:(AVCaptureSession *)captureSession{
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
//会话出错
[notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession];
设备连接成功
@param notification 通知对象
-(void)deviceConnected:(NSNotification *)notification{
NSLog(@&设备已连接...&);
设备连接断开
@param notification 通知对象
-(void)deviceDisconnected:(NSNotification *)notification{
NSLog(@&设备已断开.&);
捕获区域改变
@param notification 通知对象
-(void)areaChange:(NSNotification *)notification{
NSLog(@&捕获区域改变...&);
@param notification 通知对象
-(void)sessionRuntimeError:(NSNotification *)notification{
NSLog(@&会话发生错误.&);
#pragma mark - 私有方法
取得指定位置的摄像头
@param position 摄像头位置
@return 摄像头设备
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *camera in cameras) {
if ([camera position]==position) {
改变设备属性的统一操作方法
@param propertyChange 属性改变操作
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{
AVCaptureDevice *captureDevice= [self.captureDeviceInput device];
//注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁
if ([captureDevice lockForConfiguration:&error]) {
propertyChange(captureDevice);
[captureDevice unlockForConfiguration];
NSLog(@&设置设备属性过程发生错误,错误信息:%@&,error.localizedDescription);
设置闪光灯模式
@param flashMode 闪光灯模式
-(void)setFlashMode:(AVCaptureFlashMode )flashMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFlashModeSupported:flashMode]) {
[captureDevice setFlashMode:flashMode];
设置聚焦模式
@param focusMode 聚焦模式
-(void)setFocusMode:(AVCaptureFocusMode )focusMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFocusModeSupported:focusMode]) {
[captureDevice setFocusMode:focusMode];
设置曝光模式
@param exposureMode 曝光模式
-(void)setExposureMode:(AVCaptureExposureMode)exposureMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isExposureModeSupported:exposureMode]) {
[captureDevice setExposureMode:exposureMode];
设置聚焦点
@param point 聚焦点
-(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFocusModeSupported:focusMode]) {
[captureDevice setFocusMode:AVCaptureFocusModeAutoFocus];
if ([captureDevice isFocusPointOfInterestSupported]) {
[captureDevice setFocusPointOfInterest:point];
if ([captureDevice isExposureModeSupported:exposureMode]) {
[captureDevice setExposureMode:AVCaptureExposureModeAutoExpose];
if ([captureDevice isExposurePointOfInterestSupported]) {
[captureDevice setExposurePointOfInterest:point];
添加点按手势,点按时聚焦
-(void)addGenstureRecognizer{
UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)];
[self.viewContainer addGestureRecognizer:tapGesture];
-(void)tapScreen:(UITapGestureRecognizer *)tapGesture{
CGPoint point= [tapGesture locationInView:self.viewContainer];
//将UI坐标转化为摄像头坐标
CGPoint cameraPoint= [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point];
[self setFocusCursorWithPoint:point];
[self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint];
设置闪光灯按钮状态
-(void)setFlashModeButtonStatus{
AVCaptureDevice *captureDevice=[self.captureDeviceInput device];
AVCaptureFlashMode flashMode=captureDevice.flashM
if([captureDevice isFlashAvailable]){
self.flashAutoButton.hidden=NO;
self.flashOnButton.hidden=NO;
self.flashOffButton.hidden=NO;
self.flashAutoButton.enabled=YES;
self.flashOnButton.enabled=YES;
self.flashOffButton.enabled=YES;
switch (flashMode) {
case AVCaptureFlashModeAuto:
self.flashAutoButton.enabled=NO;
case AVCaptureFlashModeOn:
self.flashOnButton.enabled=NO;
case AVCaptureFlashModeOff:
self.flashOffButton.enabled=NO;
self.flashAutoButton.hidden=YES;
self.flashOnButton.hidden=YES;
self.flashOffButton.hidden=YES;
设置聚焦光标位置
@param point 光标位置
-(void)setFocusCursorWithPoint:(CGPoint)point{
self.focusCursor.center=
self.focusCursor.transform=CGAffineTransformMakeScale(1.5, 1.5);
self.focusCursor.alpha=1.0;
[UIView animateWithDuration:1.0 animations:^{
self.focusCursor.transform=CGAffineTransformI
} completion:^(BOOL finished) {
self.focusCursor.alpha=0;
ViewController.m
AVFoundationCamera
Created by Kenshin Cui on 14/04/05.
Copyright (c) 2014年 cmjstudio. All rights reserved.
#import &ViewController.h&
#import &AVFoundation/AVFoundation.h&
#import &AssetsLibrary/AssetsLibrary.h&
typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);
@interface ViewController ()&AVCaptureFileOutputRecordingDelegate&//视频文件输出代理
@property (strong,nonatomic) AVCaptureSession *captureS//负责输入和输出设备之间的数据传递
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceI//负责从AVCaptureDevice获得输入数据
@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileO//视频输出流
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewL//相机拍摄预览图层
@property (assign,nonatomic) BOOL enableR//是否允许旋转(注意在视频录制过程中禁止屏幕旋转)
@property (assign,nonatomic) CGRect *lastB//旋转的前大小
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskI//后台任务标识
@property (weak, nonatomic) IBOutlet UIView *viewC
@property (weak, nonatomic) IBOutlet UIButton *takeB//拍照按钮
@property (weak, nonatomic) IBOutlet UIImageView *focusC //聚焦光标
@implementation ViewController
#pragma mark - 控制器视图方法
- (void)viewDidLoad {
[super viewDidLoad];
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//}

我要回帖

更多关于 手机录视频软件哪个好 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信