第四章:多媒体应用开发
来源:互联网 发布:南京睿悦怎么样 知乎 编辑:程序博客网 时间:2024/06/05 08:49
一、音频和视频的播放
1、使用System Sound Services播放音效< AudioToolbox/AudioToolbox.h >
调使用System Sound Services播放音效这种方式是最简单、也是比较底层的音效播放服务,调用AudioServicesPlaySystemSound()这个函数播放一些简单的音频文件,但是只适合播放一些很小的提示或警告音频,它存在如下的限制:
- ①、声音长度不恩给你超过30秒;
- ②、声音文件必须是PCM或者IMA4(IMA/ADPCM)格式;
- ③、打包成.caf、aif或.wav的文件;
- ④、不能控制播放的进度;
- ⑤、没有循环播播放和立体声控制;
使用System Sound Services播放音频时可以调用系统的震动功能;可以为AudioServicesAddSystemSoundCompletion()函数来支持循环播放.
(1)、调用AudioServicesCreateSystemSoundID(CFURLRef inFileURL,SystemSoundID* outSystemSoundID);函数注册音频文件,该函数的第一个参数代表音频文件的URL(可通过NSURL转换为CFURLRef),第二个参数代表注册该音频文件的SystemSoundID;
(2)、如果需要在音频播放完成后执行某些操作,则可调用AudioServicesAddSystemSoundCompletion()函数为制定SystemSoundID注册Callback函数;
(3)、当需要播放音频时,调用AudioServicesPlaySystemSound()函数或AudioAudioServicesPlayAlertSound()函数–其中后一个函数播放音频时会调用系统的震动功能;
例如:
首先添加Audio Toolbox框架
然后添加 #import < AudioToolbox/AudioToolbox.h >头文件
static SystemSoundID crash = 0;//声音播放完成的回调函数static void completionCallback(SystemSoundID mySSID){AudioServicesPlaySystemSound(mySSID);}//点击播放声音- (void)clickBtn1{ //根据ID释放自定义系统声音 AudioServicesDisposeSystemSoundID(crash); //获取点击声音路径的URL NSURL* crashUrl = [[NSBundle mainBundle]URLForResource:@"Blues" withExtension:@"aif"]; //加载音频文件 AudioServicesCreateSystemSoundID((__bridge CFURLRef)crashUrl, &crash); /*添加音频结束时的回调*/ AudioServicesAddSystemSoundCompletion(crash, NULL, NULL, (void *)completionCallback, NULL); //播放crash代表的音频 AudioServicesPlayAlertSound(crash); //播放crash代表的音频,并控制设备震动 // AudioServicesPlaySystemSound(crash);}
2、使用AVAudioPlayer播放音乐< AVFoundation/AVFoundation.h >
AVAudioPlayer是一个属于AVFoundation.framework的类,它的作用类似于一个功能强大的播放器.AVAudioPlayer支持广泛的音频格式,主要是以下这些格式:
- ①、AAC;
- ②、AMR(Adaptive Multi-Rate,一直语言格式);
- ③、ALAC(Apple Lossless Audio Codec);
- ④、iLBC(Internet Low Bitrate Codec,另一种语音格式);
- ⑤、IMA4(IMA/ADPCM);
- ⑥、linearPCM(uncompressed);
- ⑦、u-law和a-law;
- ⑧、MP3(MPEG-Laudio Layer 3);
当程序控制用AVAudioPlayer对象转载音频完成之后,可以调用AVAudioPlayer的如下方法进行播放控制:
(1)、- (BOOL)play;开始或恢复播放.调用该方法时,如果该音频还没有准备好,程序会隐式先执行prepareToPlay方法.
(2)、- (BOOL)playAtTime:(NSTimeInterval)time;在指定时间点开始或恢复播放;
(3)、- (void)pause;暂停;
(4)、- (void)stop;停止;
(5)、- (BOOL)prepareToPlay;准备开始播放.调用play方法时,如果该音频还没有准备好,程序会隐式先执行该方法;
为了让AVAudioPlayer装载指定音频文件,AVAudioPlayer提供了如下的初始化方法:
(6)、- (instancetype)initWithContentsOfURL:(NSURL )url error:(NSError *)outError;从指定URL装载音频文件,并返回新创建的AVAudioPlayer对象;
(7)、- (instancetype)initWithData:(NSData )data error:(NSError *)outError;装载指定NSData对象所代表的音频数据,并返回新创建的AVAudioPlayer对象;
除此之外,AVAudioPlayer还提供了如下属性来访问音频文件的相关信息
(8)、@property(readonly, getter=isPlaying) BOOL playing;该只读属性返回播放器是否正在播放音频;
(9)、@property float volume;该属性用于设置和返回播放器的音量增益.该增益值可以为0~1.0;
(10)、@property float pan;该属性用于设置和返回立体声平衡.如果该属性设为-1.0,则完全在左边播放;如果设为0,则左右音量相同;如果设为1.0.则完全在右边播放;
(11)、@property float rate;该属性设置或返回播放速率.该属性值支持0.5(半速播放)~2.0(倍速播放);
(12)、@property BOOL enableRate;该属性设置或返回播放器是否允许改变播放速率;
(13)、@property NSInteger numberOfLoops;该属性设置或返回播放器的循环次数.如果将该属性设为-1,那么播放器将会一直播放,直到程序调用Stop方法停止播放.
(14)、@property(assign) id delegate;该属性用于为AVAudioPlayer设置代理对象;
(15)、@property(readonly) NSUInteger numberOfChannels;该只读属性返回音频的声道数目;
(16)、@property(readonly) NSTimeInterval duration;该只读属性返回音频的持续时间.
(17)、@property NSTimeInterval currentTime;该属性获取音频的播放点;
(18)、@property(readonly) NSTimeInterval deviceCurrentTime;该只读属性返回音频输出设备播放音频的时间.当音频播放器或暂停时,该属性值都会增加.
(19)、@property(readonly) NSURL *url;该只读属性返回播放器关联的音频URL;
(20)、@property(readonly) NSData *data;该只读属性返回播放器关联的音频数据;
例如:
为该项目添加AVFoundation框架,并添加
#import < AVFoundation/AVFoundation.h >
//定义要播放的音频文件的URLNSURL* fileUrl = [[NSBundle mainBundle]URLForResource:@"Blues" withExtension:@"aif"];//创建AVAudioPlayer对象audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:fileUrl error:nil];NSString* msg = [NSString stringWithFormat:@"音频文件的声道数:%ld\n音频文件的持续时间:%g",audioPlayer.numberOfChannels,audioPlayer.duration];show.text = msg;//将循环次数设为-1,用于指定该音频文件循环播放// audioPlayer.numberOfLoops = 1;//为AVAudioPlayer设置dialing,监听它的播放事件audioPlayer.delegate = self;- (void)play:(UIButton *)btn{ //如果当前正在播放 if (btn1.selected) { //暂停播放 btn1.selected = NO; [audioPlayer pause]; }else{ //播放音频 btn1.selected = YES; [audioPlayer play]; } //如果timer为nil,则执行如下方法 if (timer == nil) { timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateProg) userInfo:nil repeats:YES]; }}- (void)stop:(UIButton *)btn{ //设置当前播放为0 audioPlayer.currentTime = 0; //停止播放音频 [audioPlayer stop]; btn1.selected = NO; prog.progress = 0; [timer invalidate]; timer = nil;}- (void)updateProg{ prog.progress = audioPlayer.currentTime/audioPlayer.duration;}#pragma mark -AVAudioPlayerDelegate//当AVAudioPlayer播放完成后将会自动激发该方法- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ if (player == audioPlayer&&flag) { NSLog(@"播放完成!!"); }}- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{ if (player == audioPlayer) { NSLog(@"播放中断"); }}
3、使用MPMediaPickerController选择系统音乐< MPMediaPlayback >< MediaPlayer/MediaPlayer.h >
(1)、使用MPMediaPickerController选择音乐
步骤如下:
- ①、创建MPMediaPickerController对象;
- ②、将MPMediaPickerController显示出来;
创建MPMediaPickerController时可以使用initWithMediaTypes:初始化方法,该方法需要一个MPMediaType类型的参数,该参数用于指定可以选择那些类型的多媒体文件.MPMediaType的定义如下:
typedef NS_OPTIONS(NSUInteger, MPMediaType) { // audio MPMediaTypeMusic = 1 << 0, MPMediaTypePodcast = 1 << 1, MPMediaTypeAudioBook = 1 << 2, MPMediaTypeAudioITunesU NS_ENUM_AVAILABLE_IOS(5_0) = 1 << 3, MPMediaTypeAnyAudio = 0x00ff, // video (available in iOS 5.0) MPMediaTypeMovie NS_ENUM_AVAILABLE_IOS(5_0) = 1 << 8, MPMediaTypeTVShow NS_ENUM_AVAILABLE_IOS(5_0) = 1 << 9, MPMediaTypeVideoPodcast NS_ENUM_AVAILABLE_IOS(5_0) = 1 << 10, MPMediaTypeMusicVideo NS_ENUM_AVAILABLE_IOS(5_0) = 1 << 11, MPMediaTypeVideoITunesU NS_ENUM_AVAILABLE_IOS(5_0) = 1 << 12, MPMediaTypeHomeVideo NS_ENUM_AVAILABLE_IOS(7_0) = 1 << 13, MPMediaTypeAnyVideo NS_ENUM_AVAILABLE_IOS(5_0) = 0xff00, MPMediaTypeAny = ~0UL}
(2)、MPMediaPickerController创建成功后,将诶下来可以设置MPMediaPickerController的如下属性:
- ①、@property (nonatomic) BOOL allowsPickingMultipleItems;该属性设置或返回MPMediaPickerController是否允许同时选择多项;
- ②、@property (nonatomic) BOOL showsCloudItems;该属性设置或返回是否显示云端的多媒体文件;
- ③、@property (nonatomic, weak) id< MPMediaPickerControllerDelegate > delegate;为MPMediaPickerControllerDelegate指定委托,该委托对象负责处理用户选择的内容,该对象需要实现MPMediaPickerControllerDelegate协议;
- ④、@property (nonatomic, readonly) MPMediaType mediaTypes;该只读属性用于获取MPMediaPickerController允许选择的媒体类型;
- ⑤、@property (nonatomic, copy) NSString *prompt;该属性设置或返回MPMediaPickerController的提示信息.
(3)、#pragma mark -MPMediaPickerControllerDelegate
- ①、- (void)mediaPicker:(MPMediaPickerController )mediaPicker didPickMediaItems:(MPMediaItemCollection )mediaItemCollection;当用户通过MPMediaPickerController选择音乐文件后,程序将会激发该方法,通过该方法即可让程序获取用户刚刚选择的音乐.
- ②、- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker;
(4)、为了播放用户通过MPMediaPickerController选择的音乐,程序可以使用MPMusicPlayerController进行播放.MPMusicPlayerController有两种播放器可以选择:
- ①、+ (MPMusicPlayerController *)applicationMusicPlayer;该播放器是一种内部播放器,当程序退出后停止播放.
- ②、+ (MPMusicPlayerController *)iPodMusicPlayer;该播放器与iPod播放器内的信息相关,退出之后不回停止播放.
(5)、调用上述两种方法即可获取相对应的播放器,使用MPMusicPlayerController播放音乐的步骤如下:
- ①、创建MPMusicPlayerController对象;
- ②、调用MPMusicPlayerController对象的 - (void)setQueueWithQuery:(MPMediaQuery )query;或 - (void)setQueueWithItemCollection:(MPMediaItemCollection )itemCollection;方法设置将要播放的音乐队列;
- ③、调用MPMusicPlayerController的play、pause、stop方法控制播放;
(6)、MPMusicPlayerController提供了如下属性管理播放器模式和播放状态
- ①、@property(nonatomic) NSTimeInterval currentPlaybackTime;该属性返回或设置音乐的播放时间点;
- ②、@property(nonatomic) float currentPlaybackRate;该属性返回或这是音乐的播放速率;
- ③、@property (nonatomic, copy) MPMediaItem *nowPlayingItem;该属性返回或设置正在播放的音乐;
- ④、@property (nonatomic, readonly) MPMusicPlaybackState playbackState;该只读属性返回播放器当前的播放状态.该属性支持
typedef NS_ENUM(NSInteger, MPMusicPlaybackState) {MPMusicPlaybackStateStopped,//停止MPMusicPlaybackStatePlaying,//播放MPMusicPlaybackStatePaused,//暂停MPMusicPlaybackStateInterrupted,//被中断MPMusicPlaybackStateSeekingForward,//向前快进MPMusicPlaybackStateSeekingBackward//向后快退};
- ⑤、@property (nonatomic) MPMusicRepeatMode repeatMode;该属性设置或返回播放音乐的随机模式.该属性支持
typedef NS_ENUM(NSInteger, MPMusicRepeatMode) {MPMusicRepeatModeDefault, // the user's preference for repeat modeMPMusicRepeatModeNone,MPMusicRepeatModeOne,MPMusicRepeatModeAll};
- ⑥、@property (nonatomic) MPMusicShuffleMode shuffleMode;该属性设置或返回播放音乐的随机模式.该属性支持
typedef NS_ENUM(NSInteger, MPMusicShuffleMode) { MPMusicShuffleModeDefault, // the user's preference for shuffle mode MPMusicShuffleModeOff, MPMusicShuffleModeSongs, MPMusicShuffleModeAlbums};
- ⑦ 、@property (nonatomic) float volume;该属性设置或返回播放器音乐的音量;
(7)、MPMusicPlayerController提供了如下方法控制音乐播放:
- ①、- (void)play;播放音乐;
- ②、- (void)pause;暂停播放;
- ③、- (void)stop;停止播放;
- ④、- (void)beginSeekingForward;向前快进;
- ⑤、- (void)beginSeekingBackward;向后快退;
- ⑥、- (void)endSeeking;结束快进;
- ⑦、- (void)skipToNextItem;跳到下一首音乐;
- ⑧、- (void)skipToBeginning;跳到第一首音乐;
- ⑨、- (void)skipToPreviousItem;跳到上一首音乐;
例如:
首先该项目添加MediPlayer框架
并在上面控制类的实现部分使用 #import < MediaPlayer/MediaPlayer.h >
接口部分:
#import <UIKit/UIKit.h>#import <MediaPlayer/MediaPlayer.h>@interface RootViewController : UIViewController<MPMediaPickerControllerDelegate,UITableViewDataSource,UITableViewDelegate>@property (nonatomic, strong)UITableView* table;@end实现部分:#import "RootViewController.h"@interface RootViewController (){MPMediaPickerController* mpc;MPMusicPlayerController* musicPlayer;MPMediaItemCollection* itemList;}@end@implementation RootViewController- (void)viewDidLoad { [super viewDidLoad]; [self createTable]; UIBarButtonItem* bn = [[UIBarButtonItem alloc]initWithTitle:@"选择音乐" style:UIBarButtonItemStylePlain target:self action:@selector(choose:)]; self.navigationItem.rightBarButtonItem = bn;UIBarButtonItem* bn1 = [[UIBarButtonItem alloc]initWithTitle:@"停止" style:UIBarButtonItemStylePlain target:self action:@selector(stop:)]; self.navigationItem.leftBarButtonItem = bn1; //创建音乐播放器 musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; //创建MPMediaPickerController对象 mpc = [[MPMediaPickerController alloc]initWithMediaTypes:MPMediaTypeAnyAudio]; //为MPMediaPickerController设置委托 mpc.delegate = self; //设置选择音乐的提示文字 mpc.prompt = @"请选择您喜欢的音乐"; //设置是否允许进行多选 mpc.allowsPickingMultipleItems = YES; //设置是否允许选择云端音乐 mpc.showsCloudItems = YES;}- (void)createTable{ self.table = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 20)]; _table.delegate = self; _table.dataSource = self; [self.view addSubview:_table];}//点击跳转系统的音乐- (void)choose:(UIBarButtonItem *)item{ //必须以model方式显示MPMusicPlayerController视图控制器 [self presentViewController:mpc animated:YES completion:NULL];}- (void)stop:(UIBarButtonItem *)item{ [musicPlayer stop];}#pragma mark -UITableViewDelegate//行高- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 40;}//行数- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ //用户选择了多少首音乐,该表格就包含多少行 return itemList.count;}//自定义cell- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString* cellId = @"cellId"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; } //获取表格行的行号 NSUInteger rowNo = indexPath.row; //为表格行的textLabel设置文本 cell.textLabel.text = [[itemList.items objectAtIndex:rowNo] valueForProperty:MPMediaItemPropertyTitle]; return cell;}- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ //获取表格行的行号 NSUInteger rowNo = indexPath.row; //设置播放器正要播放的音乐 musicPlayer.nowPlayingItem = [itemList.items objectAtIndex:rowNo]; //开始播放 [musicPlayer play];}#pragma mark -MPMediaPickerControllerDelegate//当用户选择指定音乐时激发该方法,mediaItemCollection代表用户选择的音乐- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{ //保存用户选择的音乐列表 itemList = mediaItemCollection; NSLog(@"itemList = %@",itemList); //将用户选择的音乐列表设置为musicPlayer的播放列表 [musicPlayer setQueueWithItemCollection:mediaItemCollection]; [self.table reloadData]; [mpc dismissViewControllerAnimated:YES completion:NULL];}//用户点击完成- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker{ NSLog(@"用户取消了选择"); [mpc dismissViewControllerAnimated:YES completion:NULL];}@end
4、使用MPMoviePlayerController播放视频< MPMediaPlayback>< MediaPlayer/MediaPlayer.h >
(1)、使用MPMoviePlayerController播放视频的步骤如下:
- ①、创建MPMoviePlayerController对象,创建该对象时可调用 - (instancetype)initWithContentURL:(NSURL *)url;方法执行初始化,该初始化方法接收一个NSURL对象,该对象代表了播放器将要播放的视频;
- ②、设置MPMoviePlayerController对象的view属性的frame,该属性用于控制播放器的可视界面大小和位置;
- ③、将MPMoviePlayerController对象的view属性添加到可视界面上进行播放;
(2)、创建MPMoviePlayerController对象之后,该对象提供了如下属性来获取视频的相关信息;
- ①、@property (nonatomic, copy) NSURL *contentURL;该属性设置或返回MPMoviePlayerController关联的视频的NSURL对象.通过该属性可控制播放器播放另一段视频.
- ②、@property (nonatomic, readonly) MPMovieMediaTypeMask movieMediaTypes;该属性返回MPMoviePlayerController播放的多媒体类型.该属性返回值为:
typedef NS_OPTIONS(NSUInteger, MPMovieMediaTypeMask) { MPMovieMediaTypeMaskNone = 0, MPMovieMediaTypeMaskVideo = 1 << 0, MPMovieMediaTypeMaskAudio = 1 << 1};
- ③、@property (nonatomic) BOOL allowsAirPlay;该属性返回或设置是否允许无线播放视频;
- ④、@property (nonatomic, readonly, getter=isAirPlayVideoActive) BOOL airPlayVideoActive;该只读属性返回当前是否处于无线播放模式;
- ⑤、@property (nonatomic, readonly) CGSize naturalSize;该只读属性返回视频的大小;
- ⑥、@property (nonatomic, getter=isFullscreen) BOOL fullscreen;该属性返回视频是否处于全屏播放模式;
- ⑦、@property (nonatomic) MPMovieScalingMode scalingMode;该属性设置或返回视频的缩放模式.该属性支持:
typedef NS_ENUM(NSInteger, MPMovieScalingMode) { MPMovieScalingModeNone, // No scaling MPMovieScalingModeAspectFit, // Uniform scale until one dimension fits MPMovieScalingModeAspectFill, // Uniform scale until the movie fills the visible bounds. One dimension may have clipped contents MPMovieScalingModeFill // Non-uniform scale. Both render dimensions will exactly match the visible bounds};
- ⑧、@property (nonatomic, readonly) NSTimeInterval duration;该只读属性返回视频总的播放时间;
- ⑨、@property (nonatomic, readonly) NSTimeInterval playableDuration;该属性返回视频已下载的、可播放部分的持续时间.
(3)、另外还支持如下属性:
- ①、@property (nonatomic) MPMovieControlStyle controlStyle;播放器的控制条风格,支持如下
typedef NS_ENUM(NSInteger, MPMovieControlStyle) { MPMovieControlStyleNone, // No controls MPMovieControlStyleEmbedded, // Controls for an embedded view MPMovieControlStyleFullscreen, // Controls for fullscreen playback MPMovieControlStyleDefault = MPMovieControlStyleEmbedded};
- ②、@property (nonatomic) MPMovieRepeatMode repeatMode;播放器的重复播放
typedef NS_ENUM(NSInteger, MPMovieRepeatMode) { MPMovieRepeatModeNone, MPMovieRepeatModeOne};
- ③、- (void)setFullscreen:(BOOL)fullscreen animated:(BOOL)animated; 使播放器充满整个屏幕;
- ④、@property (nonatomic, readonly) MPMoviePlaybackState playbackState;播放状态
typedef NS_ENUM(NSInteger, MPMoviePlaybackState) { MPMoviePlaybackStateStopped,//停止 MPMoviePlaybackStatePlaying,//播放 MPMoviePlaybackStatePaused,//暂停 MPMoviePlaybackStateInterrupted,//被中断 MPMoviePlaybackStateSeekingForward,//前进 MPMoviePlaybackStateSeekingBackward//倒退};
- ⑤、@property (nonatomic, readonly) MPMovieLoadState loadState;视频加载状态
typedef NS_OPTIONS(NSUInteger, MPMovieLoadState) { MPMovieLoadStateUnknown = 0,//未知类型 MPMovieLoadStatePlayable = 1 << 0,//可以播放 MPMovieLoadStatePlaythroughOK = 1 << 1,//同上 MPMovieLoadStateStalled = 1 << 2, //缓冲中};
(4)、提示:通知
- ①、MPMoviePlayerPlaybackDidFinishNotification:播放完成通知;
- ②、MPMovieDurationAvailableNotification:总时间获取通知;
- ③、 MPMediaPlaybackIsPreparedToPlayDidChangeNotification:准备播放通知;
- ④、 MPMoviePlayerPlaybackStateDidChangeNotification:播放状态改变通知;
- ⑤、 MPMoviePlayerLoadStateDidChangeNotification:视频加载状态通知;
例如:
首先该项目添加MediPlayer框架
并在上面控制类的实现部分使用 #import < MediaPlayer/MediaPlayer.h >
//创建本地URL(也可以创建网络URL)NSURL* movieUrl = [[NSBundle mainBundle]URLForResource:@"bsm" withExtension:@"mp4"];//使用指定URL创建MPMoviePlayerController//MPMoviePlayerController将会播放该URL对应的视频moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:movieUrl];//设置该播放器的控制条风格moviePlayer.controlStyle = MPMovieControlStyleEmbedded;//设置该播放器的缩放模式moviePlayer.scalingMode = MPMovieScalingModeAspectFit;moviePlayer.movieSourceType = MPMovieSourceTypeFile;[moviePlayer prepareToPlay];NSLog(@"%f--%f",self.view.frame.size.height,self.view.frame.size.width);[moviePlayer.view setFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64)];[self.view addSubview:moviePlayer.view];// Movie Player Notifications//MP_EXTERN NSString * const MPMoviePlayerScalingModeDidChangeNotification;//MP_EXTERN NSString * const MPMoviePlayerPlaybackDidFinishNotification;//等//提示:或者直接使用MPMoviePlayerViewController播放视频- (void)buttonClick{ [self presentMoviePlayerViewControllerAnimated:_playerView]; [_playerView.moviePlayer play];}NSString* path = [[NSBundle mainBundle] pathForResource:@"bsm" ofType:@"mp4"];NSURL* url = [NSURL fileURLWithPath:path];_playerView = [[MPMoviePlayerViewController alloc] initWithContentURL:url];[self presentMoviePlayerViewControllerAnimated:_playerView];[_playerView.moviePlayer play];
二、使用AVAudioRecorder录制音频< AVFoundation/AVFoundation.h >
(1)、AVAudioRecorder与AVAudioPlayer类似,他们都属于AVFoundation.framework的类,AVAudioRecorder的功能类似于一个录音器,使用AVAudioRecorder录制音频,先创建然后调用如下方法:
- ①、- (BOOL)prepareToRecord;准备开始录制.调用record方法时,如果音频还没有准备好,程序会隐式执行该方法.
- ②、- (BOOL)record;开始或恢复录制.调用该方法时,如果音频还没有准备好程序会隐式执行prepareToRecord方法.
- ③、- (BOOL)recordAtTime:(NSTimeInterval)time;在指定时间点开始或恢复录制.
- ④、- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval) duration;在指定时间点开始或恢复录制,并指定录制的持续时间.
- ⑤、- (void)pause;暂停.
- ⑥、- (void)stop;停止.
(2)、为了AVAudioRecorder录制的音频文件指定文件名,以及指定录制音频的相关选项,AVAudioRecorder提供了如下初始化方法:
- ①、 - (instancetype)initWithURL:(NSURL )url settings:(NSDictionary )settings error:(NSError **)outError;指定将录制的音频存入URL对应的音频文件.该方法的第二个参数需要一个NSDictionary对象,该对象包含大量的key-value对,用于设置录制音频的相关信息,其中key必须是AVFormatIDKey(格式)、AVSampleRateKey(采样率)、AVNumberOfChannelsKey(声道数)等常亮.具体参考AVFoundationAudioSettingsConstants.
(3)、使用AVAudioRecorder录制音频的步骤如下:
- ①、创建AVAudioRecorder对象.在创建AVAudioRecorder对象之前,先要准备一个NSDictionary对象,该对象中封装了音频的相关设置信息.
- ②、如果需要监听录制完成、录制被中断的事件,则应该为AVAudioRecorder对象设置delegate对象,delegate对象需要实现AVAudioRecorderDelegate协议.
- ③、调用AVAudioRecorder对象的record方法录制音频.
例如:
该项目需要先添加AVFoundation框架
然后添加头文件 #import < AVFoundation/AVFoundation.h >
声明部分
#import <UIKit/UIKit.h>#import <AVFoundation/AVFoundation.h>@interface ViewController : UIViewController<AVAudioRecorderDelegate>@end
实现部分
#import "ViewController.h"@interface ViewController (){ AVAudioRecorder* audioRecorder; AVAudioPlayer* audioPlayer;}@property (nonatomic ,strong)UISegmentedControl* sampleRateSeg;@property (nonatomic ,strong)UISegmentedControl* bitDeptSeg;@property (nonatomic ,strong)UISwitch* steroSwitch;@property (nonatomic ,strong)UIButton* recordBn;@property (nonatomic ,strong)UIButton* playBn;//该属性代表应用的Documents目录@property (nonatomic ,copy)NSString* documentPath;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; UILabel* sampleRateLabel = [[UILabel alloc]initWithFrame:CGRectMake(40, 100, 100, 40)]; sampleRateLabel.text = @"采样率"; [self.view addSubview:sampleRateLabel]; self.sampleRateSeg = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"22050",@"44100", nil]]; _sampleRateSeg.frame = CGRectMake(self.view.frame.size.width - 140, 100, 100, 40); _sampleRateSeg.selectedSegmentIndex = 0; [self.view addSubview:_sampleRateSeg]; UILabel* bitDeptLabel = [[UILabel alloc]initWithFrame:CGRectMake(40, 160, 100, 40)]; bitDeptLabel.text = @"采样位数"; [self.view addSubview:bitDeptLabel]; self.bitDeptSeg = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"8",@"16",@"24",@"32", nil]]; _bitDeptSeg.frame = CGRectMake(self.view.frame.size.width - 140, 160, 100, 40); _bitDeptSeg.selectedSegmentIndex = 0; [self.view addSubview:_bitDeptSeg]; UILabel* steroLabel = [[UILabel alloc]initWithFrame:CGRectMake(40, 220, 100, 40)]; steroLabel.text = @"双声道"; [self.view addSubview:steroLabel]; self.steroSwitch = [[UISwitch alloc]initWithFrame:CGRectMake(self.view.frame.size.width - 80, 220, 40, 40)]; [self.view addSubview:_steroSwitch]; self.recordBn = [UIButton buttonWithType:UIButtonTypeRoundedRect];_recordBn.frame = CGRectMake(self.view.frame.size.width -100, 280, 60, 40); [_recordBn setTitle:@"录制" forState:UIControlStateNormal]; [_recordBn addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:_recordBn]; self.playBn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; _playBn.frame = CGRectMake(self.view.frame.size.width -100, 340, 60, 40); [_playBn setTitle:@"播放" forState:UIControlStateNormal]; [_playBn addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:_playBn]; //获取当前应用的音频会话AVAudioSession* audioSession = [AVAudioSession sharedInstance]; //设置音频类别,PlayAndRecord--这说明当前音频会话即可播放,也可录制 [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; //激活当前应用的音频会话 [audioSession setActive:YES error:nil];}//获取Document目录的路径- (NSString *)documentsPath{ if (!_documentPath) { NSArray* searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); _documentPath = [searchPaths objectAtIndex:0]; } return _documentPath;}- (void)clicked:(UIButton *)btn{ if (audioRecorder != nil && audioRecorder.isRecording) { [audioRecorder stop]; [_recordBn setTitle:@"录制" forState:UIControlStateNormal]; }else{ //获取音频文件的保存路径 NSString* destinationString = [[self documentsPath]stringByAppendingString:@"sound.wav"]; NSURL* destinationURL = [NSURL fileURLWithPath:destinationString]; NSMutableDictionary* recodSettings = [[NSMutableDictionary alloc]init]; //设置录制音频的格式--AVFormatIDKey==kAudioFormatLinearPCM [recodSettings setObject:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey]; //设置录制音频的采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量) NSString* sampleRate = [self.sampleRateSeg titleForSegmentAtIndex:self.sampleRateSeg.selectedSegmentIndex]; [recodSettings setObject:[NSNumber numberWithFloat:sampleRate.floatValue] forKey:AVSampleRateKey]; //设置录制视频的每个样点的位数 8、16、24、32 NSString* bitDepth = [self.bitDeptSeg titleForSegmentAtIndex:self.bitDeptSeg.selectedSegmentIndex]; [recodSettings setObject:[NSNumber numberWithInt:bitDepth.intValue] forKey:AVLinearPCMBitDepthKey]; //设置录制音频的通道数 1 或 2 [recodSettings setObject:[NSNumber numberWithInt:(self.steroSwitch.on? 2:1)] forKey:AVNumberOfChannelsKey]; //设置录制音频采用高位优先的记录格式 [recodSettings setObject:[NSNumber numberWithBool:YES] forKey:AVLinearPCMIsBigEndianKey]; //设置采样信号采用浮点数 [recodSettings setObject:[NSNumber numberWithBool:YES] forKey:AVLinearPCMIsFloatKey]; NSError* recorderSetupError = nil; //初始化AVAudioRecorder audioRecorder = [[AVAudioRecorder alloc]initWithURL:destinationURL settings:recodSettings error:&recorderSetupError]; audioRecorder.delegate = self; [audioRecorder record]; [_recordBn setTitle:@"录制中" forState:UIControlStateNormal]; }}- (void)play:(UIButton *)btn{ //或群殴音频文件的保存路径 NSString* destinationString = [[self documentsPath]stringByAppendingString:@"sound.wav"]; NSURL* url= [NSURL fileURLWithPath:destinationString]; //创建AVAudioPlayer对象 audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil]; //开始播放 [audioPlayer play];}#define mark -AVAudioRecorderDelegate- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{ if (flag) { NSLog(@"录制完成"); }}- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{ NSLog(@"被中断");}@end
//提示:获取下载的音乐的名称和URL-(void)getMpeFileFromCellphone{ //从ipod 库中读出音乐文件 MPMediaQuery *everything =[[MPMediaQuery alloc]init]; //读取文件 MPMediaPropertyPredicate *albumNamePredicate =[MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypeMusic] forProperty:MPMediaItemPropertyMediaType]; [everything addFilterPredicate:albumNamePredicate]; NSArray *itemsFromGenericQuery =[everything items]; NSLog(@"拿到的数组:%@",itemsFromGenericQuery); for (MPMediaItem *song in itemsFromGenericQuery) { //音乐名称 NSString *songTitle =[song valueForProperty:MPMediaItemPropertyTitle]; //音乐歌手 NSString *songArtist = [song valueForProperty:MPMediaItemPropertyArtist]; //音乐URL NSURL *url =[song valueForProperty:MPMediaItemPropertyAssetURL]; NSString *urlStr=[url absoluteString];//将url转化成string; NSLog(@"songTitle:%@,urlStr:%@,songArtist:%@",songTitle,urlStr,songArtist); }}
三、拍照和录制视频
1、使用UIImagePickerController拍照和录制视频
UIImagePickerController是一个功能强大的视图控制器类,它继承了UINavigationController,因此完全可以作为视图控制器使用,开发者只要创建该类的实例,即可通过该实例来完成如下3种操作:
- (1)、选取手机相册的图片和视频;
- (2)、控制摄像头拍照;
- (3)、控制摄像头录制视频;
使用UIImagePickerController的步骤如下:
- (1)、创建UIImagePickerController对象;
- (2)、根据需要选择UIImagePickerController要完成的操作;
①、如果要控制UIImagePickerController选取手机相册中的图片和视频,则将该对象的sourceType设置为”UIImagePickerControllerSourceTypePhotoLibrary”.
②、如果要控制UIImagePickerController拍照或录制视频,则将该对象的sourceType设置为” UIImagePickerControllerSourceTypeCamera”.
- (3)、如果要控制UIImagePickerController使用哪个摄像头,则可设置cameraDevice属性.如果该属性被设置为”UIImagePickerControllerCameraDeviceFront”,则表明使用前置摄像头;如果该属性被设为”UIImagePickerControllerCameraDeviceRear”,则表明使用后置摄像头.
- (4)、如果要设置UIImagePickerController到底是拍照,还是录制视频,则可设置cameraCaptureMode属性.如果该属性设为”UIImagePickerControllerCameraCaptureModePhoto”(默认值),则代表拍照;如果该属性被设为”UIImagePickerControllerCameraCaptureModeVideo”,则代表录制视频.
提示:如果要录制视频,还需要设置该对象的mediaTypes属性.该属性值是一个NSArray,用于控制UIImagePickerController只支持哪些类型的多媒体数据,拨入kUTTypeImage代表图片,kUTTypeMovie代表视频(带声音),kUTTypeVideo代表视频(不带声音)….因此,如果程序要录制视频,mediaTypes属性值NSArray必须包含kUTTypeMovie. - (5)、如果程序需要在UIImagePickerController拍摄完成或拍摄取消时执行某些操作,则可为该对象指定delegate属性,该属性值必须是一个实现UIImagePickerControllerDelegate、UINavigationControllerDelegate两个协议的对象.
- (6)、将UIImagePickerController对象显示出来,总体而言,UIImagePickerController还有如下常用的属性:
①、@property(nonatomic)UIImagePickerControllerSourceType sourceType;该属性控制到底是选取手机相册中的图片还是拍摄;
②、@property(nonatomic)BOOL allowsEditing;该属性控制拍摄的照片是否允许编辑;
③、@property(nonatomic,copy)NSArray *mediaTypes;该属性控制到底是拍照还是录制视频;
④、@property(nonatomic)UIImagePickerControllerQualityType videoQuality;该属性设置录制的视频质量;
⑤、@property(nonatomic)NSTimeInterval videoMaximumDuration;该属性设置视频的最大录制时间;
⑥、@property(nonatomic)BOOL showsCameraControls;该属性设置是否显示拍摄按钮等控件;
⑦、@property(nonatomic)CGAffineTransform cameraViewTransform;该属性设置对浏览画面进行变换的变换矩阵;
⑧、@property(nonatomic)UIImagePickerControllerCameraDevice cameraDevice;该属性设置使用设备的哪个摄像头.典型的:
typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) { UIImagePickerControllerCameraDeviceRear, //代表后置摄像头 UIImagePickerControllerCameraDeviceFront //代表前置摄像头};
⑨、@property(nonatomic)UIImagePickerControllerCameraFlashMode cameraFlashMode;该属性设置拍摄模式,是拍摄照片还是录制视频;
①、@property(nonatomic)UIImagePickerControllerCameraFlashMode cameraFlashMode;该属性控制闪光灯的模式;
②、@property(nonatomic,assign)id < UINavigationControllerDelegate, UIImagePickerControllerDelegate > delegate;该属性用于为UIImagePickerController设置委托对象.
- (7)、除此之外,如果过程序需要通过代码来控制拍照和录制视频,则可调用如下方法:
①、- (void)takePicture;拍照;
②、- (BOOL)startVideoCapture;开始录制视频;
③、- (void)stopVideoCapture;结束录制视频;
例如:
提示:该实例中用到了
1. 导入库“AssetsLibrary.framework”
2.在要用的类中引入头文件:#import
#pragma mark - UIActionSheetDelegate- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ NSLog(@"%ld",buttonIndex); switch (buttonIndex) { case 0: //拍照 { //如果拍摄的摄像头可用 if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { //将sourceType设为UIImagePickerControllerSourceTypeCamera,代表拍照或录制视频 imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; //设置拍摄照片 imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto; //设置使用手机的后者摄像头(默认使用后置摄像头) imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear; //设置拍摄的照片允许编辑 imagePicker.allowsEditing = YES; }else{ NSLog(@"模拟器无法打开摄像头"); } [self presentViewController:imagePicker animated:YES completion:nil]; } break; case 1: //拍摄 { //如果拍摄的摄像头可用 if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){ //将sourceType设为UImagePickerControllerSourceTypeCamera,代表拍照或拍摄视频 imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; //将medioTypes设为所有支持的多媒体类型;imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera]; //设置录制视频 imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo; //设置录制视频质量 imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh; }else{ NSLog(@"模拟器无法打开摄像头"); } [self presentViewController:imagePicker animated:YES completion:nil]; } break; case 2: //选取照片 { //设置选取相册的照片或视频 imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; //将medioTypes设为所有支持的多媒体类型; imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; imagePicker.allowsEditing = NO; [self presentViewController:imagePicker animated:YES completion:nil]; } default: break; }}#pragma mark - UIImagePickerControllerDelegate//当得到图片或者视频后,调用该方法- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ NSLog(@"成功:%@",info); //获取用户拍摄的是照片还是视频 NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType]; NSLog(@"%@",mediaType); NSLog(@"mediaTypes = %@",picker.mediaTypes); //判断获取类型:照片,并且是刚拍摄的照片 if ([mediaType isEqualToString:@"public.image"] && picker.sourceType == UIImagePickerControllerSourceTypeCamera){ UIImage* theImage = nil; if ([picker allowsEditing]) { //获取用户编辑之后的图片 theImage = [info objectForKey:UIImagePickerControllerEditedImage]; }else{ theImage = [info objectForKey:UIImagePickerControllerOriginalImage]; } //保存照片到相册中 UIImageWriteToSavedPhotosAlbum(theImage, self, nil, nil); } //判断获取类型:视频,并且是刚录制的视频 else if ([mediaType isEqualToString:@"public.movie"] && picker.sourceType == UIImagePickerControllerSourceTypeCamera){ //获取视频文件的URL NSURL* mediaURL = [info objectForKey:UIImagePickerControllerMediaURL]; //创建ALAssetsLibrary对象并将视频保存到媒体库ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc]init]; //将视频保存到相册中 [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:mediaURL completionBlock:^(NSURL *assetURL, NSError *error) { //如果没有错误,则保存成功 if (!error) { NSLog(@"视频保存成功"); }else{ NSLog(@"保存视频出现错误:%@",error); } }]; } //判断是选取照片 else if ([mediaType isEqualToString:@"public.image"] && picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary){ UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage]; }else if ([mediaType isEqualToString:@"public.movie"] && picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary){ //视频播放URL NSURL* movieURL = [info objectForKey:UIImagePickerControllerReferenceURL]; } [picker dismissViewControllerAnimated:YES completion:nil];}//当用户点击取消时,调用该方法- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ NSLog(@"用户点击取消拍摄"); [picker dismissViewControllerAnimated:YES completion:nil];}
2、使用AVFoundation拍照和录制视频
如果开发者需要开发自定义的拍照和录制视频功能,则可借助于AVFoundation框架来实现,该框架提供了大量的类来完成拍照和录制视频.主要使用如下类:
(1)、AVCaptureDevice:该对象代表物理输入设备,包括摄像头和麦克风.开发者可通过该对象来配置底层物理设备的属性.需要指出的是,开发者不能直接创建该类的实例,只能通过该类的devices、defaultDeviceWithMediaType:(NSString )mediaType、devicesWithMediaType:(NSString )mediaType方法来获取对应的输入设备数组,接下来即可获取前置摄像头、后置摄像头或麦克风等.
一旦获取elAVMediaTypeVideo类型对应的设备(摄像头),程序就可设置该对象的额对焦模式、闪光灯模式、曝光模式、白平衡等各种拍照相关属性.在配置摄像头的相关性之前,必须先调用lockForConfiguration:方法执行锁定,配置完成后调用unlickForConfiguration方法解锁.
AVCapturaDevice代表物理输入设备将会把捕捉到得视频或声音数据提交给AVCaptureSession对象.
- (2)、AVCaptureSession:该对象负责把AVCaptureDevice捕捉得到的视频或声音数据输出到输出设备中.不管执行实时的还是离线的录制,开发者都必须创建AVCaptureSession对象,并为该对象添加输入设备(负责捕捉数据)和输出端(负责接收数据).例如:如下代码片段:
AVCaptureSession* captureSession = [[AVCaptureSession alloc]init];AVCaptureDevice* audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];NSError* error = nil;AVCaptureDeviceInput* audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];if (audioInput) { [captureSession addInput:audioInput];}else{ //handle the failure}
- (3)、AVCaptureDeviceInput:它是AVCaptureInput得子类,开发者使用该对象从AVCaptureDevice设备获取数据.该对象将会被添加给AVCaptureSession管理;
- (4)、AVCaptureScreenInput:它也是AVCaptureInput的子类,开发者使用该对象从屏幕获取数据(用于录制屏幕动作).该对象将会被添加给AVCaptureSession管理.
- (5)、AVCaptureAudioDataOutput、AVCaptureAudioPreviewOutput、AVCaptureFileOutput、AVCaptureStillImageOutput、AVCaptureVideoDataOutput:他们都是AVCaptureOutput的子类,用于接收各种数据.该对象也会被添加给AVCaptureSession管理.其中AVCaptureFileOutput依然代表输出到文件的输出端.
- (6)、AVCaptureAudioFileOutput、AVCaptureMovieFileOutput:它们都是AVCaptureFileOutput的子类,分别代表输出到音频文件、电影文件的输出段.
- (7)、AVCaptureVideoPreviewLayer:该对象是CALayer的子类,开发者只要创建它的实力,并为它设置AVCaptureSession,就可以非常方便的用它来实现拍摄预览.
//得到AVCaptureSession对象AVCaptureSession* captureSession = [[AVCaptureSession alloc]init];//创建AVCaptureVideoPreviewLayer,并传入AVCaptureSession对象AVCaptureVideoPreviewLayer* previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];//获取显示AVCaptureVideoPreviewLayer的UIView控件UIView* aView;//获取view//设置预览layer与UIView大小相同,并将预览layer显示出来previewLayer.frame = aView.bounds;[aView.layer addSublayer:previewLayer];
使用AVFoundation实现拍照和录制视频的大致步骤如下:
- ①、使用AVCaptureDevice的静态方法获取设备,包括摄像头和麦克风都通过这种方式来获取;
- ②、利用AVCaptureDevice初始化AVCaptureDeviceInput对象,无论摄像头还是麦克风都可通过这种方式转为AVCaptureDeviceInput对象;
- ③、初始化输出端.如果只是拍照,则初始化AVCaptureStillImageOutput输出端即可;如果要捕捉视频,则初始化AVCaptureMovieFileOutput输出端;
- ④、创建AVCaptureSession对象,使用该对象来添加输入设备和输出端.调用AVCaptureSession的startRunning方法开始捕捉画面或声音数据;
- ⑤、将捕捉的数据(照片、视频数据)输出到指定文件.
代码略:
四、使用AVFoundation生成视频缩略图
AVFoundation还可以用来生成视频缩略图.AVFoundation生成视频缩略图主要靠如下两个类.
- (1)、AVURLAsset:该类是AVAsset的子类,AVAsset类专门用于获取多媒体的相关信息,包括获取多媒体的画面、声音等信息.而AVURLAsset子类的作用则是根据NSURL来初始化AVAsset对象.
- (2)、AVAssetImageGenerator:该类专门用于截取视频指定帧的画面;
使用AVFoundation生成视频缩略图的步骤如下:- ①、根据视频的NSURL创建AVURLAsset对象;
- ②、根据AVURLAsset对象创建AVAssetImageGenerator对象;
- ③、调用AVAssetImageGenerator对象的copyCGImageAtTime:actualTime:error:方法来获取该视频指定时间点的视频截图.该方法的第一个CMTime参数用于指定获取哪个时间点的视频截图,第二个CMTime参数用于获取实际截图位于哪个时间点;
- (3)、CMTimeMake(int64_ value,int32_t timescale):第一个参数代表获取第几帧的截图,第二个参数代表每秒的帧数.因此实际截取的时间点是value/timescale;
- (4)、CMTime CMTimeMakeWithSeconds(Float64 seconds,int32_t preferredTimeScale):第一个参数代表获取第几秒的截图,第二个参数则代表每秒的帧数.
例如:
#import "UIImage+Video.h"#import <AVFoundation/AVFoundation.h>@implementation UIImage (Video)- (UIImage *)imageWithVideo:(NSURL *)videoURL{ //根据视频的URL创建AVURLAsset AVURLAsset* asset = [[AVURLAsset alloc]initWithURL:videoURL options:nil]; //根据AVURLAsset创建AVAssetImageGenerator对象 AVAssetImageGenerator* gen = [[AVAssetImageGenerator alloc]initWithAsset:asset]; // gen.appliesPreferredTrackTransform = YES; //定义获取0帧处的视频截图 CMTime time = CMTimeMake(0, 10); NSError* error = nil; CMTime actualTime; //获取time处的视频截图 CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error]; //将CGImageRef转换为UIImage UIImage* thumb = [[UIImage alloc]initWithCGImage:image];CGImageRelease(image); return thumb;}
- 第四章:多媒体应用开发
- HiMPP多媒体应用开发
- Android应用开发揭秘(笔记) 第七章 多媒体开发
- 多媒体应用开发1---MediaPlayer
- 多媒体应用练习---照相机开发
- J2ME MMAPI开发移动多媒体应用
- Android多媒体应用开发-控制摄像头拍照
- Android多媒体应用开发-控制摄像头拍照
- Android开发_多媒体的简单应用
- Android-应用开发-多媒体编程(九)
- Android多媒体应用开发系列(一) 拍照
- 多媒体应用
- Knockout应用开发指南 第四章:模板绑定
- LBS应用开发读书有感(第四章 内容选择)
- Knockout应用开发指南 第四章:模板绑定
- Knockout应用开发指南 第四章:模板绑定
- Knockout应用开发指南 第四章:模板绑定
- Knockout应用开发指南 第四章:模板绑定
- Word Break II 单词分割系列2
- Android Studio-gradle无法下载解决方案
- 多Fragment嵌套,出现数据内容清空的问题
- Memblaze发布企业级数据存储管理系统FlashRAID——从NVMe SSD出发,全面进击软件定义存储
- Mac下iTem2使用rz、sz上传下载
- 第四章:多媒体应用开发
- friend void fun(); 类的友元函数
- Android使用Ant批量打包Android应用签名和混淆
- 制作静态库并支持bitcode
- [图解]ACCESS数据库也能这么做--“登陆界面”四步成
- ajax data传参数时{id:id} 和 {id,id} 在谷歌下都能用,在其他浏览器{id,id}不能用
- Android开发:fiddler 抓https请求
- Python for循环 基础知识篇(重要)
- 百度UEditor添加视频 增加支持“通用代码”功能,支持微信