iOS開發-進階:音訊播放、錄音、視訊播放、拍照、視訊錄製
轉自: http://www.cnblogs.com/kenshincui/p/4186022.html#audioRecord
文章太長了, 如果我這裡寫的質量不好, 請參考原文;
概覽
隨著移動網際網路的發展,如今的手機早已不是打電話、發簡訊那麼簡單了,播放音樂、視訊、錄音、拍照等都是很常用的功能。在iOS中對於多媒體的支援是非常強大的,無論是音視訊播放、錄製,還是對麥克風、攝像頭的操作都提供了多套API。在今天的文章中將會對這些內容進行一一介紹:
音訊
在iOS中音訊播放從形式上可以分為音效播放和音樂播放。前者主要指的是一些短音訊播放,通常作為點綴音訊,對於這類音訊不需要進行進度、迴圈等控制。後者指的是一些較長的音訊,通常是主音訊,對於這些音訊的播放通常需要進行精確的控制。在iOS中播放兩類音訊分別使用AudioToolbox.framework和AVFoundation.framework來完成音效和音樂播放。
音效
AudioToolbox.framework是一套基於C語言的框架,使用它來播放音效其本質是將短音訊註冊到系統聲音服務(System Sound Service)。System Sound Service是一種簡單、底層的聲音播放服務,但是它本身也存在著一些限制:
- 音訊播放時間不能超過30s
- 資料必須是PCM或者IMA4格式
- 音訊檔案必須打包成.caf、.aif、.wav中的一種(注意這是官方文件的說法,實際測試發現一些.mp3也可以播放)
使用System Sound Service 播放音效的步驟如下:
- 呼叫AudioServicesCreateSystemSoundID( CFURLRef inFileURL, SystemSoundID* outSystemSoundID)
- 如果需要監聽播放完成操作,則使用AudioServicesAddSystemSoundCompletion( SystemSoundID inSystemSoundID,
CFRunLoopRef inRunLoop, CFStringRef inRunLoopMode, AudioServicesSystemSoundCompletionProc inCompletionRoutine, void* inClientData)方法註冊回撥函式。 - 呼叫AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID)
下面是一個簡單的示例程式:
// // KCMainViewController.m // Audio // // Created by Kenshin Cui on 14/03/30. // Copyright (c) 2014年 cmjstudio. All rights reserved. // 音效播放 #import "KCMainViewController.h" #import <AudioToolbox/AudioToolbox.h> @interface KCMainViewController () @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; [self playSoundEffect:@"videoRing.caf"]; } /** * 播放完成回撥函式 * * @param soundID 系統聲音ID * @param clientData 回撥時傳遞的資料 */ void soundCompleteCallback(SystemSoundID soundID,void * clientData){ NSLog(@"播放完成..."); } /** * 播放音效檔案 * * @param name 音訊檔名稱 */ -(void)playSoundEffect:(NSString *)name{ NSString *audioFile=[[NSBundle mainBundle] pathForResource:name ofType:nil]; NSURL *fileUrl=[NSURL fileURLWithPath:audioFile]; //1.獲得系統聲音ID SystemSoundID soundID=0; /** * inFileUrl:音訊檔案url * outSystemSoundID:聲音id(此函式會將音效檔案加入到系統音訊服務中並返回一個長整形ID) */ AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID); //如果需要在播放完之後執行某些操作,可以呼叫如下方法註冊一個播放完成回撥函式 AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL); //2.播放音訊 AudioServicesPlaySystemSound(soundID);//播放音效 // AudioServicesPlayAlertSound(soundID);//播放音效並震動 } @end
音樂
如果播放較大的音訊或者要對音訊有精確的控制則System Sound Service可能就很難滿足實際需求了,通常這種情況會選擇使用AVFoundation.framework中的AVAudioPlayer來實現。AVAudioPlayer可以看成一個播放器,它支援多種音訊格式,而且能夠進行進度、音量、播放速度等控制。首先簡單看一下AVAudioPlayer常用的屬性和方法:
屬性 | 說明 |
@property(readonly, getter=isPlaying) BOOL playing | 是否正在播放,只讀 |
@property(readonly) NSUInteger numberOfChannels | 音訊聲道數,只讀 |
@property(readonly) NSTimeInterval duration | 音訊時長 |
@property(readonly) NSURL *url | 音訊檔案路徑,只讀 |
@property(readonly) NSData *data | 音訊資料,只讀 |
@property float pan | 立體聲平衡,如果為-1.0則完全左聲道,如果0.0則左右聲道平衡,如果為1.0則完全為右聲道 |
@property float volume | 音量大小,範圍0-1.0 |
@property BOOL enableRate | 是否允許改變播放速率 |
@property float rate | 播放速率,範圍0.5-2.0,如果為1.0則正常播放,如果要修改播放速率則必須設定enableRate為YES |
@property NSTimeInterval currentTime | 當前播放時長 |
@property(readonly) NSTimeInterval deviceCurrentTime | 輸出裝置播放音訊的時間,注意如果播放中被暫停此時間也會繼續累加 |
@property NSInteger numberOfLoops | 迴圈播放次數,如果為0則不迴圈,如果小於0則無限迴圈,大於0則表示迴圈次數 |
@property(readonly) NSDictionary *settings | 音訊播放設定資訊,只讀 |
@property(getter=isMeteringEnabled) BOOL meteringEnabled | 是否啟用音訊測量,預設為NO,一旦啟用音訊測量可以通過updateMeters方法更新測量值 |
物件方法 | 說明 |
- (instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError | 使用檔案URL初始化播放器,注意這個URL不能是HTTP URL,AVAudioPlayer不支援載入網路媒體流,只能播放本地檔案 |
- (instancetype)initWithData:(NSData *)data error:(NSError **)outError | 使用NSData初始化播放器,注意使用此方法時必須檔案格式和檔案字尾一致,否則出錯,所以相比此方法更推薦使用上述方法或- (instancetype)initWithData:(NSData *)data fileTypeHint:(NSString *)utiString error:(NSError **)outError方法進行初始化 |
- (BOOL)prepareToPlay; | 載入音訊檔案到緩衝區,注意即使在播放之前音訊檔案沒有載入到緩衝區程式也會隱式呼叫此方法。 |
- (BOOL)play; | 播放音訊檔案 |
- (BOOL)playAtTime:(NSTimeInterval)time | 在指定的時間開始播放音訊 |
- (void)pause; | 暫停播放 |
- (void)stop; | 停止播放 |
- (void)updateMeters | 更新音訊測量值,注意如果要更新音訊測量值必須設定meteringEnabled為YES,通過音訊測量值可以即時獲得音訊分貝等資訊 |
- (float)peakPowerForChannel:(NSUInteger)channelNumber; | 獲得指定聲道的分貝峰值,注意如果要獲得分貝峰值必須在此之前呼叫updateMeters方法 |
- (float)averagePowerForChannel:(NSUInteger)channelNumber | 獲得指定聲道的分貝平均值,注意如果要獲得分貝平均值必須在此之前呼叫updateMeters方法 |
@property(nonatomic, copy) NSArray *channelAssignments | 獲得或設定播放聲道 |
代理方法 | 說明 |
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag | 音訊播放完成 |
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error | 音訊解碼發生錯誤 |
AVAudioPlayer的使用比較簡單:
- 初始化AVAudioPlayer物件,此時通常指定本地檔案路徑。
- 設定播放器屬性,例如重複次數、音量大小等。
- 呼叫play方法播放。
下面就使用AVAudioPlayer實現一個簡單播放器,在這個播放器中實現了播放、暫停、顯示播放進度功能,當然例如調節音量、設定迴圈模式、甚至是聲波影象(通過分析音訊分貝值)等功能都可以實現,這裡就不再一一演示。介面效果如下:
當然由於AVAudioPlayer一次只能播放一個音訊檔案,所有上一曲、下一曲其實可以通過建立多個播放器物件來完成,這裡暫不實現。播放進度的實現主要依靠一個定時器實時計算當前播放時長和音訊總時長的比例,另外為了演示委託方法,下面的程式碼中也實現了播放完成委託方法,通常如果有下一曲功能的話播放完可以觸發下一曲音樂播放。下面是主要程式碼:
// // ViewController.m // KCAVAudioPlayer // // Created by Kenshin Cui on 14/03/30. // Copyright (c) 2014年 cmjstudio. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> #define kMusicFile @"劉若英 - 原來你也在這裡.mp3" #define kMusicSinger @"劉若英" #define kMusicTitle @"原來你也在這裡" @interface ViewController ()<AVAudioPlayerDelegate> @property (nonatomic,strong) AVAudioPlayer *audioPlayer;//播放器 @property (weak, nonatomic) IBOutlet UILabel *controlPanel; //控制面板 @property (weak, nonatomic) IBOutlet UIProgressView *playProgress;//播放進度 @property (weak, nonatomic) IBOutlet UILabel *musicSinger; //演唱者 @property (weak, nonatomic) IBOutlet UIButton *playOrPause; //播放/暫停按鈕(如果tag為0認為是暫停狀態,1是播放狀態) @property (weak ,nonatomic) NSTimer *timer;//進度更新定時器 @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self setupUI]; } /** * 初始化UI */ -(void)setupUI{ self.title=kMusicTitle; self.musicSinger.text=kMusicSinger; } -(NSTimer *)timer{ if (!_timer) { _timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateProgress) userInfo:nil repeats:true]; } return _timer; } /** * 建立播放器 * * @return 音訊播放器 */ -(AVAudioPlayer *)audioPlayer{ if (!_audioPlayer) { NSString *urlStr=[[NSBundle mainBundle]pathForResource:kMusicFile ofType:nil]; NSURL *url=[NSURL fileURLWithPath:urlStr]; NSError *error=nil; //初始化播放器,注意這裡的Url引數只能時檔案路徑,不支援HTTP Url _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; //設定播放器屬性 _audioPlayer.numberOfLoops=0;//設定為0不迴圈 _audioPlayer.delegate=self; [_audioPlayer prepareToPlay];//載入音訊檔案到快取 if(error){ NSLog(@"初始化播放器過程發生錯誤,錯誤資訊:%@",error.localizedDescription); return nil; } } return _audioPlayer; } /** * 播放音訊 */ -(void)play{ if (![self.audioPlayer isPlaying]) { [self.audioPlayer play]; self.timer.fireDate=[NSDate distantPast];//恢復定時器 } } /** * 暫停播放 */ -(void)pause{ if ([self.audioPlayer isPlaying]) { [self.audioPlayer pause]; self.timer.fireDate=[NSDate distantFuture];//暫停定時器,注意不能呼叫invalidate方法,此方法會取消,之後無法恢復 } } /** * 點選播放/暫停按鈕 * * @param sender 播放/暫停按鈕 */ - (IBAction)playClick:(UIButton *)sender { if(sender.tag){ sender.tag=0; [sender setImage:[UIImage imageNamed:@"playing_btn_play_n"] forState:UIControlStateNormal]; [sender setImage:[UIImage imageNamed:@"playing_btn_play_h"] forState:UIControlStateHighlighted]; [self pause]; }else{ sender.tag=1; [sender setImage:[UIImage imageNamed:@"playing_btn_pause_n"] forState:UIControlStateNormal]; [sender setImage:[UIImage imageNamed:@"playing_btn_pause_h"] forState:UIControlStateHighlighted]; [self play]; } } /** * 更新播放進度 */ -(void)updateProgress{ float progress= self.audioPlayer.currentTime /self.audioPlayer.duration; [self.playProgress setProgress:progress animated:true]; } #pragma mark - 播放器代理方法 -(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ NSLog(@"音樂播放完成..."); } @end執行效果:
音訊會話
事實上上面的播放器還存在一些問題,例如通常我們看到的播放器即使退出到後臺也是可以播放的,而這個播放器如果退出到後臺它會自動暫停。如果要支援後臺播放需要做下面幾件事情:
1.設定後臺執行模式:在plist檔案中新增Required background modes,並且設定item 0=App plays audio or streams audio/video using AirPlay(其實可以直接通過Xcode在Project Targets-Capabilities-Background Modes中設定)
2.設定AVAudioSession的型別為AVAudioSessionCategoryPlayback並且呼叫setActive::方法啟動會話。
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
3.為了能夠讓應用退到後臺之後支援耳機控制,建議新增遠端控制事件(這一步不是後臺播放必須的)
前兩步是後臺播放所必須設定的,第三步主要用於接收遠端事件,這部分內容之前的文章中有詳細介紹,如果這一步不設定雖讓也能夠在後臺播放,但是無法獲得音訊控制權(如果在使用當前應用之前使用其他播放器播放音樂的話,此時如果按耳機播放鍵或者控制中心的播放按鈕則會播放前一個應用的音訊),並且不能使用耳機進行音訊控制。第一步操作相信大家都很容易理解,如果應用程式要允許執行到後臺必須設定,正常情況下應用如果進入後臺會被掛起,通過該設定可以上應用程式繼續在後臺執行。但是第二步使用的AVAudioSession有必要進行一下詳細的說明。
在iOS中每個應用都有一個音訊會話,這個會話就通過AVAudioSession來表示。AVAudioSession同樣存在於AVFoundation框架中,它是單例模式設計,通過sharedInstance進行訪問。在使用Apple裝置時大家會發現有些應用只要開啟其他音訊播放就會終止,而有些應用卻可以和其他應用同時播放,在多種音訊環境中如何去控制播放的方式就是通過音訊會話來完成的。下面是音訊會話的幾種會話模式:
會話型別 | 說明 | 是否要求輸入 | 是否要求輸出 | 是否遵從靜音鍵 |
AVAudioSessionCategoryAmbient | 混音播放,可以與其他音訊應用同時播放 | 否 | 是 | 是 |
AVAudioSessionCategorySoloAmbient | 獨佔播放 | 否 | 是 | 是 |
AVAudioSessionCategoryPlayback | 後臺播放,也是獨佔的 | 否 | 是 | 否 |
AVAudioSessionCategoryRecord | 錄音模式,用於錄音時使用 | 是 | 否 | 否 |
AVAudioSessionCategoryPlayAndRecord | 播放和錄音,此時可以錄音也可以播放 | 是 | 是 | 否 |
AVAudioSessionCategoryAudioProcessing | 硬體解碼音訊,此時不能播放和錄製 | 否 | 否 | 否 |
AVAudioSessionCategoryMultiRoute | 多種輸入輸出,例如可以耳機、USB裝置同時播放 | 是 | 是 | 否 |
注意:是否遵循靜音鍵表示在播放過程中如果使用者通過硬體設定為靜音是否能關閉聲音。
根據前面對音訊會話的理解,相信大家開發出能夠在後臺播放的音訊播放器並不難,但是注意一下,在前面的程式碼中也提到設定完音訊會話型別之後需要呼叫setActive::方法將會話啟用才能起作用。類似的,如果一個應用已經在播放音訊,開啟我們的應用之後設定了在後臺播放的會話型別,此時其他應用的音訊會停止而播放我們的音訊,如果希望我們的程式音訊播放完之後(關閉或退出到後臺之後)能夠繼續播放其他應用的音訊的話則可以呼叫setActive::方法關閉會話。程式碼如下:
// // ViewController.m // KCAVAudioPlayer // // Created by Kenshin Cui on 14/03/30. // Copyright (c) 2014年 cmjstudio. All rights reserved. // AVAudioSession 音訊會話 #import "ViewController.h" #import <AVFoundation/AVFoundation.h> #define kMusicFile @"劉若英 - 原來你也在這裡.mp3" #define kMusicSinger @"劉若英" #define kMusicTitle @"原來你也在這裡" @interface ViewController ()<AVAudioPlayerDelegate> @property (nonatomic,strong) AVAudioPlayer *audioPlayer;//播放器 @property (weak, nonatomic) IBOutlet UILabel *controlPanel; //控制面板 @property (weak, nonatomic) IBOutlet UIProgressView *playProgress;//播放進度 @property (weak, nonatomic) IBOutlet UILabel *musicSinger; //演唱者 @property (weak, nonatomic) IBOutlet UIButton *playOrPause; //播放/暫停按鈕(如果tag為0認為是暫停狀態,1是播放狀態) @property (weak ,nonatomic) NSTimer *timer;//進度更新定時器 @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self setupUI]; } /** * 顯示當面檢視控制器時註冊遠端事件 * * @param animated 是否以動畫的形式顯示 */ -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //開啟遠端控制 [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; //作為第一響應者 //[self becomeFirstResponder]; } /** * 當前控制器檢視不顯示時取消遠端控制 * * @param animated 是否以動畫的形式消失 */ -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; //[self resignFirstResponder]; } /** * 初始化UI */ -(void)setupUI{ self.title=kMusicTitle; self.musicSinger.text=kMusicSinger; } -(NSTimer *)timer{ if (!_timer) { _timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateProgress) userInfo:nil repeats:true]; } return _timer; } /** * 建立播放器 * * @return 音訊播放器 */ -(AVAudioPlayer *)audioPlayer{ if (!_audioPlayer) { NSString *urlStr=[[NSBundle mainBundle]pathForResource:kMusicFile ofType:nil]; NSURL *url=[NSURL fileURLWithPath:urlStr]; NSError *error=nil; //初始化播放器,注意這裡的Url引數只能時檔案路徑,不支援HTTP Url _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; //設定播放器屬性 _audioPlayer.numberOfLoops=0;//設定為0不迴圈 _audioPlayer.delegate=self; [_audioPlayer prepareToPlay];//載入音訊檔案到快取 if(error){ NSLog(@"初始化播放器過程發生錯誤,錯誤資訊:%@",error.localizedDescription); return nil; } //設定後臺播放模式 AVAudioSession *audioSession=[AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; // [audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil]; [audioSession setActive:YES error:nil]; //新增通知,拔出耳機後暫停播放 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil]; } return _audioPlayer; } /** * 播放音訊 */ -(void)play{ if (![self.audioPlayer isPlaying]) { [self.audioPlayer play]; self.timer.fireDate=[NSDate distantPast];//恢復定時器 } } /** * 暫停播放 */ -(void)pause{ if ([self.audioPlayer isPlaying]) { [self.audioPlayer pause]; self.timer.fireDate=[NSDate distantFuture];//暫停定時器,注意不能呼叫invalidate方法,此方法會取消,之後無法恢復 } } /** * 點選播放/暫停按鈕 * * @param sender 播放/暫停按鈕 */ - (IBAction)playClick:(UIButton *)sender { if(sender.tag){ sender.tag=0; [sender setImage:[UIImage imageNamed:@"playing_btn_play_n"] forState:UIControlStateNormal]; [sender setImage:[UIImage imageNamed:@"playing_btn_play_h"] forState:UIControlStateHighlighted]; [self pause]; }else{ sender.tag=1; [sender setImage:[UIImage imageNamed:@"playing_btn_pause_n"] forState:UIControlStateNormal]; [sender setImage:[UIImage imageNamed:@"playing_btn_pause_h"] forState:UIControlStateHighlighted]; [self play]; } } /** * 更新播放進度 */ -(void)updateProgress{ float progress= self.audioPlayer.currentTime /self.audioPlayer.duration; [self.playProgress setProgress:progress animated:true]; } /** * 一旦輸出改變則執行此方法 * * @param notification 輸出改變通知物件 */ -(void)routeChange:(NSNotification *)notification{ NSDictionary *dic=notification.userInfo; int changeReason= [dic[AVAudioSessionRouteChangeReasonKey] intValue]; //等於AVAudioSessionRouteChangeReasonOldDeviceUnavailable表示舊輸出不可用 if (changeReason==AVAudioSessionRouteChangeReasonOldDeviceUnavailable) { AVAudioSessionRouteDescription *routeDescription=dic[AVAudioSessionRouteChangePreviousRouteKey]; AVAudioSessionPortDescription *portDescription= [routeDescription.outputs firstObject]; //原裝置為耳機則暫停 if ([portDescription.portType isEqualToString:@"Headphones"]) { [self pause]; } } // [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { // NSLog(@"%@:%@",key,obj); // }]; } -(void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil]; } #pragma mark - 播放器代理方法 -(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ NSLog(@"音樂播放完成..."); //根據實際情況播放完成可以將會話關閉,其他音訊應用繼續播放 [[AVAudioSession sharedInstance]setActive:NO error:nil]; } @end
在上面的程式碼中還實現了拔出耳機暫停音樂播放的功能,這也是一個比較常見的功能。在iOS7及以後的版本中可以通過通知獲得輸出改變的通知,然後拿到通知物件後根據userInfo獲得是何種改變型別,進而根據情況對音樂進行暫停操作。
擴充套件--播放音樂庫中的音樂
眾所周知音樂是iOS的重要組成播放,無論是iPod、iTouch、iPhone還是iPad都可以在iTunes購買音樂或新增本地音樂到音樂庫中同步到你的iOS裝置。在MediaPlayer.frameowork中有一個MPMusicPlayerController用於播放音樂庫中的音樂。
下面先來看一下MPMusicPlayerController的常用屬性和方法:
屬性 | 說明 |
@property (nonatomic, readonly) MPMusicPlaybackState playbackState |
播放器狀態,列舉型別: MPMusicPlaybackStateStopped:停止播放 MPMusicPlaybackStatePlaying:正在播放 MPMusicPlaybackStatePaused:暫停播放 MPMusicPlaybackStateInterrupted:播放中斷 MPMusicPlaybackStateSeekingForward:向前查詢 MPMusicPlaybackStateSeekingBackward:向後查詢 |
@property (nonatomic) MPMusicRepeatMode repeatMode |
重複模式,列舉型別: MPMusicRepeatModeDefault:預設模式,使用使用者的首選項(系統音樂程式設定) MPMusicRepeatModeNone:不重複 MPMusicRepeatModeOne:單曲迴圈 MPMusicRepeatModeAll:在當前列表內迴圈 |
@property (nonatomic) MPMusicShuffleMode shuffleMode |
隨機播放模式,列舉型別: MPMusicShuffleModeDefault:預設模式,使用使用者首選項(系統音樂程式設定) MPMusicShuffleModeOff:不隨機播放 MPMusicShuffleModeSongs:按歌曲隨機播放 MPMusicShuffleModeAlbums:按專輯隨機播放 |
@property (nonatomic, copy) MPMediaItem *nowPlayingItem | 正在播放的音樂項 |
@property (nonatomic, readonly) NSUInteger indexOfNowPlayingItem | 當前正在播放的音樂在播放佇列中的索引 |
@property(nonatomic, readonly) BOOL isPreparedToPlay | 是否準好播放準備 |
@property(nonatomic) NSTimeInterval currentPlaybackTime | 當前已播放時間,單位:秒 |
@property(nonatomic) float currentPlaybackRate | 當前播放速度,是一個播放速度倍率,0表示暫停播放,1代表正常速度 |
類方法 | 說明 |
+ (MPMusicPlayerController *)applicationMusicPlayer; | 獲取應用播放器,注意此類播放器無法在後臺播放 |
+ (MPMusicPlayerController *)systemMusicPlayer | 獲取系統播放器,支援後臺播放 |
物件方法 | 說明 |
- (void)setQueueWithQuery:(MPMediaQuery *)query | 使用媒體佇列設定播放源媒體佇列 |
- (void)setQueueWithItemCollection:(MPMediaItemCollection *)itemCollection | 使用媒體項集合設定播放源媒體佇列 |
- (void)skipToNextItem | 下一曲 |
- (void)skipToBeginning | 從起始位置播放 |
- (void)skipToPreviousItem | 上一曲 |
- (void)beginGeneratingPlaybackNotifications | 開啟播放通知,注意不同於其他播放器,MPMusicPlayerController要想獲得通知必須首先開啟,預設情況無法獲得通知 |
- (void)endGeneratingPlaybackNotifications | 關閉播放通知 |
- (void)prepareToPlay | 做好播放準備(載入音訊到緩衝區),在使用play方法播放時如果沒有做好準備回自動呼叫該方法 |
- (void)play | 開始播放 |
- (void)pause | 暫停播放 |
- (void)stop | 停止播放 |
- (void)beginSeekingForward |
相關推薦iOS開發-進階:音訊播放、錄音、視訊播放、拍照、視訊錄製轉自: http://www.cnblogs.com/kenshincui/p/4186022.html#audioRecord 文章太長了, 如果我這裡寫的質量不好, 請參考原文; 概覽 隨著移動網際網路的發展,如今的手機早已不是打電話、發簡訊那麼 《iOS開發進階》書籍目錄archive 憑證 修改 工具 core serial 第二部分 破解 uilabel 第一部分:iOS開發工具 第二部分:iOS開發實踐 第10章 理解內存管理 10.1 引用計數 10.1.1 什麽是引用計數,原理是什麽 10.1.2 我們為什麽需要引用計數 10 《iOS開發進階》閱讀總結1.引用計數的作用 物件A向物件B傳遞引數物件M ,物件M可能成為物件B的成員變數,也可能只是臨時使用,如果不用引用計數控制,則無法在正確的時間釋放物件M。 案例一:物件A將物件M傳遞給物件B後 Reveal的使用--整理自唐巧的《iOS開發進階》1.下載一個正版的reveal來安裝。 2.開啟終端,輸入vim ~/.lldbinit建立一個名為.lldbinit的檔案,然後將如下內容輸入檔案中 command alias reveal_load_sim expr (void*)dlopen("/Applicat iOS開發進階-使用多個StoryBoard劃分專案前言:在實際來發中,作者一般都是使用純程式碼的方式進行開發,國內很多開發者都喜歡使用純程式碼進行開發,一方面是程式碼可維護性比較高,另一方面也是因為StoryBoard團隊協作的詬病。不過如果把一個專案拆分為多個StroyBoard,不同的人負責不同的模組 iOS開發-進階:被誤解的MVC和被神化的MVVM(作者:唐巧)作者 唐巧 釋出於 2015年11月1日 | 被誤解的 MVC MVC 的歷史 MVC,全稱是 Model View Controller,是模型 (model)-檢視 (view)-控制器 (controller) 的縮寫。它表示的是一種常見的客戶端軟 iOS開發-進階:最新版SDWebImage的使用文章轉自: http://www.cocoachina.com/ios/20141212/10622.html 我之前寫過一篇部落格,介紹快取處理的三種方式,其中最難,最麻煩,最佔記憶體資源的還是圖片快取,最近做的專案有大量的圖片處理,還是採用了SDWebIma iOS開發-進階:MOV格式視訊轉MP4格式AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:sourceUrl options:nil]; NSArray *compatiblePresets = [AVAssetExportSession exportP iOS開發-進階:開啟Remote notifications需要在Xcode 中修改應用的 Capabilities 開啟Remote notifications,請參考下圖: 修改通知處理函式 當註冊了Backgroud Modes -> Remote notifications 後,notification 處理 iOS開發-進階:瀑布流基本實現文章轉自: http://www.jianshu.com/p/78830bdb04a9 一、瀑布流設計方案 不可取.png 過於複雜.png 最優方案.png 二、瀑布流設計思路分析 1、自定義流水佈局中,指定滾動方向、預設列數、行間距、列間距、以及 iOS開發進階-UITapGestureRecognizer使用技巧手勢互動是iOS開發中用的比較多的一個類,用途無處不在,這裡面也衍生了很多的需求和用法,UIGestureRecognizer很強大,它的子類包括很多,不過想要更完美的使用它,就需要了解它的底層原理和和一些特殊情況下的處理辦法,本文主要介紹UITapGestur iOS開發-進階:JS與OC的互動在移動應用的專案中, web 相比原生應用有如下優點: 版本可以隨時更新, 效率高;可動態配置要展示的資料, 及資料來源.原生應用中, 如果一個頁面的展示, 需要多次呼叫不同的網路請求, 並且, 上一次請求的結果是下一次請求的引數, 這樣按順序呼叫網路並且等待網路返回的資 iOS開發-進階:JPush設定標籤與別名的API標籤與別名 API (iOS) 功能說明 溫馨提示,設定標籤別名請注意處理call back結果。 只有call back 返回值為 0 才設定成功,才可以向目標推送。否則伺服器 API 會返回1011錯誤。所有回撥函式都在主執行緒執行。 提供幾個相關 AP ios開發進階之多執行緒01 執行緒 GCD一 多執行緒基礎 什麼是程序? 程序是指在系統中正在執行的一個應用程式。 每個程序之間是獨立的,每個程序均執行在其專用且受保護的記憶體空間內。 什麼是執行緒? 1個程序要想執行任務,必須得有執行緒(每1個程序至少要有1條執行緒)。 1個執行緒中任務的執行 【原】iOS開發進階(唐巧)讀書筆記(二)第三部分:iOS開發底層原理 1、Objective-C物件模型 1.1 isa指標 NSObject.h部分程式碼: NS_ROOT_CLASS @interface NSObject <NSObject> { Class isa; } objc.h部分程式碼: typedef stru 5、第十 - WEB開發進階 - Django靜態文件應用cfile 過濾 back inpu get csr con base rom Web Django 網站通常需要提供其他文件,如圖像、JavaScript或CSS。在Django中,我們將這些文件稱為“靜態文件”。 Django提供了django.contrib.st 6、第十 - WEB開發進階 - Django使用者登入後的資訊管理及生命週期簡述案例操作: 一、Django編寫模擬使用者登入並跳轉到後臺 示範案例,要求: 1、模擬使用者登入,賬號密碼一致、輸入錯誤的話進行提示 2、使用者登入成功跳轉到後臺,並顯示其他home.html資訊 3、彈出對話方塊,設定新增、刪除按鈕 程式碼結構: 程式碼 8、第十 - WEB開發進階 - Django URL路由分發Django基於正則表示式的URL Django的路由模式,主要是定義前端的URL訪問模式。簡單歸納有以下幾種方式: 1、FBV結構:path(r'index/',views.index); CBV結構:path(r'home',views.Home.as_view()), 2、字串拼 iOS開發之建立音訊播放的單例類因為涉及到專案的開發,所以這裡只把PlayerCenter單例類中的程式碼進行展示,僅做參考,其中包含上一曲,暫停/播放,下一曲等功能,專案中也涉及到了後臺播放和操作的功能,具體的使用大家可以繼續研究,或者給我留言,等有空寫一個Demo給大家分享PlayCenter.h#im Android開發-進階:Json字串轉換為java物件的各種實現方法[json_lib框架、Gson、org.json]JSON (JavaScript Object Notation) 是一種輕量級的資料交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。它基於JavaScript Programming Language, Standard ECMA-262 3rd Edition |