录音功能实现

http://hhuai.github.com/blog/2012/02/05/ios-and-andorid-voice/

介绍

学习ios第一个练手功能就是给已有产品加上语音通信功能,能够互通ios与android。这里给出自己的一些心得,希望能给他人一些参考。

资料搜集与参考

  1. 类似产品使用的技术

    • talkbox Android版用的是ilbc的第三方编解码库,在iPhone上用的是caf
    • 微信   Android版估计是amr估计转码的是交给腾讯强大的服务器了。
    • 米聊   Android版和Iphone版用的都是speex

    目前支持的开源第三方库也就只有 ilbc和speex了

  2. 考虑采用的方案

    speex 需要Android和ios都进入转码,工作量太大,不采用。 剩下的方案就是在amr和ilbc上选择了,android支持amr,低版本不支持ilbc, ios高版本(4.3)只支持ilbc,不能支持amr。 刚开始的测试方案使用的是android将语音转ilbc, 由于我对于android开发不是太熟悉,在同事的帮助下一直没有转换成功,现在想想可能是处理问题,如果能转换成或,这种方案应该是最方便的。

ios实现amr编解码

录制

  1. 将语音录成原始pcm码

    注意这里,虽然录制是pcm码,但出来的文件ios依然会封装一层,将其包装成pcf格式。所以就有了第二步。

  2. 将pcf中的pcm码取出来
  3. 使用libopencore库将其编成amr格式,这时可以发送给android端播放了。

播放

  1. 将android版本发送过来的amr解码出来
  2. 播放原始pcm即可

代码文件都放在github上了,有需要的可以参考一下。 https://github.com/hhuai/ios_util

--------------------------------------------------------------

真正用到的例子

https://github.com/guange2015/ios-amr

--------------------------------------------------------------

国外专门的博客

http://www.raywenderlich.com/69365/audio-tutorial-ios-file-data-formats-2014-edition

--------------------------------------------------------------

我是采用的AVAudioRecorder这个框架来进行录音

这个录音跟官方网站上的speakHere有些区别,最大的区别是,这个必须要录制完成才能处理文件,而speakhere示例是可以实现边录制边上传的效果。

#import <AVFoundation/AVFoundation.h>

#import <CoreAudio/CoreAudioTypes.h>

引入框架,这是使用录音功能的基本配备

先说明一点,默认AVAudioRecorder录制后的格式是.caf,而大部分的播放器都是不支持这个格式的,下面一段设置是可以让录制格式是wav的格式

NSDictionary *recordSetting = [[NSDictionary
alloc] initWithObjectsAndKeys:

[NSNumber
numberWithFloat: 44100.0],AVSampleRateKey, //采样率

[NSNumber
numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,

[NSNumber
numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数
默认 16

[NSNumber
numberWithInt: 2],
AVNumberOfChannelsKey,//通道的数目

[NSNumber
numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端
是内存的组织方式

[NSNumber
numberWithBool:NO],AVLinearPCMIsFloatKey,nil];//采样信号是整数还是浮点数

NSURL *recordedTmpFile = [NSURL
fileURLWithPath:[NSTemporaryDirectory()
stringByAppendingPathComponent: [NSString
stringWithFormat: @"%.0f.%@", [NSDate
timeIntervalSinceReferenceDate] * 1000.0,
@"wav"]]];  //文件名的设置

//Setup the recorder to use this file and record to it.

AVAudioRecorder *recorder = [[
AVAudioRecorder alloc]
initWithURL:recordedTmpFile
settings:recordSetting error:&error];

[recorder
prepareToRecord];

[recorder
record];

下面代码应该是当前.m文件加载时候就设置

AVAudioSession * audioSession = [AVAudioSession
sharedInstance];

[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
error: &error]; //设置音频类别,这里表示当应用启动,停掉后台其他音频

[audioSession setActive:YES
error: &error];//设置当前应用音频活跃性

---------------------------------------------------------------------------------

//参数指定录音文件名和路径
-(void)startRecordWithPath:(NSString *)path
{
    NSError * err = nil;

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];

    if(err){
        NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return;
    }

    [audioSession setActive:YES error:&err];

    err = nil;
    if(err){
        NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return;
    }

    /*

     ios  几种格式录音大小
     Here are the results for few encoding supported by iPhone. Size of audio file in KB of duration 10 sec.

     kAudioFormatMPEG4AAC : 164,

     kAudioFormatAppleLossless : 430,

     kAudioFormatAppleIMA4 : 475,

     kAudioFormatULaw : 889,

     kAudioFormatALaw : 889,

     Among these kAudioFormatMPEG4AAC is having smallest size

     */
    //默认AVAudioRecorder录制后的格式是.caf
//    NSMutableDictionary * recordSetting = [NSMutableDictionary dictionary];
//    [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey]; //caf
//    [recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];  //采样率
//    [recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];

    //大部分的播放器都是不支持这个格式的,下面一段设置是可以让录制格式是wav的格式
//    NSDictionary *recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys:
//                                   [NSNumber numberWithFloat: 44100.0],AVSampleRateKey, //采样率
//                                   [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
//                                   [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数 默认 16
//                                   [NSNumber numberWithInt: 2], AVNumberOfChannelsKey,//通道的数目
//                                   [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端 是内存的组织方式
//                                   [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,nil];//采样信号是整数还是浮点数

//    NSDictionary *recordSetting = @{AVFormatIDKey : @(kAudioFormatLinearPCM), AVEncoderBitRateKey:@(16),AVEncoderAudioQualityKey : @(AVAudioQualityMax), AVSampleRateKey : @(8000.0), AVNumberOfChannelsKey : @(1)};

    self.recordPath = path;
    NSURL * url = [NSURL fileURLWithPath:self.recordPath];

    err = nil;

    NSData * audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];

    if(audioData)
    {
        NSFileManager *fm = [NSFileManager defaultManager];
        [fm removeItemAtPath:[url path] error:&err];
    }

    err = nil;

    if(self.recorder){[self.recorder stop];self.recorder = nil;}

    self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];

    if(!_recorder){
        NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        UIAlertView *alert =
        [[UIAlertView alloc] initWithTitle: @"Warning"
                                   message: [err localizedDescription]
                                  delegate: nil
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil];
        [alert show];
        return;
    }

    [_recorder setDelegate:self];
    [_recorder prepareToRecord];
    _recorder.meteringEnabled = YES;

    BOOL audioHWAvailable = audioSession.inputIsAvailable;
    if (! audioHWAvailable) {
        UIAlertView *cantRecordAlert =
        [[UIAlertView alloc] initWithTitle: @"提醒"
                                   message: @"设备无录音功能"
                                  delegate: nil
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil];
        [cantRecordAlert show];
        return;
    }

    //[_recorder recordForDuration:(NSTimeInterval) 60];

    self.recordTime = 0;
    [self resetTimer];

    timer_ = [NSTimer scheduledTimerWithTimeInterval:WAVE_UPDATE_FREQUENCY target:self selector:@selector(updateMeters) userInfo:nil repeats:YES];
    NSLog(@"------- timer_ : %@",timer_);

    [self showVoiceHudOrHide:YES];

}

-(void) stopRecordWithCompletionBlock:(void (^)())completion
{
    dispatch_async(dispatch_get_main_queue(),completion);

   // [self.recorder stopRecording]; //停止录音

    [self resetTimer];
    [self showVoiceHudOrHide:NO];
}
时间: 2024-08-24 17:26:25

录音功能实现的相关文章

为android系统添加USB AUDIO设备的放音和录音功能

http://blog.csdn.net/adits/article/details/8242146 开发环境简介 1. 主机系统: Unbuntu10.102. android系统版本: 4.0.3(Linux kernel 3.0.8) 综述 android的音频系统非常庞大复杂:涉及到java应用程序,java框架层,JNI,本地服务(AudioFlinger和AudioPolicyService),硬件抽象层HAL,ALSA-LIB和ALSA-DRIVER.本文将先分析音频系统的启动与模

Android 实现能够暂停的录音功能

转载请注明出处:http://blog.csdn.net/yegongheng/article/details/40624267 好久没更新博客了,着实有点惭愧,以后不管工作是忙是闲都得坚持更新博客,持之以恒地做下去! 正式进入主题,今天我分享一个在工作中过程中遇到的一个技术难点以及我解决该难点的方案,该问题困扰了我许久,通过不断地研究和翻阅资料,终于在满足工作需求的情况下将该问题解决,希望我的经验能够对读者有所帮助.我们知道Android ApI提供了MediaRecorder和AudioRe

iOS录音功能真机调试失败

在模拟器中录音功能正常,在真机上需要以下操作,才能正常录音 AVAudioSession * session = [AVAudioSession sharedInstance]; _session = session; NSError * sessionError; [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError]; if(session == nil) NSLog(@"Error

第二天,关于sip的学习(freeSwitch增加配置录音功能)(2)

学习一些FreeSwitch核心的一些命令,再细节地了解下FS. 看下是不是之前怀疑的,二次编程的时候更改配置文件,或者java注入一些参数到配置文件,详细了解下配置文件. 这个应该比较难的,不清楚 问下百度先生吧. 学习了一个新知识  FS增加录音功能如何去配置 一般电话系统都可以将本系统内的语音通话录制下来,FreeSwitch 系统中也可以进行语音录制. 需求: 录制系统中的所有通话. 实现: (1)建立一个文件夹 freeswitch/recordings/archive/ ,用来存储录

Android仿微信录音功能,自定义控件的设计技巧

欢迎各位加入我的Android开发群[257053751] 最近由于需要做一个录音功能(/嘘 悄悄透露一下,千万别告诉红薯,就是新版本的OSC客户端噢),起初打算采用仿微信的录音方式,最后又改成了QQ的录音方式,之前的微信录音控件也就白写了[大哭].之前有很多朋友在问我自定义控件应该怎么学习,遂正好拿出来讲讲喽,没来得及截效果图,大家就自己脑补一下微信发语音时的样子吧. 所谓自定义控件其实就是由于系统SDK无法完成需要的功能时,通过自己扩展系统组件达到完成所需功能做出的控件. Android自定

模仿微信语音聊天功能(3) 核心部分,录音功能的实现

在上一篇文章中,我们实现了按钮和对话框的交互.没有读的可以点击下面的链接查看: http://www.cnblogs.com/fuly550871915/p/4836108.html 在这一篇文章中,我们接着往下做,实现核心部分,即录音功能的实现.这里需要读者具备一定的MediaPlayer这个类的一些基础知识. 首先我们要在添加一下权限,切记,这个步骤千万不要忘记了.代码如下: 1 <uses-permission android:name="android.permission.REC

AndroidFM模块学习之录音功能

前些天分析了一下FM的流程以及主要类,接下来我们分析一下FM的录音功能: 首先看下流程图: Fm录音时,当点击了录音按钮,会发一个广播出去,源码在FMRadioService.java中 <span style="font-family:KaiTi_GB2312;font-size:18px;"> public void startRecording() { Log.d(LOGTAG, "In startRecording of Recorder");

PhoneGap录像 以及 录音功能 简单代码实现

1,录音功能 navigator.device.capture.captureAudio( function(files){//成功回调函数 Ext.getCmp("video_files_mainview").config.param.sourceobj.startUpload(files[0].fullPath, 2); }, function(error){//失败回调函数 // navigator.notification.alert('Error code: ' + erro

录音功能格式确认

音频格式测试 录音最终发布,需要确定一个格式统一的音频格式.参考了网上介绍. 一.iOS 录音功能支持格式主要的录音格式包括: (1)mp3: ios,android录制都 需要进行编码转换,使用lame第三方库,播放应该都可以直接播放 (2)iLBC:ios支持编码解码, android 低版本不支持,不过有开源第三方库,可以进行录制编码,播放解码的处理 (3)Speex:也是开源的第三方库,声称文件小,能降噪,需要ios,android客户端都进行编码解码处理 (4)amr:ios 4.3之

Android 能够暂停的录音功能

Android ApI提供了MediaRecorder和AudioRecord两个类给开发者来很方便地实现音视频的录制(前者可以实现音频和视频的录制,后者只能实 现音频的录制).这两个类都提供了start()和stop()方法用于开始和结束音频或视频的录制,但令人费解的是这两个类都没有提供pause()方 法用于暂停录制音视频,因为在实际应用当中,暂停录制的功能是非常有必要的Android 实现能够暂停的录音功能 需实现音频录制的暂停功能,并且生成的音频文件格式必须是m4a格式 为什么项目中音频