美文网首页
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