iOS录音及播放

昨天前端同事说要添加录音功能,需要原生这边支持,所以就百度了一下,记录了iOS录音功能的实现

录音

  1. 录音设置项
    NSDictionary *recordSettings = @{
        AVFormatIDKey: [NSNumber numberWithInt:kAudioFormatLinearPCM],//录音格式
        AVSampleRateKey: @(11025.0),//采样率
        AVNumberOfChannelsKey: @(2),//通道数
        AVLinearPCMBitDepthKey: @(16),//线性采样位数
        AVEncoderAudioQualityKey: @(AVAudioQualityMin)//音频质量,采样质量
    };
  1. 初始化录音器
    self.recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:self.recordFilePath] settings:recordSettings error:&error];
  1. 开始录音
    //启动或者恢复记录的录音文件
    [self.recorder prepareToRecord];
    [self.recorder record];
  1. 停止录音
    [self.recorder stop];
    self.recorder = nil;
  1. 格式转换
- (void)conventFileToMp3AtPath:(NSString *)path getFile:(GetRecordFile)getFile {
    //tmpUrl是caf文件的路径,并转换成字符串
    NSString *cafFilePath = path;
    //存储mp3文件的路径
    NSString *mp3FilePath = [NSString stringWithFormat:@"%@.mp3",[NSString stringWithFormat:@"%@",[cafFilePath substringToIndex:cafFilePath.length - 4]]];
    @try {
        int read, write;

        FILE *pcm = fopen([cafFilePath cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header
        FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb");  //output 输出生成的Mp3文件位置

        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        unsigned char mp3_buffer[MP3_SIZE];

        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 11025.0);
        lame_set_VBR(lame, vbr_default);
        lame_init_params(lame);

        do {
            read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
            if (read == 0)
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            else
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);

            fwrite(mp3_buffer, write, 1, mp3);

        } while (read != 0);

        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
        NSLog(@"转换成功");
    }
    @catch (NSException *exception) {
        NSLog(@"%@",[exception description]);
        
    }
    @finally {
        if (getFile) {
            getFile(mp3FilePath);
        }
    }
}

播放

  1. 初始化播放器
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:self.mp3FilePath] error:&error];
  1. 开始播放
    [self.player prepareToPlay];
    [self.player play];
  1. 停止播放
    [self.player stop];
    self.player = nil;

格式转换

使用AVAudioRecorder录音的文件是caf格式的,占用空间大,并且在其他设备上也不能播放,需要转成mp3格式。这里使用lame来进行音频格式转化

  1. 下载最新版lame,并解压
  2. 下载lame编译脚本,并解压,将.sh文件复制到lame的最外层目录里
  3. 修改脚本中的路径SOURCE="lame-3.100",运行脚本
  4. 直接运行脚本不成功,发现是xcode-select路径的问题,需要设置xcode-select路径,使用命令sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/,再次运行脚本即可

问题及解决

第一次录音只能录制4k左右就停止了,并且caf文件打不开,添加AVAudioSession在开始录音和结束录音时,切换session的状态,即可解决这个问题

参考

https://www.jianshu.com/p/c1bdab0ddf59
https://www.cnblogs.com/qqcc1388/p/11021870.html

原文地址:https://www.cnblogs.com/shenyuiOS/p/14186418.html