• AVAudioSession,


    转:http://blog.csdn.net/ysy441088327/article/details/8164120(余书懿

    音频方面的知识,相对其他编程还是较为复杂的,特别是要搞清楚框架里具体使用的参数和方法,不然写起代码来非常迷茫.

    1:播放简短性质的音频,例如按键声音,等可以这样实现.

    一:引入框架:

    [csharp] view plaincopy
     
    1. #import <AudioToolbox/AudioToolbox.h>  


    二:先声明一个声音源ID

    [csharp] view plaincopy
     
    1. SystemSoundID _bookSoundID;  


    三:提供需要播放的音频地址进行声音源的注册.

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


    四:在需要的时候播放:

    [csharp] view plaincopy
     
    1. AudioServicesPlaySystemSound(_bookSoundID);  


    五:不用的声音源记得释放掉

    [csharp] view plaincopy
     
    1. AudioServicesDisposeSystemSoundID(_bookSoundID);  


    2: 关于 AVAudioSession 的使用

    首先知道 AVAudioSession  是一个单例模式,也就是说,不用开发者自行实例化. 这个类在各种音频环境中起着非常重要的作用

    一:首先是设置 AVAudioSession 的 类别

                                                                                          获取输入硬 件          获取输出硬件       与IPOD混合      遵从振铃/静音按键
    AVAudioSessionCategoryAmbient                            否                               是                          是                         是

    AVAudioSessionCategorySoloAmbient                    否                              是                           否                         是

    AVAudioSessionCategoryPlayback                          否                               是                           否                        否

    AVAudioSessionCategoryRecord                              是                              否                           否                         否

    AVAudioSessionCategoryPlayAndRecord              是                              是                           否                         否

    根据实际的使用情况来设定具体的类别,设置代码如下:

    [csharp] view plaincopy
     
    1. AVAudioSession * audioSession = [AVAudioSession sharedInstance]; //得到AVAudioSession单例对象  
    2. [audioSession setDelegate:self];//设定代理  
    3. [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];//设置类别,表示该应用同时支持播放和录音  
    4. [audioSession setActive:YES error: &error];//启动音频会话管理,此时会阻断后台音乐的播放.  

    二:在录制完声音或者播放完声音后,可以将音频会话关闭,来延续后台音乐的播放,代码如下:

    [csharp] view plaincopy
     
    1. [[AVAudioSession sharedInstance] setActive:NO error: nil];  


    三:通过音频会话可以强制的设置应用程序使用指定的输出方式,例如:内声道,扬声器,代码如下:

    [csharp] view plaincopy
     
    1. UInt32 audioRouteOverride = hasHeadset ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;  
    2. AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);  


    kAudioSessionOverrideAudioRoute_None  内声道,耳机

    kAudioSessionOverrideAudioRoute_Speaker 扬声器

    四:那么怎么判断用户是否已经插入耳机?代码如下: (参考:http://iandworld.sinaapp.com/?p=184001)

    [csharp] view plaincopy
     
    1. - (BOOL)hasHeadset {  
    2. //模拟器不支持  
    3. #if TARGET_IPHONE_SIMULATOR  
    4.     #warning *** Simulator mode: audio session code works only on a device  
    5.     return NO;  
    6. #else  
    7.     CFStringRef route;  
    8.     UInt32 propertySize = sizeof(CFStringRef);  
    9.     AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &route);  
    10.       
    11.     if((route == NULL) || (CFStringGetLength(route) == 0)){  
    12.         // Silent Mode  
    13.         NSLog(@"AudioRoute: SILENT, do nothing!");  
    14.     } else {  
    15.         NSString* routeStr = (__bridge NSString*)route;  
    16.         NSLog(@"AudioRoute: %@", routeStr);  
    17.           
    18.         /* Known values of route: 
    19.          * "Headset" 
    20.          * "Headphone" 
    21.          * "Speaker" 
    22.          * "SpeakerAndMicrophone" 
    23.          * "HeadphonesAndMicrophone" 
    24.          * "HeadsetInOut" 
    25.          * "ReceiverAndMicrophone" 
    26.          * "Lineout" 
    27.          */  
    28.           
    29.         NSRange headphoneRange = [routeStr rangeOfString : @"Headphone"];  
    30.         NSRange headsetRange = [routeStr rangeOfString : @"Headset"];  
    31.         if (headphoneRange.location != NSNotFound) {  
    32.             return YES;  
    33.         } else if(headsetRange.location != NSNotFound) {  
    34.             return YES;  
    35.         }  
    36.     }  
    37.     return NO;  
    38. #endif  
    39.       
    40. }  


    返回YES,表示已经插入耳机,返回NO表示没有插入耳机

    五:监听用户拔出插入耳机事件

    1:注册监听事件,和回调函数

    [csharp] view plaincopy
     
    1. AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange,  
    2.                                      audioRouteChangeListenerCallback,  
    3.                                      self);  

    2:实现回调函数进行相关处理:

    [csharp] view plaincopy
     
    1. void audioRouteChangeListenerCallback (  
    2.                                        void                      *inUserData,  
    3.                                        AudioSessionPropertyID    inPropertyID,  
    4.                                        UInt32                    inPropertyValueSize,  
    5.                                        const void                *inPropertyValue  
    6.                                        ) {  
    7.   
    8.     if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return;  
    9.     // Determines the reason for the route change, to ensure that it is not  
    10.     //      because of a category change.  
    11.     CFDictionaryRef routeChangeDictionary = inPropertyValue;  
    12.   
    13.     CFNumberRef routeChangeReasonRef =  
    14.     CFDictionaryGetValue (routeChangeDictionary,  
    15.                           CFSTR (kAudioSession_AudioRouteChangeKey_Reason));  
    16.   
    17.     SInt32 routeChangeReason;  
    18.   
    19.     CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);  
    20.     NSLog(@" ===================================== RouteChangeReason : %d", routeChangeReason);  
    21.     AudioHelper *_self = (AudioHelper *) inUserData;  
    22.     if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {  
    23.         [_self resetSettings];  
    24.         if (![_self hasHeadset]) {  
    25.             [[NSNotificationCenter defaultCenter] postNotificationName:@"ununpluggingHeadse"  
    26.                                                                 object:nil];  
    27.         }  
    28.     } else if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) {  
    29.         [_self resetSettings];  
    30.         if (![_self hasMicphone]) {  
    31.             [[NSNotificationCenter defaultCenter] postNotificationName:@"pluggInMicrophone"  
    32.                                                                 object:nil];  
    33.         }  
    34.     } else if (routeChangeReason == kAudioSessionRouteChangeReason_NoSuitableRouteForCategory) {  
    35.         [_self resetSettings];  
    36.         [[NSNotificationCenter defaultCenter] postNotificationName:@"lostMicroPhone"  
    37.                                                             object:nil];  
    38.     }  
    39.     //else if (routeChangeReason == kAudioSessionRouteChangeReason_CategoryChange  ) {  
    40.     //    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];  
    41.     //}  
    42.   
    43.     [_self printCurrentCategory];  
    44. }  

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

    1:在Info.plist中,添加"Required background modes"键,其值设置如下图所示:

    2:系统音频服务支持音频播放,并关闭其他正在播放的音频

    [csharp] view plaincopy
     
    1. AVAudioSession *session = [AVAudioSession sharedInstance];  
    2. [session setActive:YES error:nil];  
    3. [session setCategory:AVAudioSessionCategoryPlayback error:nil];  

    3:设置app支持接受远程控制事件代码:

    [csharp] view plaincopy
     
    1. [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];  

    设置app支持接受远程控制事件,其实就是在dock中可以显示应用程序图标,同时点击该图片时,打开app,如下图所示:

    4:执行 AVAudioPlayer  

    七 关于音量

    1:由应用主动获取系统音量

    [csharp] view plaincopy
     
    1. UInt32 dataSize = sizeof(float);  
    2. AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareOutputVolume,  
    3.                                            &dataSize,  
    4.                                            &keyVolume);  

    获取之前要确保

    [csharp] view plaincopy
     
    1. AVAudioSession *session = [AVAudioSession sharedInstance];  
    2. [session setActive:YES error:nil];  
    3. [session setCategory:AVAudioSessionCategoryPlayback error:nil];  

    2:由应用主动设置系统音量 (参考:http://blog.csdn.net/studyrecord/article/details/6452354)

    八:关于音频边下载边播放的实现.

    请参考:AudioStreamer

    https://github.com/mattgallagher/AudioStreamer

    如果你只是想简简单单在线播放以下不做任何处理. 那使用AVPlayer 等等 去实现在线播放,也是可以的,但是如果要实现更多更能,还是别折腾这玩意,浪费生命. 

  • 相关阅读:
    USB Descriptors
    回车(carriage return : \r) 换行(line feed : \n)
    SQLSERVER改变已有数据表中的列
    SQLSERVER数据库中的5173错误
    SQLSERVER 在局域网使用Windows身份验证连接局域网内的另一台SQL服务器(不是域环境)
    对于索引假脱机的一点理解
    SQLSERVER备份系统数据库以及何时备份系统数据库
    SQL PROMPT5.3.4.1的一些设置选项
    设置SQLSERVER的错误日志数量和查找SQLSERVER安装错误日志
    谈谈我是如何学习SQL Server的
  • 原文地址:https://www.cnblogs.com/guligei/p/3517786.html
Copyright © 2020-2023  润新知