美文网首页
iOS(最新)录音,播放,上传至服务器,格式转MP3

iOS(最新)录音,播放,上传至服务器,格式转MP3

作者: iOS刘耀宗 | 来源:发表于2018-10-31 11:19 被阅读37次
  承接APP,小程序,公众号开发. 性价比高.+V信:17723566468    有单子的也可找我一起开发哦!        在很多地方用到语音功能. 网上千篇一律的文章针对录音以及播放.录音以及播放在此不做重点讲解(后面贴有代码).主要是将录音文件格式转成MP3上传到服务器,然后拿到地址播放. 代码将贴在最后,大家直接复制粘贴即可使用. 亲测有效: 
拿到录音文件之后如何转换成MP3. 在收集相关资料之后发现现在都是用一个库就是lame
这是编译[lame](https://www.jianshu.com/p/ef5192f41de8)库详解文章
上面这边文章并没有讲解如何进行编译.很简单最后只需要将脚本文件拖拉至终端后即可.

编译出来之后将下面两个文件拖拉至项目中


Snip20181031_1.png
//将语音格式转换成MP3 
 - (void)transformCAFToMP3 {
 NSURL *   mp3FilePath = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"myselfRecord.mp3"]];
    @try {
         int read, write;

         FILE *pcm = fopen([[self.recordFileUrl absoluteString] cStringUsingEncoding:1], "rb");   //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                                   //skip file header
         FILE *mp3 = fopen([[mp3FilePath absoluteString] 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 = (int)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);
    }
    @catch (NSException *exception) {
         NSLog(@"%@",[exception description]);
     }
     @finally {
        NSLog(@"MP3生成成功");
//       base64Str = [self mp3ToBASE64];
         NSData *mp3Data = [NSData dataWithContentsOfFile:[NSTemporaryDirectory() stringByAppendingString:@"myselfRecord.mp3"]];
         [[YGDZViewModel shareViewModel] updateVoice:mp3Data Success:^(NSDictionary *resDic) {
             NSLog(@"当前的数据是%@",resDic);
             self.voiceUrlStr=resDic[@"URL"];
         }];
         
    }
 }

//上传语音的方法 其实就是上传一个文件, 替换一下上传地址即可
-(void)updateVoice:(NSData  *)data Success:(void (^)(NSDictionary *resDic))success
{

    YGDZUserInfoModel *model=[YGDZUserInfoModel getUseData];
    NSString *tempUrl = [NSString  stringWithFormat:@"%@api/Doc/Upload/UserPost/%@/0/%@/0/1",uploadFlsq,model.UserCode,model.OrgID];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager POST:tempUrl parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        
        [formData appendPartWithFileData:data name:@"file" fileName:@"Mp3File.mp3"mimeType:@"mp3"];
        
    }progress:^(NSProgress * _Nonnull uploadProgress) {
        
    }success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSError *errorJSON = [[NSError alloc] init];
        NSDictionary *tempDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&errorJSON];
        NSLog(@"responseObject=%@",tempDict);
        [SVProgressHUD dismiss];
        BOOL result = YES;
        if(tempDict){
            NSInteger Status = [[tempDict objectForKey:@"Status"] integerValue];
            if(Status == 1){
                NSString *tempUrl = [tempDict objectForKey:@"URL"];
                success(tempDict);
            }else
            {
             //失败处理
            }
        }
    }failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    }];
}

亲测有效.
//完整代码 直接复制粘贴即可.拉入项目即可使用.
.h文件


//
//  YGDZVoiceTool.h
//  gjpt
//
//  Created by 刘耀宗 on 2018/10/19.
//  Copyright © 2018年 CQYGKJ. All rights reserved.
//

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

@interface YGDZVoiceTool : NSObject
+(instancetype)shareViewModel;
@property (nonatomic, strong) AVAudioSession *session;
@property (nonatomic, strong) AVAudioRecorder *recorder;//录音器
@property (nonatomic, strong) AVAudioPlayer *player; //播放器
@property (nonatomic, strong) NSURL *recordFileUrl; //文件地址
@property (nonatomic, strong) NSString *voiceUrlStr; //文件地址

//开始录音
- (void)startRecordNew;
//停止录音
- (void)endRecord;
- (void)PlayRecord;//播放录音


@end

NS_ASSUME_NONNULL_END

.m文件




//
//  YGDZVoiceTool.m
//  gjpt
//
//  Created by 刘耀宗 on 2018/10/19.
//  Copyright © 2018年 CQYGKJ. All rights reserved.
//

#import "YGDZVoiceTool.h"
#import <AVFoundation/AVFoundation.h>
#import "lame.h"
@interface YGDZVoiceTool (){
    
    NSTimer *_timer; //定时器
    NSInteger countDown;  //倒计时
    NSString *filePath;
    UIButton*                       _playBtn;
    UIButton*                       _encodeBtn;
    UIButton*                       _recordBtn;
    UIButton*                       _playMp3Btn;
    
    UILabel*                        _cafFileSize;
    UILabel*                        _mp3FileSize;
    UILabel*                        _duration;
    UILabel*                        _format;
    
    UISegmentedControl*             _sampleRateSegment;
    UISegmentedControl*             _qualityRateSegment;
    
    UIPickerView*                   _picker;
    
    AVAudioRecorder*                _recorder;
    AVAudioPlayer*                  _player;
    AVAudioPlayer*                  _mp3Player;
    
    UIProgressView*                 _progress;
    UIProgressView*                 _mp3Progress;
    
    BOOL                            _hasCAFFile;
    BOOL                            _recording;
    BOOL                            _playing;
    BOOL                            _hasMp3File;
    BOOL                            _playingMp3;
    
    NSURL*                          _recordedFile;
    CGFloat                         _sampleRate;
    AVAudioQuality                  _quality;
    NSInteger                       _formatIndex;
    UIAlertView*                    _alert;
    NSDate*                         _startDate;
    
    
}
@property (nonatomic, strong)  UILabel*             cafFileSize;
@property (nonatomic, strong)  UILabel*             mp3FileSize;
@property (nonatomic, strong)  UILabel*             duration;
@property (nonatomic, strong)  UILabel*             format;
@property (nonatomic, strong)  UIButton*            recordBtn;
@property (nonatomic, strong)  UIButton*            playBtn;
@property (nonatomic, strong)  UIButton*            encodeBtn;
@property (nonatomic, strong)  UIButton*            playMp3Btn;
@property (nonatomic, strong)  UISegmentedControl*  sampleRateSegment;
@property (nonatomic, strong)  UISegmentedControl*  qualityRateSegment;
@property (nonatomic, strong)  UIProgressView*      progress;
@property (nonatomic, strong)  UIProgressView*      mp3Progress;
@property (nonatomic, copy) NSString *filePath;
@property (nonatomic, strong) AVAudioSession*    audioSession ;


@end
@implementation YGDZVoiceTool
+(instancetype)shareViewModel{
    static id instance;
    static  dispatch_once_t once;
    dispatch_once(&once, ^{
        instance=[[self alloc] init];
    });
    return instance;
    
}
- (void)PlayRecord {
    
    NSLog(@"播放录音");
    [self.recorder stop];
    
    if ([self.player isPlaying])return;
    
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.recordFileUrl error:nil];
    NSLog(@"%li",self.player.data.length/1024);
    //放外音
    [self.session setCategory:AVAudioSessionCategoryPlayback error:nil];
    [self.session setActive:YES error:nil];
    [self.player play];
    
}
//开始录音
- (void)startRecordNew
{
     //删除上次生成的文件,保留最新文件
     NSFileManager *fileManager = [NSFileManager defaultManager];
      if ([NSTemporaryDirectory() stringByAppendingString:@"myselfRecord.mp3"]) {
          [fileManager removeItemAtPath:[NSTemporaryDirectory() stringByAppendingString:@"myselfRecord.mp3"] error:nil];
          }
     if ([NSTemporaryDirectory() stringByAppendingString:@"selfRecord.wav"]) {
           [fileManager removeItemAtPath:[NSTemporaryDirectory() stringByAppendingString:@"selfRecord.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:11025.0] 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];
 
     //存储录音文件
    self.recordFileUrl = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"selfRecord.wav"]];

    //初始化
_recorder = [[AVAudioRecorder alloc] initWithURL:self.recordFileUrl settings:recordSetting error:nil];
       //开启音量检测
      _recorder.meteringEnabled = YES;
  _audioSession = [AVAudioSession sharedInstance];//得到AVAudioSession单例对象
 
     if (![_recorder isRecording]) {
        [_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];//设置类别,表示该应用同时支持播放和录音
          [_audioSession setActive:YES error:nil];//启动音频会话管理,此时会阻断后台音乐的播放.

       [_recorder prepareToRecord];
        [_recorder peakPowerForChannel:0.0];
        [_recorder record];
     }
 }

//停止录音
- (void)endRecord
 {
     [_recorder stop];
//     AVAudioSession *session = [AVAudioSession sharedInstance];
     [_audioSession setCategory:AVAudioSessionCategoryPlayback error:NULL];
     [_audioSession setActive:YES error:NULL];

//     [_audioSession setActive:NO error:nil];         //一定要在录音停止以后再关闭音频会话管理(否则会报错),此时会延续后台音乐播放
     [self.session setCategory:AVAudioSessionCategoryPlayback error:nil];  //此处需要恢复设置回放标志,否则会导致其它播放声音也会变小
     [self transformCAFToMP3];
 }



- (void)transformCAFToMP3 {
 NSURL *   mp3FilePath = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"myselfRecord.mp3"]];

    @try {
         int read, write;

         FILE *pcm = fopen([[self.recordFileUrl absoluteString] cStringUsingEncoding:1], "rb");   //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                                   //skip file header
         FILE *mp3 = fopen([[mp3FilePath absoluteString] 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 = (int)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);
    }
    @catch (NSException *exception) {
         NSLog(@"%@",[exception description]);
     }
     @finally {
        NSLog(@"MP3生成成功");
//       base64Str = [self mp3ToBASE64];
         
         NSData *mp3Data = [NSData dataWithContentsOfFile:[NSTemporaryDirectory() stringByAppendingString:@"myselfRecord.mp3"]];
         [[YGDZViewModel shareViewModel] updateVoice:mp3Data Success:^(NSDictionary *resDic) {
             NSLog(@"当前的数据是%@",resDic);
             self.voiceUrlStr=resDic[@"URL"];
             
             
         }];
         
    }
 }

@end


相关文章

网友评论

      本文标题:iOS(最新)录音,播放,上传至服务器,格式转MP3

      本文链接:https://www.haomeiwen.com/subject/yewotqtx.html