iOS 关于音频开发

简介: 音频方面的知识,相对其他编程还是较为复杂的,特别是要搞清楚框架里具体使用的参数和方法,不然写起代码来非常迷茫. 1:播放简短性质的音频,例如按键声音,等可以这样实现.
+关注继续查看

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

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 的使用

首先知道 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.
    CFDictionaryRef	routeChangeDictionary = 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 等等 去实现在线播放,也是可以的,但是如果要实现更多更能,还是别折腾这玩意,浪费生命. 


目录
相关文章
|
14天前
|
安全 前端开发 Android开发
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
鸿蒙开发学习是一项探索性的工作,旨在开发一个全场景分布式操作系统,覆盖所有设备,让消费者能够更方便、更直观地使用各种设备。
59 0
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
|
18天前
|
JavaScript 前端开发 PHP
用swift开发ios移动端app应用初体验
直接跟着 apple 官方的 SwiftUI 教程跑的,写惯了 javascript 奔放的代码,很多语法理解起来还是有点费劲
30 1
|
18天前
|
移动开发 小程序 JavaScript
uniapp开发打包ios应用踩坑记
iOS 设备的一个唯一识别码,每台 iOS 设备都有一个独一无二的编码,这个编码,我们称之为识别码,也叫做UDID
22 0
|
21天前
|
API 数据安全/隐私保护 iOS开发
 利用uni-app 开发的iOS app 发布到App Store全流程
首次提交关于App Store上架步骤流程:兼容检查 -> 账号申请 -> 证书申请 -> 发布准备 -> App Store上架 -> 审核后续提交审核iOS审核团队联系方式;
|
24天前
|
安全 数据安全/隐私保护 iOS开发
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固 摘要
随着智能手机的普及,越来越多的用户使用iOS设备来处理日常任务,因此iOS应用程序的安全性变得越来越重要。为了防止应用程序被攻击或破解,开发人员需要采用一些保护措施来加固应用程序。本文将介绍一种使用ipaguard混淆加固的方法来保护iOS应用的安全。
|
25天前
|
Linux Android开发 iOS开发
基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
37 0
|
1月前
|
iOS开发 开发者
iOS开发:如何进行App备案并查看SHA-1值?
在移动应用程序的开发和发布过程中,进行App备案是确保应用符合相关法规的重要一步。SHA-1值是应用与第三方服务进行集成时必须提供的信息。本教程将详细介绍如何进行App备案,并查看iOS应用的SHA-1值。
|
2月前
|
开发工具 Android开发 iOS开发
使用xamarin开发Android、iOS报错failed to open directory: 系统找不到指定的文件
使用vs2019学习xamarin时,创建新程序。使用模拟器真机等测试都报错如下图错误: ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/column/article/5877188/20231030-de8ce5fd.png?x-cos-security-token=r4KyZDEowPT0kGTL0LqE8EnwfN1Nzexadb05dcffed3939ff8d7591c528c01706nvpGSE93QwHpZM8NwhJNTZctNRQa0l3KDhEnqj8P7d8t
21 0
使用xamarin开发Android、iOS报错failed to open directory: 系统找不到指定的文件
|
2月前
|
存储 安全 数据安全/隐私保护
iOS开发之打包上传到App Store——(一)各种证书的理解
iOS开发之打包上传到App Store——(一)各种证书的理解
|
2月前
|
开发工具 Android开发 C语言
IOS APP开发:苹果app从开发到上架教程详解
IOS APP开发:苹果app从开发到上架教程详解
热门文章
最新文章
相关产品
云迁移中心
推荐文章
更多