第四章:多媒体应用开发

来源:互联网 发布:南京睿悦怎么样 知乎 编辑:程序博客网 时间: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;}
0 0
原创粉丝点击