01.音频播放 音频播放

@(iOS Study)[音视频播放]


目录

  • 01.音频播放 音频播放知识点
    • 音频播放
  • 1.AVFoundation框架
  • 2.实现录音功能
    • 简单使用AVAudioRecorder实现录音功能
  • 3.使用SystemSoundID播放音效
    • 使用SystemSoundID播放音效
    • 封装使用SystemSoundID播放音效工具类
  • 4.使用AVAudioPlayer播放器播放音乐

音频播放

1.AVFoundation框架

  • 可以进行录音
  • 播放音效(短暂音频)
  • 播放音乐(一首完整的歌)(本地/远程)
  • 播放视频(本地/远程)

2.实现录音功能

简单使用AVAudioRecorder实现录音功能

  • 录音功能实现步骤
    • 1.设置录音文件存放的url,音频相关参数
      • 1.1 要保存的路径(沙盒路径)
      • 1.2 拼接全路径, caf是录音文件的格式,如mp3
      • 1.3 创建url
      • 1.4 设置setting
    • 2.创建录音对象
    • 3.开始录音
      [self.recorder record];
    • 4.停止录音
      [self.recorder stop];
#pragma mark - 懒加载
// REMARKS: 简单使用AVAudioRecorder实现录音功能
- (AVAudioRecorder *)recorder
{
    if (_recorder == nil) {
        
        // 1.设置录音文件存放的url,音频相关参数
        // 1.1 要保存的路径(沙盒路径)
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        // 1.2 拼接全路径, caf是录音文件的格式,如mp3
        NSString *fullPath = [path stringByAppendingPathComponent:@"123.caf"];
        
        // 1.3 创建url
        NSURL *url = [NSURL fileURLWithPath:fullPath];
        
        // 1.4 设置setting
        /**
         AVEncoderAudioQualityKey : @(AVAudioQualityLow),   // 音频质量
         AVEncoderBitRateKey : @(16),                       // 比特率
         AVNumberOfChannelsKey : @(2),                      // 通道
         AVFormatIDKey : @(kAudioFormatLinearPCM),          // 音频编码
         AVSampleRateKey : @(8000.0)                        // 速率
         */
        NSDictionary *settingDict = @{
                                      AVEncoderAudioQualityKey : @(AVAudioQualityLow),
                                      AVEncoderBitRateKey : @(16),
                                      AVNumberOfChannelsKey : @(2),
                                      AVFormatIDKey : @(kAudioFormatLinearPCM),
                                      AVSampleRateKey : @(8000.0)
                                      };
        
        // 2.创建录音对象
        _recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settingDict error:nil];
    }
    return _recorder;
}

- (IBAction)startRecorder {
    // SINGLE: 开始录音
    [self.recorder record];
}

- (IBAction)stopRecorder {
    // SINGLE: 停止录音
    [self.recorder stop];
}

3.使用SystemSoundID播放音效

使用SystemSoundID播放音效

  • 使用SystemSoundID(C语言AudioServicesPlaySystemSound函数)方式播放短音效
    • 1.创建SystemSoundID
    • 2.创建音效资源url,url类型为CFURLRef类型,使用(__bridge CF type)方式桥联,不需要手动释放
      使用(__bridge_retained CF type)方式桥联,需要手动释放,需要调用CFRelease(CFTypeRef cf)方法释放
    • 3.通过url生成SystemSoundID
    • 4.播放音效
      • 播放音效没有有震动效果
        AudioServicesPlaySystemSound(soundID);
      • 播放音效有震动效果,需用真机测试
        AudioServicesPlayAlertSound(soundID);
// REMARKS: 使用SystemSoundID(C语言AudioServicesPlaySystemSound函数)方式播放音效
- (void)AudioServicesPlaySound
{
    // 1.创建SystemSoundID
    SystemSoundID soundID = 0;
    
    // 2.创建音效资源url
    // SINGLE: 使用(__bridge CF type)方式桥联,不需要手动释放
    // 使用(__bridge_retained CF type)方式桥联,需要手动释放,需要调用CFRelease(CFTypeRef cf)方法释放
    CFURLRef url = (__bridge CFURLRef)[[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
    
    // 3.通过url生成SystemSoundID
    AudioServicesCreateSystemSoundID(url, &soundID);
    
    // 4.播放音效
    AudioServicesPlaySystemSound(soundID);  // 播放音效没有有震动效果
//    AudioServicesPlayAlertSound(soundID);   // 播放音效有震动效果,需用真机测试
}

封装使用SystemSoundID播放音效工具类

  • 封装播放音效WXAudioTool工具类
// SINGLE: 创建一个可变字典缓存歌曲,字典只需创建一次,可以在initialize类方法中创建
static NSMutableDictionary *_soundIDs;
+ (void)initialize {
    // 创建可变字典
    _soundIDs = [NSMutableDictionary dictionary];
}

// REMARKS: 播放音效类方法
/** 播放音效 */
+ (void)playSoundWithSoundName:(NSString *)soundName
{
    // 1.先从内存缓存获取soundID
    SystemSoundID soundID = [_soundIDs[soundName] unsignedIntegerValue];
    
    // 2.判断内存是否存在音效资源,内存没有音效资源,则创建
    if (soundID == 0) {
        // 2.1 若不存在, 创建音效资源url
        CFURLRef url = (__bridge CFURLRef)[[NSBundle mainBundle] URLForResource:soundName withExtension:nil];
        
        // 2.2 判断url是否为空,如果为空,说明资源不存在,直接退出
        if (url == nil) return;
        
        // 2.3 生成SystemSoundID
        AudioServicesCreateSystemSoundID(url, &soundID);
        
        // 2.4 存入可变字典内存缓存
        [_soundIDs setObject:@(soundID) forKey:soundName];
    }
    
    // 3.播放音效
    AudioServicesPlaySystemSound(soundID);
}

4.使用AVAudioPlayer播放器播放音乐

  • AVAudioPlayer控制音量属性,音量范围0.0 ~ 1.0
    self.player.volume = 0.5;
  • 使用AVAudioPlayer封装播放音乐工具类WXAudioTool
    • 实现播放/暂停/停止音乐等方法
      播放音乐: + (AVAudioPlayer *)playMusicWithMusicName:(NSString *)musicName;
      暂停音乐: + (void)pauseMusicWithMusicName:(NSString *)musicName;
      停止音乐: + (void)stopMusicWithMusicName:(NSString *)musicName;
      播放音效: + (void)playSoundWithSoundName:(NSString *)soundName;
#import "WXAudioTool.h"
#import <AVFoundation/AVFoundation.h>

@implementation WXAudioTool

// SINGLE: 创建一个可变字典缓存音乐,字典只需创建一次,可以在initialize类方法中创建
static NSMutableDictionary *_soundIDs;
// SINGLE: 创建音乐内存缓存,在initialize类方法中创建
static NSMutableDictionary *_players;

#pragma mark - 初始化设置
/** 创建内存缓存 */
+ (void)initialize {
    // 创建可变字典,用于存放播放音效SystemSoundID
    _soundIDs = [NSMutableDictionary dictionary];
    
    // 创建可变字典,用于存放音乐播放器AVAudioPlayer
    _players = [NSMutableDictionary dictionary];
}

#pragma mark - 播放音乐API(AVAudioPlayer)
/** 播放音乐 */
+ (AVAudioPlayer *)playMusicWithMusicName:(NSString *)musicName
{
    // 1.先从内存字典中获取播放器AVAudioPlayer
    AVAudioPlayer *player = _players[musicName];
    
    // 2.判断是否从内存获取到播放器,如果没有获取到,新建播放器
    if (player == nil) {
        // 2.1 获取音乐文件的url
        NSURL *url = [[NSBundle mainBundle] URLForResource:musicName withExtension:nil];
        if (url == nil) return nil;

        // 2.2 根据音频文件的url,创建播放器
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        
        // 2.3 保存到内存缓存_players
        [_players setObject:player forKey:musicName];
    }
    
    // SINGLE: 3.播放音乐
    [player play];
    
    return player;
}

/** 暂停音乐 */
+ (void)pauseMusicWithMusicName:(NSString *)musicName
{
    // 1.从内存字典中取出播放器
    AVAudioPlayer *player = _players[musicName];
    
    // 2.如果内存中有获取到播放器,暂停播放
    if (player) {
        // SINGLE: 暂停播放
        [player pause];
    }
}

/** 停止音乐 */
+ (void)stopMusicWithMusicName:(NSString *)musicName
{
    // 1.从内存字典中取出播放器
    AVAudioPlayer *player = _players[musicName];
    
    // 2.如果内存中有获取到播放器,停止播放
    if (player) {
        // SINGLE: 2.1 停止播放
        [player stop];
        // 2.2 从内存字典中移除
        [_players removeObjectForKey:musicName];
        player = nil;
    }
}

#pragma mark - 播放短音效API(SystemSoundID)

// REMARKS: 播放音效类方法
/** 播放音效 */
+ (void)playSoundWithSoundName:(NSString *)soundName
{
    // 1.先从内存缓存获取soundID
    SystemSoundID soundID = [_soundIDs[soundName] unsignedIntValue];
    
    // 2.判断内存是否存在音效资源,内存没有音效资源,则创建
    if (soundID == 0) {
        // 2.1 若不存在, 创建音效资源url
        CFURLRef url = (__bridge CFURLRef)[[NSBundle mainBundle] URLForResource:soundName withExtension:nil];
        
        // 2.2 判断url是否为空,如果为空,说明资源不存在,直接退出
        if (url == nil) return;
        
        // 2.3 生成SystemSoundID
        AudioServicesCreateSystemSoundID(url, &soundID);
        
        // 2.4 存入可变字典内存缓存
        [_soundIDs setObject:@(soundID) forKey:soundName];
    }
    
    // 3.播放音效
    AudioServicesPlaySystemSound(soundID);
}
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容