iOS 關於音頻開發

來源:互聯網
上載者:User

音頻方面的知識,相對其他編程還是較為複雜的,特別是要搞清楚架構裡具體使用的參數和方法,不然寫起代碼來非常迷茫.

1:播放簡短性質的音頻,例如按鍵聲音,等可以這樣實現.

一:引入架構:

#import <AudioToolbox/AudioToolbox.h>

二:先聲明一個聲音源ID

SystemSoundID _bookSoundID;

三:提供需要播放的音頻地址進行聲音源的註冊.

    NSURL *bookSoundUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"bookSound" ofType:@"wav"]];    AudioServicesCreateSystemSoundID((__bridge CFURLRef)bookSoundUrl, &_bookSoundID);

四:在需要的時候播放:

AudioServicesPlaySystemSound(_bookSoundID);

五:不用的聲音源記得釋放掉

AudioServicesDisposeSystemSoundID(_bookSoundID);

2: 關於 AVAudioSession 的使用

首Crowdsourced Security Testing道 AVAudioSession  是一個單例模式,也就是說,不用開發人員自行執行個體化. 這個類在各種音頻環境中起著非常重要的作用

一:首先是設定 AVAudioSession 的 類別

                                                                                      擷取輸入硬 件          擷取輸出硬體       與IPOD混合      遵從響鈴/靜音按鍵
AVAudioSessionCategoryAmbient                            否                               是                          是                         是

AVAudioSessionCategorySoloAmbient                    否                              是                           否                         是

AVAudioSessionCategoryPlayback                          否                               是                           否                        否

AVAudioSessionCategoryRecord                              是                              否                           否                         否

AVAudioSessionCategoryPlayAndRecord              是                              是                           否                         否

根據實際的使用方式來設定具體的類別,設定代碼如下:

AVAudioSession * audioSession = [AVAudioSession sharedInstance]; //得到AVAudioSession單例對象[audioSession setDelegate:self];//設定代理[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];//設定類別,表示該應用同時支援播放和錄音[audioSession setActive:YES error: &error];//啟動音頻會話管理,此時會阻斷後台音樂的播放.

二:在錄製完聲音或者播放完聲音後,可以將音頻會話關閉,來延續後台音樂的播放,代碼如下:

[[AVAudioSession sharedInstance] setActive:NO error: nil];

三:通過音頻會話可以強制的設定應用程式使用指定的輸出方式,例如:內聲道,擴音器,代碼如下:

    UInt32 audioRouteOverride = hasHeadset ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

kAudioSessionOverrideAudioRoute_None  內聲道,耳機

kAudioSessionOverrideAudioRoute_Speaker 擴音器

四:那麼怎麼判斷使用者是否已經插入耳機?代碼如下: (參考:http://iandworld.sinaapp.com/?p=184001)

- (BOOL)hasHeadset {//模擬器不支援#if TARGET_IPHONE_SIMULATOR    #warning *** Simulator mode: audio session code works only on a device    return NO;#else    CFStringRef route;    UInt32 propertySize = sizeof(CFStringRef);    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &route);        if((route == NULL) || (CFStringGetLength(route) == 0)){        // Silent Mode        NSLog(@"AudioRoute: SILENT, do nothing!");    } else {        NSString* routeStr = (__bridge NSString*)route;        NSLog(@"AudioRoute: %@", routeStr);                /* Known values of route:         * "Headset"         * "Headphone"         * "Speaker"         * "SpeakerAndMicrophone"         * "HeadphonesAndMicrophone"         * "HeadsetInOut"         * "ReceiverAndMicrophone"         * "Lineout"         */                NSRange headphoneRange = [routeStr rangeOfString : @"Headphone"];        NSRange headsetRange = [routeStr rangeOfString : @"Headset"];        if (headphoneRange.location != NSNotFound) {            return YES;        } else if(headsetRange.location != NSNotFound) {            return YES;        }    }    return NO;#endif    }

返回YES,表示已經插入耳機,返回NO表示沒有插入耳機

五:監聽使用者拔出插入耳機事件

1:註冊監聽事件,和回呼函數

AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange,                                     audioRouteChangeListenerCallback,                                     self);

2:實現回呼函數進行相關處理:

void audioRouteChangeListenerCallback (                                       void                      *inUserData,                                       AudioSessionPropertyID    inPropertyID,                                       UInt32                    inPropertyValueSize,                                       const void                *inPropertyValue                                       ) {    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return;    // Determines the reason for the route change, to ensure that it is not    //because of a category change.    CFDictionaryRefrouteChangeDictionary = inPropertyValue;    CFNumberRef routeChangeReasonRef =    CFDictionaryGetValue (routeChangeDictionary,                          CFSTR (kAudioSession_AudioRouteChangeKey_Reason));    SInt32 routeChangeReason;    CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);    NSLog(@" ===================================== RouteChangeReason : %d", routeChangeReason);    AudioHelper *_self = (AudioHelper *) inUserData;    if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {        [_self resetSettings];        if (![_self hasHeadset]) {            [[NSNotificationCenter defaultCenter] postNotificationName:@"ununpluggingHeadse"                                                                object:nil];        }    } else if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) {        [_self resetSettings];        if (![_self hasMicphone]) {            [[NSNotificationCenter defaultCenter] postNotificationName:@"pluggInMicrophone"                                                                object:nil];        }    } else if (routeChangeReason == kAudioSessionRouteChangeReason_NoSuitableRouteForCategory) {        [_self resetSettings];        [[NSNotificationCenter defaultCenter] postNotificationName:@"lostMicroPhone"                                                            object:nil];    }    //else if (routeChangeReason == kAudioSessionRouteChangeReason_CategoryChange  ) {    //    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];    //}    [_self printCurrentCategory];}

六:如何保持後台音樂的一直播放呢? (參考:http://blog.csdn.net/yhawaii/article/details/7788340)


1:在Info.plist中,添加"Required background modes"鍵,其值設定如所示:

2:系統音頻服務支援音頻播放,並關閉其他現正播放的音頻

AVAudioSession *session = [AVAudioSession sharedInstance];[session setActive:YES error:nil];[session setCategory:AVAudioSessionCategoryPlayback error:nil];

3:設定app支援接受遠端控制事件代碼:

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

設定app支援接受遠端控制事件,其實就是在dock中可以顯示應用程式圖示,同時點擊該圖片時,開啟app,如所示:

4:執行 AVAudioPlayer  

七 關於音量

1:由應用主動擷取系統音量

UInt32 dataSize = sizeof(float);AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareOutputVolume,                                           &dataSize,                                           &keyVolume);

擷取之前要確保

AVAudioSession *session = [AVAudioSession sharedInstance];[session setActive:YES error:nil];[session setCategory:AVAudioSessionCategoryPlayback error:nil];

2:由應用主動設定系統音量 (參考:http://blog.csdn.net/studyrecord/article/details/6452354)

八:關於音頻邊下載邊播放的實現.

請參考:AudioStreamer

https://github.com/mattgallagher/AudioStreamer

如果你只是想簡簡單單線上播放以下不做任何處理. 那使用AVPlayer 等等 去實現線上播放,也是可以的,但是如果要實現更多更能,還是別折騰這玩意,浪費生命. 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.