iOS录音和音频播放

21 篇文章 0 订阅

简介

  • 最近公司研发了一个语音识别的框架,但这个框架是后端识别,所以需要手机端录音,录音后将音频文件通转成NSData类型,然后通过bsae64转码传给后台进行语音识别,识别的文字再传回给前端,虽然我认为这样做体验并不好,毕竟请求是耗时的,并且iOS10以后,自带语音识别框架,但毕竟是公司研发的框架,所以就配合做了一下测试。
  • iOS录音和音频播放用到时AVFoundation.h框架中的,AVAudioRecorder类和AVAudioPlayer,其中AVAudioPlayer播放器只能播放本地音频文件,如果要在线播放需要用AVPlayer,其配合AVPlayerLayer类还可实现视频播放。另外支持播放进度监听。

AVAudioRecorder录音

  • AVAudioRecorder录音的主要步骤:
  1. 创建录音文件保存路径,并设置相关属性(是一个字典),然后实例化AVAudioRecorder录音对象,该对象必须是全局变量
  2. 使用AVAudioSession的单例对象(音频会话对象)来设置当前音频会话状态和会话类别。
  3. 录音对象设置开始录音,录音结束后会调用录音完成的代理方法。
  • 相关代码
//导入头文件
#import <AVFoundation/AVFoundation.h>
#import "GTMBase64.h"

@interface ViewController ()<AVAudioRecorderDelegate,AVAudioPlayerDelegate>{
    NSURL * recordUrl;
    AVAudioRecorder * audioRecorder;//必须为全局变量
    AVAudioPlayer * player;//必须为全局变量
    }


//开始录音
- (void)startRecord
{
    //删除上次生成的文件,保留最新文件
    NSFileManager *fileManager = [NSFileManager defaultManager];
    //默认就是wav格式,是无损的
    if ([fileManager fileExistsAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"recordAudio.wav"]]) {
        [fileManager removeItemAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"recordAudio.wav"] error:nil];
    }
    //录音设置
    NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
    //设置录音格式 AVFormatIDKey==kAudioFormatLinearPCM
    [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    //设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量), 采样率必须要设为11025才能使转化成mp3格式后不会失真
    [recordSetting setValue:[NSNumber numberWithFloat:16000] forKey:AVSampleRateKey];
    //录音通道数 1 或 2 ,要转换成mp3格式必须为双通道
    [recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    //线性采样位数 8、16、24、32
    [recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    //录音的质量
    [recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
    // 设置录制音频采用高位优先的记录格式
    [recordSetting setValue:[NSNumber numberWithBool:YES] forKey:AVLinearPCMIsBigEndianKey];
    // 设置采样信号采用浮点数
    [recordSetting setValue:[NSNumber numberWithBool:YES] forKey:AVLinearPCMIsFloatKey];
    //存储录音文件
    NSURL * recordUrl = [NSURL URLWithString:[NSTemporaryDirectory()stringByAppendingPathComponent:@"recordAudio.wav"]];
    //初始化录音对象
    NSError * error;
    audioRecorder = [[AVAudioRecorder alloc] initWithURL:recordUrl settings:recordSetting error:&error];
    if (error) {
        NSLog(@"%@",error.description);
        return;
    }
    audioRecorder.delegate = self;
    //开启音量检测
    audioRecorder.meteringEnabled = YES;
    AVAudioSession * audioSession = [AVAudioSession sharedInstance];//得到音频会话单例对象
    //如果不是正在录音
    if (![audioRecorder isRecording]) {
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];//设置类别,表示该应用同时支持播放和录音
        [audioSession setActive:YES error:nil];//激活当前应用的音频会话,此时会阻断后台音乐的播放.
        [audioRecorder prepareToRecord];//准备录音
        [audioRecorder record];//开始录音
        //暂停录音
//        [audioRecorder pause];
    }
}
 
 //结束录音
- (void)endRecord
{
    [audioRecorder stop];             //录音停止
}

//录音结束后代理
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
    [[AVAudioSession sharedInstance] setActive:NO error:nil];//一定要在录音停止以后再关闭音频会话管理(否则会报错),此时会延续后台音乐播放
    if (!flag) return;
    //请求接口传给后台
    [self postwavdata];
}

  • 注意:

    1. 录音时音频文件类型后缀必须为.caf、.aif、.wav中的一种,不能是.mp3,但播放是可以播放.mp3文件,可以导入githu上的一个C语言框架lame转成mp3音频文件。
    2. 将音频文件转成NSData然后用bsae64加密传给服务器,用系统自带的base64EncodedStringWithOptions编码方法后台可能解析有问题,主要是有空格和换行,可以多encode一次转义去掉这些特殊符号,也可以用第三方框架GTMBase64,请求数据时候requestContent-Type要设置为application/json,否则后台可能结束不到音频转码后端参数。
    //设置request的Content-Type为application/json
     [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    //转成base64编码格式上传服务器
    -(NSString *)wavToBASE64{
    NSData * wavData = [NSData dataWithContentsOfFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"recordAudio.wav"]];
    NSString * encodedImageStr = [GTMBase64 encodeBase64Data:wavData];
    }
    

AVAudioPlayer播放音频文件。

  • AVAudioPlayer播放音频文件主要步骤:
    1. 获取音频文件URL或者音频文件数据;
    2. 初始化AVAudioPlayer音频播放器全局对象
    3. 设置相关属性,并播放文件。
  • 相关代码
//开始播放音频文件
- (void)playWav{
//获取音频文件url
//   NSURL * url = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"recordAudio.wav"]];
//获取录音数据
NSData * wavData = [NSData dataWithContentsOfFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"recordAudio.wav"]];
NSError * error;
//    AVAudioPlayer * player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
   player = [[AVAudioPlayer alloc]initWithData:wavData error:&error];
   player.delegate = self;
   if (error) {
       NSLog(@"语音播放失败,%@",error);
       return;
   }
    //播放器的声音会自动切到receiver,所以听起来特别小,如果需要从speaker出声,需要自己设置。
   [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
   // 单独设置音乐的音量(默认1.0,可设置范围为0.0至1.0,两个极端为静音、系统音量):
   player.volume = 1.0;
//    修改左右声道的平衡(默认0.0,可设置范围为-1.0至1.0,两个极端分别为只有左声道、只有右声道):
   player.pan = -1;
//    设置播放速度(默认1.0,可设置范围为0.5至2.0,两个极端分别为一半速度、两倍速度):
   player.rate = 2.0;
//    设置循环播放(默认1,若设置值大于0,则为相应的循环次数,设置为-1可以实现无限循环):
   player.numberOfLoops = 0;
//    player.currentTime = 0;
   //调用prepareToPlay方法,这样可以提前获取需要的硬件支持,并加载音频到缓冲区。在调用play方法时,减少开始播放的延迟。
   [player prepareToPlay];
//    开始播放音乐:
   [player play];
   
   }
//播放完成代理
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
   if (flag) {
       NSLog(@"停止播放");
       //调用pause或stop来暂停播放,这里的stop方法的效果也只是暂停播放,不同之处是stop会撤销prepareToPlay方法所做的准备。
       [player stop];
       player = nil;
   }
}
  • 注意AVAudioRecorderAVAudioPlayerAVPlayerLayer一定要声明成全局变量,否则录音和播放都不能成功。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS 上,你可以使用 AVAudioRecorder 和 AVAudioPlayer 来同时进行录音播放。 首先,你需要创建一个 AVAudioRecorder 实例来录制音频。然后,你可以在录制音频的同时,创建一个 AVAudioPlayer 实例来播放音频。在录制和播放过程中,你需要将音频数据写入文件和缓存中。 以下是一个示例代码,展示了如何同时录制和播放音频: ```swift import AVFoundation class AudioController: NSObject, AVAudioRecorderDelegate { var recorder: AVAudioRecorder? var player: AVAudioPlayer? func startRecordingAndPlayback() { // 设置录音会话 let session = AVAudioSession.sharedInstance() try? session.setCategory(AVAudioSession.Category.playAndRecord, mode: .default, options: []) try? session.setActive(true) // 设置录音器 let settings: [String: Any] = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVSampleRateKey: 44100.0, AVNumberOfChannelsKey: 2, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue] let url = URL(fileURLWithPath: NSTemporaryDirectory() + "recording.m4a") recorder = try? AVAudioRecorder(url: url, settings: settings) recorder?.delegate = self recorder?.prepareToRecord() recorder?.record() // 设置播放器 let audioData = try? Data(contentsOf: url) player = try? AVAudioPlayer(data: audioData ?? Data()) player?.prepareToPlay() player?.play() } // AVAudioRecorderDelegate 方法 func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) { player?.stop() } } ``` 在这个示例中,我们首先设置了一个音频会话,然后创建了一个 AVAudioRecorder 实例来录制音频。同时,我们也创建了一个 AVAudioPlayer 实例来播放音频。最后,在录音完成后,我们停止了播放器。 你可以根据自己的需求进行更改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值