标签:
调使用System Sound Services播放音效这种方式是最简单、也是比较底层的音效播放服务,调用AudioServicesPlaySystemSound()这个函数播放一些简单的音频文件,但是只适合播放一些很小的提示或警告音频,它存在如下的限制:
(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);
}
AVAudioPlayer是一个属于AVFoundation.framework的类,它的作用类似于一个功能强大的播放器.AVAudioPlayer支持广泛的音频格式,主要是以下这些格式:
当程序控制用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(@"播放中断");
}
}
(1)、使用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的如下属性:
(3)、#pragma mark -MPMediaPickerControllerDelegate
(4)、为了播放用户通过MPMediaPickerController选择的音乐,程序可以使用MPMusicPlayerController进行播放.MPMusicPlayerController有两种播放器可以选择:
(5)、调用上述两种方法即可获取相对应的播放器,使用MPMusicPlayerController播放音乐的步骤如下:
(6)、MPMusicPlayerController提供了如下属性管理播放器模式和播放状态
typedef NS_ENUM(NSInteger, MPMusicPlaybackState) {
MPMusicPlaybackStateStopped,//停止
MPMusicPlaybackStatePlaying,//播放
MPMusicPlaybackStatePaused,//暂停
MPMusicPlaybackStateInterrupted,//被中断
MPMusicPlaybackStateSeekingForward,//向前快进
MPMusicPlaybackStateSeekingBackward//向后快退
};
typedef NS_ENUM(NSInteger, MPMusicRepeatMode) {
MPMusicRepeatModeDefault, // the user‘s preference for repeat mode
MPMusicRepeatModeNone,
MPMusicRepeatModeOne,
MPMusicRepeatModeAll
};
typedef NS_ENUM(NSInteger, MPMusicShuffleMode) {
MPMusicShuffleModeDefault, // the user‘s preference for shuffle mode
MPMusicShuffleModeOff,
MPMusicShuffleModeSongs,
MPMusicShuffleModeAlbums
};
(7)、MPMusicPlayerController提供了如下方法控制音乐播放:
例如:
首先该项目添加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
(1)、使用MPMoviePlayerController播放视频的步骤如下:
(2)、创建MPMoviePlayerController对象之后,该对象提供了如下属性来获取视频的相关信息;
typedef NS_OPTIONS(NSUInteger, MPMovieMediaTypeMask) {
MPMovieMediaTypeMaskNone = 0,
MPMovieMediaTypeMaskVideo = 1 << 0,
MPMovieMediaTypeMaskAudio = 1 << 1
};
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
};
(3)、另外还支持如下属性:
typedef NS_ENUM(NSInteger, MPMovieControlStyle) {
MPMovieControlStyleNone, // No controls
MPMovieControlStyleEmbedded, // Controls for an embedded view
MPMovieControlStyleFullscreen, // Controls for fullscreen playback
MPMovieControlStyleDefault = MPMovieControlStyleEmbedded
};
typedef NS_ENUM(NSInteger, MPMovieRepeatMode) {
MPMovieRepeatModeNone,
MPMovieRepeatModeOne
};
typedef NS_ENUM(NSInteger, MPMoviePlaybackState) {
MPMoviePlaybackStateStopped,//停止
MPMoviePlaybackStatePlaying,//播放
MPMoviePlaybackStatePaused,//暂停
MPMoviePlaybackStateInterrupted,//被中断
MPMoviePlaybackStateSeekingForward,//前进
MPMoviePlaybackStateSeekingBackward//倒退
};
typedef NS_OPTIONS(NSUInteger, MPMovieLoadState) {
MPMovieLoadStateUnknown = 0,//未知类型
MPMovieLoadStatePlayable = 1 << 0,//可以播放
MPMovieLoadStatePlaythroughOK = 1 << 1,//同上
MPMovieLoadStateStalled = 1 << 2, //缓冲中
};
(4)、提示:通知
首先该项目添加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];
(1)、AVAudioRecorder与AVAudioPlayer类似,他们都属于AVFoundation.framework的类,AVAudioRecorder的功能类似于一个录音器,使用AVAudioRecorder录制音频,先创建然后调用如下方法:
(2)、为了AVAudioRecorder录制的音频文件指定文件名,以及指定录制音频的相关选项,AVAudioRecorder提供了如下初始化方法:
(3)、使用AVAudioRecorder录制音频的步骤如下:
例如:
该项目需要先添加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);
}
}
UIImagePickerController是一个功能强大的视图控制器类,它继承了UINavigationController,因此完全可以作为视图控制器使用,开发者只要创建该类的实例,即可通过该实例来完成如下3种操作:
使用UIImagePickerController的步骤如下:
①、如果要控制UIImagePickerController选取手机相册中的图片和视频,则将该对象的sourceType设置为”UIImagePickerControllerSourceTypePhotoLibrary”.
②、如果要控制UIImagePickerController拍照或录制视频,则将该对象的sourceType设置为” UIImagePickerControllerSourceTypeCamera”.
①、@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设置委托对象.
①、- (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];
}
如果开发者需要开发自定义的拍照和录制视频功能,则可借助于AVFoundation框架来实现,该框架提供了大量的类来完成拍照和录制视频.主要使用如下类:
(1)、AVCaptureDevice:该对象代表物理输入设备,包括摄像头和麦克风.开发者可通过该对象来配置底层物理设备的属性.需要指出的是,开发者不能直接创建该类的实例,只能通过该类的devices、defaultDeviceWithMediaType:(NSString )mediaType、devicesWithMediaType:(NSString )mediaType方法来获取对应的输入设备数组,接下来即可获取前置摄像头、后置摄像头或麦克风等.
一旦获取elAVMediaTypeVideo类型对应的设备(摄像头),程序就可设置该对象的额对焦模式、闪光灯模式、曝光模式、白平衡等各种拍照相关属性.在配置摄像头的相关性之前,必须先调用lockForConfiguration:方法执行锁定,配置完成后调用unlickForConfiguration方法解锁.
AVCapturaDevice代表物理输入设备将会把捕捉到得视频或声音数据提交给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
}
//得到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实现拍照和录制视频的大致步骤如下:
AVFoundation还可以用来生成视频缩略图.AVFoundation生成视频缩略图主要靠如下两个类.
#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