audio监听不到结束 ios
2017-08-13 16:16:00 weixin_34319111 阅读数 23

每当在同一时间网络请求的时候, 务必要监听到所有的网络请求结束的时间.

请看如下例子:


// 模拟同时请求多个网络请求, 并监听所有网络请求都结束.
- (void)dispatch_group_Test {
    // 创建一个组
    dispatch_group_t group = dispatch_group_create();
    
    // 网络请求 1
    {
        // 进入组
        dispatch_group_enter(group);
        
        // 假装这里有一个网络请求
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // TODO : 假装这里有一个不定时的网络请求
            [NSThread sleepForTimeInterval:2];
            
            NSLog(@"网络请求 1 结束 %@", [NSThread currentThread]);
            // 任务结束, 退出组
            dispatch_group_leave(group);
        });
    }
    
    // 网络请求 2
    {
        // 进入组
        dispatch_group_enter(group);
        
        // 假装这里有一个网络请求
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // TODO : 假装这里有一个不定时的网络请求
            [NSThread sleepForTimeInterval:3];
            NSLog(@"网络请求 2 结束 %@", [NSThread currentThread]);
            // 任务结束, 退出组
            dispatch_group_leave(group);
        });
    }
    
    // 网络请求 3
    {
        // 进入组
        dispatch_group_enter(group);
        
        // 假装这里有一个网络请求
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // TODO : 假装这里有一个不定时的网络请求
            [NSThread sleepForTimeInterval:1];
            NSLog(@"网络请求 3 结束 %@", [NSThread currentThread]);
            // 任务结束, 退出组
            dispatch_group_leave(group);
        });
    }
    
    
    // 所有子线程任务全部完成, 并回到主线程
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"所有请求结束 %@", [NSThread currentThread]);
    });
}

还有另一种方式:

let globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let group = dispatch_group_create()

dispatch_group_async(group, globalQueue) { () -> Void in
    println("1")
}
dispatch_group_async(group, globalQueue) { () -> Void in
    println("2")
}
dispatch_group_async(group, globalQueue) { () -> Void in
    println("3")
}
dispatch_group_notify(group, globalQueue) { () -> Void in
    println("completed")
}

来自于 : iOS GCD使用指南

2017-06-27 14:04:01 xiejinwen 阅读数 7273

最近做了个H5产品的宣传活动,用到了audio标签并且要求自动播放,我们都知道safri on ios里面明确指出等待用户的交互动作后才能播放media,也就是说如果你没有得到用户的action就播放的话就会被safri拦截。百度了许多方法,其实很多都说亲测可用,然而都是骗子,用上去之后再iphone还是不能自动播放,这里我是做微信上的H5活动,所以使用了微信上的插件配合就能达到自动播放的效果,在其他浏览器上我没有测试过!

<script type="text/javascript" src="js/jweixin-1.0.0.js"></script>

<audio controls="controls" id="audio_cot">
<source src="vedio/Sheppard.mp3" type="audio/mpeg" />
</audio>

	var $audio = $('#audio_cot')[0];
	//$audio.play();	

	wx.config({
	    debug : false, // 这里为false
	    appId : '', // 以下随意填写即可
	    timestamp : (new Date()).getTime(),
	    nonceStr : '',
	    signature : '',
	    jsApiList : ['checkJsApi'] 
    });
	wx.ready(function() {
	    $audio.play();
    });
	

接下来就是要监听audio的播放状态从而改变音乐播放暂停的图标

	$audio.addEventListener("playing", function(){		
		$audio.removeClass('music_off').addClass('music_on');
});$audio.addEventListener("pause", function(){
		$audio.removeClass('music_on').addClass('music_off');
});




2012-10-21 10:52:57 jinglijun 阅读数 1428

iOS SDK附带提供多种方法播放声音剪辑,甚至产生音频的framework。

苹果的 Multimedia Programming Guide 介绍了每一个可用的音频框架的目的如下:

1.用Media Player framework 来播放用户的iPod音乐库中播放歌曲,有声书籍,音频播客。详细的请看 Media Player Framework Reference, iPod Library Access Programming Guide, 和 AddMusic 官方的源代码。

2.用 AV Foundation framework 来播放和录制音频使用一个简单的Objective-C接口。详细请看 AV Foundation Framework Referenceand和 avTouch官方源代码。

3.用 Audio Toolbox framework 来播放传入的音频同步能力,接入包,解析音频流,转换音频格式,并记录提供给每个数据包的音频,详细请看 Audio Toolbox Framework ReferenceSpeakHere  官方的源代码。

4.用 Audio Unit framework 来连接和使用的音频处理插件,详细请看Audio Unit Hosting Guide for iOS

5.用OpenAL framework 来在游戏和其他应用程序提供位置的音频播放。 iOS支持OpenAL 1.1.详细请看 OpenAL 网站, OpenAL FAQ for iPhone OS, 和 oalTouch 官方的源代码。

2018-01-25 16:21:00 weixin_33798152 阅读数 1

1. 播放音效

#pragma mark 基本使用
- (void)baseUse
{
    //1. 创建URL地址
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
    
    //2. 系统音效文件 SystemSoundID = UInt32
    SystemSoundID soundID;
    
    //3. 创建音效文件
    AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);
    
    //4. 播放音效文件
    //4.1 不带震动的播放
    //AudioServicesPlaySystemSound(soundID);
    
    //4.2 带振动的播放 --> 真机才有效果
    AudioServicesPlayAlertSound(soundID);
    
    //5. 如果不需要播放了, 需要释放音效所占用的内存
    AudioServicesDisposeSystemSoundID(soundID);
}

2. 简单封装

MTAudioTool.h

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

@interface MTAudioTools : NSObject
/** 播放系统音效*/
+ (void)playSystemSoundWithURL:(NSURL *)url;
/** 播放震动音效*/
+ (void)playAlertSoundWithURL:(NSURL *)url;
/** 清空音效文件的内存*/
+ (void)clearMemory;
@end

MTAudioTool.m


#import "MTAudioTools.h"

/** 缓存字典*/
static NSMutableDictionary *_soundIDDict;

@implementation MTAudioTools

// 只要头文件参与了编译调用
//+ (void)load

/** 缓存字典初始化*/
+ (void)initialize
{
    _soundIDDict = [NSMutableDictionary dictionary];
}

+ (void)playSystemSoundWithURL:(NSURL *)url
{
    // 不带震动的播放
    AudioServicesPlaySystemSound([self loadSoundIDWithURL:url]);
}

/** 播放震动音效*/
+ (void)playAlertSoundWithURL:(NSURL *)url
{
    // 带震动的播放
    AudioServicesPlayAlertSound([self loadSoundIDWithURL:url]);

}

#pragma mark 播放音效的公用方法
+ (SystemSoundID)loadSoundIDWithURL:(NSURL *)url
{
    // 思路思路
    // soundID重复创建 --> soundID每次创建, 就会有对应的URL地址产生
    // 可以将创建后的soundID 及 对应的URL 进行缓存处理
    
    //1. 获取URL的字符串
    NSString *urlStr = url.absoluteString;
    
    //2. 从缓存字典中根据URL来取soundID 系统音效文件
    SystemSoundID soundID = [_soundIDDict[urlStr] intValue];
    
    //需要在刚进入的时候, 判断缓存字典是否有url对应的soundID
    
    //3. 判断soundID是否为0, 如果为0, 说明没有找到, 需要创建
    if (soundID == 0) {
        //3.1 创建音效文件
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);
        
        //3.2 缓存字典的添加键值
        _soundIDDict[urlStr] = @(soundID);
    }
    
    return soundID;
}


/** 清空音效文件的内存*/
+ (void)clearMemory
{
    //1. 遍历字典
    [_soundIDDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        //2. 清空音效文件的内存
        SystemSoundID soundID = [obj intValue];
        AudioServicesDisposeSystemSoundID(soundID);
    }];
}

@end

ViewController.m

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "MTAudioTools.h"

/**
 1. 导入AVFoundation框架
 2. 创建音效文件
 3. 播放音效文件
 
 音效: 非常短的音乐, 一般来说30秒以内的声音, 都算作音效
 */

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark 点击播放音效
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1. 获取URL地址
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
    
    //2. 调用工具类播放音效
    //[MTAudioTools playSystemSoundWithURL:url];
    
    [MTAudioTools playAlertSoundWithURL:url];
    
}

#pragma mark 当前控制器收到内存警告时会调用的方法
- (void)didReceiveMemoryWarning
{
    // 局部音效需要在这里进行释放
    [MTAudioTools clearMemory];
    NSLog(@"%s",__func__);
}

@end

3. 音乐播放

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

/**
 1. 需要使用AVFoundatiaon框架
 2. 创建音乐播放器
 3. 根据需求, 进行播放/暂停/停止
 */

@interface ViewController ()
@property (nonatomic, strong) AVAudioPlayer *player;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建音乐播放器
    
    //1. 获取URL路径
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"我爱你你却爱着她.mp3" withExtension:nil];
    
    //2. 创建一个error对象
    NSError *error;
    
    //3. 创建音乐播放器
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    
    if (error) {
        NSLog(@"有错误产生");
    }
    
}

- (IBAction)playClick:(id)sender {
    //1. 准备播放 --> 将音频文件加载到内存中 --> 这句话可以不写 --> play会隐式调用prepareToPlay方法. 但是规范来说, 还是会写上
    [self.player prepareToPlay];
    
    //2. 开始播放
    [self.player play];
}

- (IBAction)pauseClick:(id)sender {

    // 暂停播放
    [self.player pause];
}

- (IBAction)stopClick:(id)sender {
    // 停止播放
    [self.player stop];
    
    // 归零操作 / 时间重置 currentTime--> 秒为单位
    self.player.currentTime = 0;
}
@end

4. 录音

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

/**
 1. 需要使用AVFoundatiaon框架
 2. 创建录音对象
 3. 根据需求, 进行录音/暂停/停止
 */

@interface ViewController ()

@property (nonatomic, strong) AVAudioRecorder *recorder;

@property (nonatomic, strong) CADisplayLink *displayLink;

@end

@implementation ViewController

/**
 
 //录音
 //    //settings  设置参数  录音相关参数  声道  速率  采样率
 //    NSMutableDictionary *setting = [NSMutableDictionary dictionary];
 //    // 音频格式
 //    setting[AVFormatIDKey] = @(kAudioFormatAppleIMA4);
 //    // 音频采样率
 //    setting[AVSampleRateKey] = @(600.0);
 //    // 音频通道数
 //    setting[AVNumberOfChannelsKey] = @(1);
 //    // 线性音频的位深度
 //    setting[AVLinearPCMBitDepthKey] = @(8);
 */

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建录音对象
    //1. 获取URL地址 --> 具体的文件名路径
    //--> 注意之前是获取资源地址, 这里是指要将录音存放到哪里
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"recorde.wav"];
    
    //2. 将path字符串转换成NSURL --> file://
    NSURL *url = [NSURL fileURLWithPath:path];
    
    //3. 配置设置字典
    // 如果传空, 默认就是高质量
    // 录音的参数值
    NSMutableDictionary *setting = [NSMutableDictionary dictionary];
    
    //4. 创建Error对象 __autoreleasing 可以不加, 加上之后是最标准写法
    __autoreleasing NSError *error;
    
    //5. 创建录音对象
    self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
    
//    if (error) {
//        NSLog(@"error");
//    }
    
    //6. 打开分贝的检测
    self.recorder.meteringEnabled = YES;
    
    //7. 如果要在真机运行, 还需要一个session类, 并且制定分类为录音
    AVAudioSession *session = [AVAudioSession new];
    [session setCategory:AVAudioSessionCategoryRecord error:nil];
}

- (IBAction)recordClick:(id)sender {
    //1. 准备录音
    [self.recorder prepareToRecord];
    
    //2. 开始录音  --> 如果同一路径再次录音, 则会覆盖之前的文件
    [self.recorder record];
    
    //3. 进行分贝的循环检测 --> 添加计时器
    [self updateMetering];
}

- (IBAction)pauseClick:(id)sender {
    // 暂停录音  --> 如果用户只是暂停了, 应该提示用户进行保存操作
    [self.recorder pause];
    
    // 暂停循环
    self.displayLink.paused = YES;
}

- (IBAction)stopClick:(id)sender {
    // 停止录音 --> 之后停止录音时, 最终的录音文件才会生产
    [self.recorder stop];
    
    // 暂停循环
    self.displayLink.paused = YES;
    
    NSLog(@"停止录音");
}

#pragma mark 添加计时器
- (void)updateMetering
{
    // 如果没有displayLink就创建
    if (self.displayLink == nil) {
        //1. 创建displayLink
        self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateMeter)];
        
        //2. 添加到运行循环中
        [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }
    
    // 判断如果暂停了循环, 就打开
    if (self.displayLink.isPaused) {
        self.displayLink.paused = NO;
    }
}

#pragma mark 循环调用的方法
- (void)updateMeter
{
    //需求: 自动停止录音 --> 根据分贝的大小来判断
    
    //1. 我们需要获取分贝信息
    //2. 设置分贝如果小于某个值, 一定时间后, 自动停止
    
    //1. 更新分贝信息
    [self.recorder updateMeters];
    
    //2. 获取分贝信息 --> iOS直接传0
    // 0 ~ -160 , 值最大是0, 最小是-160. 系统返回的是负值
    CGFloat power = [self.recorder averagePowerForChannel:0];
    
    //3. 实现2S自动停止
    static NSInteger number;
    
    //displayLink,一秒默认是60次, 如果120此的调用都小于某个分贝值, 我们就可以认为要自动停止
    
    //3.1 先判断用户是否小于某个分贝值 --> 用户是否没说话
    if (power < -30) {
        
        //3.2 如果发现很安静, 我们就可以记录一下, number进行叠加
        number++;
        
        //3.3 如果发现120次了, 都小于设定的分贝值
        if (number / 60 >= 2) {
            
            //3.4 调用停止方法
            [self stopClick:nil];
        }
    } else {
        number = 0;
    }
    
    NSLog(@"power: %f",power);
}

@end
2018-03-27 10:53:50 mazaiting 阅读数 331

1. 播放音效

#pragma mark 基本使用
- (void)baseUse
{
    //1. 创建URL地址
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
    
    //2. 系统音效文件 SystemSoundID = UInt32
    SystemSoundID soundID;
    
    //3. 创建音效文件
    AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);
    
    //4. 播放音效文件
    //4.1 不带震动的播放
    //AudioServicesPlaySystemSound(soundID);
    
    //4.2 带振动的播放 --> 真机才有效果
    AudioServicesPlayAlertSound(soundID);
    
    //5. 如果不需要播放了, 需要释放音效所占用的内存
    AudioServicesDisposeSystemSoundID(soundID);
}

2. 简单封装

MTAudioTool.h

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

@interface MTAudioTools : NSObject
/** 播放系统音效*/
+ (void)playSystemSoundWithURL:(NSURL *)url;
/** 播放震动音效*/
+ (void)playAlertSoundWithURL:(NSURL *)url;
/** 清空音效文件的内存*/
+ (void)clearMemory;
@end

MTAudioTool.m


#import "MTAudioTools.h"

/** 缓存字典*/
static NSMutableDictionary *_soundIDDict;

@implementation MTAudioTools

// 只要头文件参与了编译调用
//+ (void)load

/** 缓存字典初始化*/
+ (void)initialize
{
    _soundIDDict = [NSMutableDictionary dictionary];
}

+ (void)playSystemSoundWithURL:(NSURL *)url
{
    // 不带震动的播放
    AudioServicesPlaySystemSound([self loadSoundIDWithURL:url]);
}

/** 播放震动音效*/
+ (void)playAlertSoundWithURL:(NSURL *)url
{
    // 带震动的播放
    AudioServicesPlayAlertSound([self loadSoundIDWithURL:url]);

}

#pragma mark 播放音效的公用方法
+ (SystemSoundID)loadSoundIDWithURL:(NSURL *)url
{
    // 思路思路
    // soundID重复创建 --> soundID每次创建, 就会有对应的URL地址产生
    // 可以将创建后的soundID 及 对应的URL 进行缓存处理
    
    //1. 获取URL的字符串
    NSString *urlStr = url.absoluteString;
    
    //2. 从缓存字典中根据URL来取soundID 系统音效文件
    SystemSoundID soundID = [_soundIDDict[urlStr] intValue];
    
    //需要在刚进入的时候, 判断缓存字典是否有url对应的soundID
    
    //3. 判断soundID是否为0, 如果为0, 说明没有找到, 需要创建
    if (soundID == 0) {
        //3.1 创建音效文件
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);
        
        //3.2 缓存字典的添加键值
        _soundIDDict[urlStr] = @(soundID);
    }
    
    return soundID;
}


/** 清空音效文件的内存*/
+ (void)clearMemory
{
    //1. 遍历字典
    [_soundIDDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        //2. 清空音效文件的内存
        SystemSoundID soundID = [obj intValue];
        AudioServicesDisposeSystemSoundID(soundID);
    }];
}

@end

ViewController.m

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "MTAudioTools.h"

/**
 1. 导入AVFoundation框架
 2. 创建音效文件
 3. 播放音效文件
 
 音效: 非常短的音乐, 一般来说30秒以内的声音, 都算作音效
 */

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark 点击播放音效
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1. 获取URL地址
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
    
    //2. 调用工具类播放音效
    //[MTAudioTools playSystemSoundWithURL:url];
    
    [MTAudioTools playAlertSoundWithURL:url];
    
}

#pragma mark 当前控制器收到内存警告时会调用的方法
- (void)didReceiveMemoryWarning
{
    // 局部音效需要在这里进行释放
    [MTAudioTools clearMemory];
    NSLog(@"%s",__func__);
}

@end

3. 音乐播放

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

/**
 1. 需要使用AVFoundatiaon框架
 2. 创建音乐播放器
 3. 根据需求, 进行播放/暂停/停止
 */

@interface ViewController ()
@property (nonatomic, strong) AVAudioPlayer *player;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建音乐播放器
    
    //1. 获取URL路径
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"我爱你你却爱着她.mp3" withExtension:nil];
    
    //2. 创建一个error对象
    NSError *error;
    
    //3. 创建音乐播放器
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    
    if (error) {
        NSLog(@"有错误产生");
    }
    
}

- (IBAction)playClick:(id)sender {
    //1. 准备播放 --> 将音频文件加载到内存中 --> 这句话可以不写 --> play会隐式调用prepareToPlay方法. 但是规范来说, 还是会写上
    [self.player prepareToPlay];
    
    //2. 开始播放
    [self.player play];
}

- (IBAction)pauseClick:(id)sender {

    // 暂停播放
    [self.player pause];
}

- (IBAction)stopClick:(id)sender {
    // 停止播放
    [self.player stop];
    
    // 归零操作 / 时间重置 currentTime--> 秒为单位
    self.player.currentTime = 0;
}
@end

4. 录音

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

/**
 1. 需要使用AVFoundatiaon框架
 2. 创建录音对象
 3. 根据需求, 进行录音/暂停/停止
 */

@interface ViewController ()

@property (nonatomic, strong) AVAudioRecorder *recorder;

@property (nonatomic, strong) CADisplayLink *displayLink;

@end

@implementation ViewController

/**
 
 //录音
 //    //settings  设置参数  录音相关参数  声道  速率  采样率
 //    NSMutableDictionary *setting = [NSMutableDictionary dictionary];
 //    // 音频格式
 //    setting[AVFormatIDKey] = @(kAudioFormatAppleIMA4);
 //    // 音频采样率
 //    setting[AVSampleRateKey] = @(600.0);
 //    // 音频通道数
 //    setting[AVNumberOfChannelsKey] = @(1);
 //    // 线性音频的位深度
 //    setting[AVLinearPCMBitDepthKey] = @(8);
 */

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建录音对象
    //1. 获取URL地址 --> 具体的文件名路径
    //--> 注意之前是获取资源地址, 这里是指要将录音存放到哪里
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"recorde.wav"];
    
    //2. 将path字符串转换成NSURL --> file://
    NSURL *url = [NSURL fileURLWithPath:path];
    
    //3. 配置设置字典
    // 如果传空, 默认就是高质量
    // 录音的参数值
    NSMutableDictionary *setting = [NSMutableDictionary dictionary];
    
    //4. 创建Error对象 __autoreleasing 可以不加, 加上之后是最标准写法
    __autoreleasing NSError *error;
    
    //5. 创建录音对象
    self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
    
//    if (error) {
//        NSLog(@"error");
//    }
    
    //6. 打开分贝的检测
    self.recorder.meteringEnabled = YES;
    
    //7. 如果要在真机运行, 还需要一个session类, 并且制定分类为录音
    AVAudioSession *session = [AVAudioSession new];
    [session setCategory:AVAudioSessionCategoryRecord error:nil];
}

- (IBAction)recordClick:(id)sender {
    //1. 准备录音
    [self.recorder prepareToRecord];
    
    //2. 开始录音  --> 如果同一路径再次录音, 则会覆盖之前的文件
    [self.recorder record];
    
    //3. 进行分贝的循环检测 --> 添加计时器
    [self updateMetering];
}

- (IBAction)pauseClick:(id)sender {
    // 暂停录音  --> 如果用户只是暂停了, 应该提示用户进行保存操作
    [self.recorder pause];
    
    // 暂停循环
    self.displayLink.paused = YES;
}

- (IBAction)stopClick:(id)sender {
    // 停止录音 --> 之后停止录音时, 最终的录音文件才会生产
    [self.recorder stop];
    
    // 暂停循环
    self.displayLink.paused = YES;
    
    NSLog(@"停止录音");
}

#pragma mark 添加计时器
- (void)updateMetering
{
    // 如果没有displayLink就创建
    if (self.displayLink == nil) {
        //1. 创建displayLink
        self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateMeter)];
        
        //2. 添加到运行循环中
        [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }
    
    // 判断如果暂停了循环, 就打开
    if (self.displayLink.isPaused) {
        self.displayLink.paused = NO;
    }
}

#pragma mark 循环调用的方法
- (void)updateMeter
{
    //需求: 自动停止录音 --> 根据分贝的大小来判断
    
    //1. 我们需要获取分贝信息
    //2. 设置分贝如果小于某个值, 一定时间后, 自动停止
    
    //1. 更新分贝信息
    [self.recorder updateMeters];
    
    //2. 获取分贝信息 --> iOS直接传0
    // 0 ~ -160 , 值最大是0, 最小是-160. 系统返回的是负值
    CGFloat power = [self.recorder averagePowerForChannel:0];
    
    //3. 实现2S自动停止
    static NSInteger number;
    
    //displayLink,一秒默认是60次, 如果120此的调用都小于某个分贝值, 我们就可以认为要自动停止
    
    //3.1 先判断用户是否小于某个分贝值 --> 用户是否没说话
    if (power < -30) {
        
        //3.2 如果发现很安静, 我们就可以记录一下, number进行叠加
        number++;
        
        //3.3 如果发现120次了, 都小于设定的分贝值
        if (number / 60 >= 2) {
            
            //3.4 调用停止方法
            [self stopClick:nil];
        }
    } else {
        number = 0;
    }
    
    NSLog(@"power: %f",power);
}

@end

iOS Audio(音频)

阅读数 12

iOS Audio(音频)

阅读数 11

IOS Audio RemoteControl

阅读数 1464

iOS Audio 后台播放

阅读数 556

没有更多推荐了,返回首页