用swift实现自动录音器

基本介绍

自动录音一般录音区别在:不用像微信那样按下录音-松手结束,而是根据说话声音的大小自动判断该录音和该停止的点,然后可以做到结束录音之后马上播放出来。类似于达到会说话的汤姆猫那样的效果。

在自动录音的初始化阶段需要建立两个录音对象,一个需要一直录音充当监听器的功能,另一个用来在需要的时刻录音。具体流程大致如下

准备工作

这个项目使用swift写的,设置的成员变量如下

如果你不是在董铂然博客园看到本文请点击查看原文

    // 录音器
    var recoder:AVAudioRecorder!
    // 监听器
    var monitor:AVAudioRecorder!
    // 播放器
    var player:AVAudioPlayer!
    // 定时器
    var timer:NSTimer!
    // 录音器的URL
    var recordURL:NSURL!
    // 监听器的URL
    var monitorURL:NSURL!

当然这些属性不能直接敲出来需要先引入一个桥接文件并导入#import <AVFoundation/AVFoundation.h>

导入如果出现问题可以看下此文 : 怎么让OC与swift混合开发

 

在程序启动时应将录音器,监听器,定时器一同初始化。

在那之前需要先设置好音频的保存质量,这其中会用到很多库里自带的key,AVSampleRateKey,AVFormatIDKey,AVNumberOfChannelsKey,AVEncoderAudioQualityKey这些key对应的值一般为double类型或int类型。一一解释没有必要,大概意思就是保存声音的Hertz(类似于QQ音乐的无损和普通),转化率,保存的声道,声音品质等等。有兴趣的可以仔细去头文件里研究研究。我就查了下所有参数的最高品质发现录完之后大小也可以接受就用最高品质了。(但是微信说话那种发的应该是中下品质,省流量且时效性为主)

        AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, error:nil)
        var recoderSetting:NSDictionary = NSDictionary(objectsAndKeys: 14400.0,AVSampleRateKey,kAudioFormatAppleIMA4,AVFormatIDKey,2,AVNumberOfChannelsKey,0x7F,AVEncoderAudioQualityKey)

这其中有个参数应该是AVAudioQuality.Max类型但是swift不能识别,就直接查看里面的常量用十六进制填进去了。总的来说就是先用一个字典把所有的键值对都存好然后这个字典会用在后面实例化录音器中的一个参数。

初始化录音器的方法如下,监听器完全相似只需要另改一个URL

        // 实例化录音器
        var recordPath = NSTemporaryDirectory().stringByAppendingPathComponent("record.caf")
        recordURL = NSURL.fileURLWithPath(recordPath)
        recoder = AVAudioRecorder(URL: recordURL, settings:recoderSetting as [NSObject : AnyObject], error: nil)

 

开始录音

核心功能是录音,录音的原理是监听声音分贝的大小,自己设置临界点开启和关闭录音。(董铂然)

  • 如果声音一直很小不作处理。
  • 如果声音大了先判断现在是否在录音如果没有则开始录音。
  • 如果声音小了先判断现在是否在录音如果在录音则停止录音。
    func updateTimer(){

        // 更新测量器
        self.monitor.updateMeters()
        // 获得说话的分贝
        var power = self.monitor.peakPowerForChannel(0);
        
        println("-----》\(power)")
        
        if (power > -30){
            if(!self.recoder.recording){
                println("开始录音")
                self.recoder.record()
            }
        }else {
            if(self.recoder.recording){
                println("结束录音")
                self.recoder.stop()
                self.play()
            }
        
        }

尝试的结果如下打印,其中数值就是一直监听分贝数。极安静的情况下是-160 嘈杂环境一般是-40起。

 

播放声音

录音完成后可以直接设置马上播放声音

    func play(){
        timer.invalidate()
        monitor.stop()
        // 删除录音缓存
        monitor.deleteRecording()
        player = AVAudioPlayer(contentsOfURL: recordURL, error: nil)
        player.delegate = self
        player.play()
    }

上面图中的定时器停止-监听器停止-删除监听器的缓存 在这块代码中都有体现。这里建议设置一下代理,因为即使是播放一次在播放完成后也很可能会做一些额外操作,并且此项目的期望是能够循环的录音播放。即播放完打开定时器,监听器重新开始总流程。

 

延展操作

代理遵守的是AVAudioPlayerDelegate 。并实现代理方法,在代理方法中调用之前开启的方法

    func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
        // 重新开启定时器
        self.setupTimer()
    }
    func setupTimer(){
        self.monitor.record()
        self.timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "updateTimer", userInfo: nil, repeats: true)
    }

到此为止一个完整的录音流程就结束了。

也可以做一些特殊操作就是类似于会说话的汤姆猫并不是把你说的话原话说出,而是对声音做了一定的处理再说出的。如果想实现此功能需要再声音播放前,先开启声音预播放,并且设置一些更改声音的操作最后再播放以达到目的。大部分的属性在修改前都需要打开一个BOOL值才能操作。举例如下(把上面的play()换成下面代码)

        // 允许更改速度
        player.enableRate = true
        // 设置速度
        player.rate = 2
        player.play()

这个属性rate的取值范围是0.5到2.0。原生的好像就找到这一个其他的改声调等应该还需要引用第三方库。

如果你不是在董铂然博客园看到本文请点击查看原文

 

posted @ 2015-07-27 11:57  董铂然  阅读(2694)  评论(2编辑  收藏  举报