码迷,mamicode.com
首页 > 其他好文 > 详细

第四章:多媒体应用开发

时间:2016-06-21 06:54:05      阅读:530      评论:0      收藏:0      [点我收藏+]

标签:

一、音频和视频的播放

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 >
技术分享
技术分享

//定义要播放的音频文件的URL
NSURL* 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 mode
MPMusicRepeatModeNone,
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;
}

第四章:多媒体应用开发

标签:

原文地址:http://blog.csdn.net/xiaoxiaobukuang/article/details/51722542

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!