欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

ios 音频录音、上传至7牛、播放及其与android兼容的问题

发布时间:2023/12/31 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 ios 音频录音、上传至7牛、播放及其与android兼容的问题 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

iOS录音使用AVAudioRecorder,播放用 AVPlayer 就可以很好的解决,网上也有很多的教程。这里就不细讲,后面会附上代码。

先说一下demo内容,现在项目要求做一个录音、上传、播放的功能。细节:录音前需要提示音,录音时会有一个根据声音强度来展示的相应动态效果,还有个计时功能。

我们来说一下我在制作此功能时所遇到的坑!!

这里先呈现音频录制的代码,这里面引用了SpectrumView,点击打开链接。这是一个根据声强来显示声音录制的效果,如果不需要可以去除。

录制音频代码:

1.首先说一下录制音频的格式。

   经验证,这里博主建议各位使用AAC的录制格式。AAC(Advanced Audio Coding),中文称为“高级音频编码”,所占内存小,音质也不错,最重要的是可以与android兼容。


2.这里用的是7牛云的上传。这里我遇到的大问题就是上传音频到7牛云后,发现格式不能识别,显示为application/octet-stream。我最开始用.mp4的格式,的确上传上去后,能够识别为video/mp4,并且能正常播放。 但是后来发现不能播放android的录音。于是就想办法解决,经过一下午的各种博客浏览,。。。无果!! 好吧,最后想到先本地存储,再来播放的方式,解决问题。(这里的录音文件都比较小,不超过30s)


这里附上部分demo片段,有需要自取。

录音部分:#import "AudioRecorderVC.h" #import <AVFoundation/AVFoundation.h> #define kRecordAudioFile @"myRecord.aac"@interface AudioRecorderVC ()<AVAudioRecorderDelegate> @property (strong,nonatomic) SpectrumView *spectrumView; @property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音频录音机 @property (nonatomic, strong) AVAudioPlayer *bellplayer; @property (nonatomic, assign) int sCountup; @property (nonatomic, strong) NSTimer *mTimer; @end@implementation AudioRecorderVC#pragma mark - 控制器视图方法 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [self.naView setHidden:YES]; [self.statusTip setHidden:YES]; [self.view createBordersWithColor:[UIColor clearColor] withCornerRadius:6 andWidth:1]; [self.labReminder createBordersWithColor:[UIColor clearColor] withCornerRadius:4 andWidth:1]; [self.labReminder setTextColor:MCOLOR_FFFFFF]; [self addTapGesture]; [self addSpectrumView]; [self labToSize]; }-(void)addSpectrumView{ if (!self.spectrumView) { __weak AudioRecorderVC *weakSelf = self; self.spectrumView = [[SpectrumView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.bounds)-150,240,300, 60.0)]; self.spectrumView.hidden = YES; self.spectrumView.text = [NSString stringWithFormat:@"%d",0]; __weak SpectrumView * weakSpectrum = self.spectrumView; self.spectrumView.itemLevelCallback = ^() {[weakSelf.audioRecorder updateMeters]; //取得第一个通道的音频,音频强度范围是-160到0 float power= [weakSelf.audioRecorder averagePowerForChannel:0]; weakSpectrum.level = power; }; [self.view addSubview:self.spectrumView]; } }-(void)addTapGesture{ //添加手势 UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickPop)]; //将手势添加到需要相应的view中去 [self.view addGestureRecognizer:tapGesture]; }-(void)clickPop{ if (_Block) { _Block(nil); } }#pragma mark - getter 懒加载 - (UIButton *)btnRecorder { // 开始 [_btnRecorder addTarget:self action:@selector(recordStart:) forControlEvents:UIControlEventTouchDown]; // 取消 // [_btnRecorder addTarget:self action:@selector(recordCancel:) forControlEvents: UIControlEventTouchUpOutside]; //完成 [_btnRecorder addTarget:self action:@selector(recordFinish:) forControlEvents:UIControlEventTouchUpInside]; /* //移出 [_btnRecorder addTarget:self action:@selector(recordTouchDragExit:) forControlEvents:UIControlEventTouchDragExit]; //移入 [_btnRecorder addTarget:self action:@selector(recordTouchDragEnter:) forControlEvents:UIControlEventTouchDragEnter]; */ return _btnRecorder; }/** * 获得录音机对象 * * @return 录音机对象 */ - (AVAudioRecorder *)audioRecorder { if (!_audioRecorder) { [self setAudioSession]; //创建录音文件保存路径 NSURL *url=[self getSavePath]; //创建录音格式设置 NSDictionary *setting=[self getAudioSetting]; //创建录音机 NSError *error=nil; _audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error]; _audioRecorder.delegate= self; _audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES if (error) { NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription); return nil; } } return _audioRecorder; }#pragma mark - layout- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CGFloat width = self.view.bounds.size.width; CGFloat height = self.view.bounds.size.height; self.btnRecorder.frame = CGRectMake(width / 2.f - 50.f, height - 180.f, 100.f, 100.f); [self.audioRecorder record]; [self.audioRecorder stop]; [self removeFile]; }#pragma mark - ControlEvents /* - (void)recordCancel:(UIButton *)button {if ([self.audioRecorder isRecording]) { NSLog(@"取消"); [self.audioRecorder stop]; self.spectrumView.hidden = NO; } } */ - (void)recordStart:(UIButton *)button { if (![self.audioRecorder isRecording]) { NSLog(@"录音开始"); [self startScount]; [self playthebell]; [self.audioRecorder record]; [self startAnimate]; self.labReminder.hidden = YES; self.spectrumView.hidden = NO;} }- (void)recordFinish:(UIButton *)button {if ([self.audioRecorder isRecording]) { NSLog(@"完成"); [self.audioRecorder stop]; [self stopAnimate]; self.spectrumView.hidden = NO; [self judgePushAudio]; } } /* - (void)recordTouchDragExit:(UIButton *)button { if([self.audioRecorder isRecording]) { [self stopAnimate]; } }- (void)recordTouchDragEnter:(UIButton *)button { if([self.audioRecorder isRecording]) { [self startAnimate]; } } */ - (void)startAnimate { [self.spectrumView start]; }- (void)stopAnimate { [self.spectrumView stop]; [self.mTimer invalidate]; self.mTimer = nil; }- (void)setAudioSession { AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; //AVAudioSessionCategoryPlayAndRecord用于录音和播放 [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError]; if(session == nil) NSLog(@"Error creating session: %@", [sessionError description]); else [session setActive:YES error:nil]; }/** * 取得录音文件设置 * * @return 录音设置 */ - (NSDictionary *)getAudioSetting { NSMutableDictionary *dicM=[NSMutableDictionary dictionary]; //设置录音格式 [dicM setObject:@(kAudioFormatMPEG4AAC) forKey:AVFormatIDKey]; //设置录音采样率,8000是电话采样率,对于一般录音已经够了 [dicM setObject:@(8000) forKey:AVSampleRateKey]; //设置通道,这里采用单声道 [dicM setObject:@(1) forKey:AVNumberOfChannelsKey]; //每个采样点位数,分为8、16、24、32 [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey]; //是否使用浮点数采样 [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; //....其他设置等return dicM; }/** * 取得录音文件保存路径 * * @return 录音文件路径 */ - (NSURL *)getSavePath {// 在Documents目录下创建一个名为FileData的文件夹 NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioData"]; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir = FALSE; BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir]; if(!(isDirExist && isDir)) { BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil]; if(!bCreateDir){ NSLog(@"创建文件夹失败!"); } NSLog(@"创建文件夹成功,文件路径%@",path); } path = [path stringByAppendingPathComponent:kRecordAudioFile]; NSLog(@"file path:%@",path); NSURL *url=[NSURL fileURLWithPath:path];return url; }- (void)removeFile{ NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioData"]; NSFileManager *fileManager = [NSFileManager defaultManager]; path = [path stringByAppendingPathComponent:kRecordAudioFile]; NSError *error; if ([fileManager removeItemAtPath:path error:&error] != YES) NSLog(@"Unable to delete file: %@", [error localizedDescription]);}- (void)judgePushAudio{ if (_sCountup < 1) { [self showToast:@"录音时间太短,请重试!"]; [self removeFile];}else if(_sCountup >= 1 && _sCountup <= 30){ if (_Block) { _Block([self getSavePath]); } } }- (void)labToSize{ NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:self.labReminder.text]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineSpacing:20.0f];//调整行间距 [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [self.labReminder.text length])]; self.labReminder.attributedText = attributedString; [self.labReminder sizeToFit]; }#pragma --提示音 - (void)playthebell{ NSString *mp3Str; mp3Str = @"talkroom_begin"; NSString *filePath = [[NSBundle mainBundle] pathForResource:mp3Str ofType:@"mp3"]; self.bellplayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:nil]; self.bellplayer.volume = 1.0; self.bellplayer.numberOfLoops = -1; [self.bellplayer prepareToPlay]; [self.bellplayer play]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, ( 0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.bellplayer stop]; }); }#pragma --计时器 - (void)startScount{ self.sCountup = 0; [UIView animateWithDuration:0.5 animations:^{ self.mTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startCountUp) userInfo:nil repeats:YES]; }]; }- (void)startCountUp{ _sCountup++; self.spectrumView.timeLabel.text = [NSString stringWithFormat:@"%ds", _sCountup]; if (_sCountup == 30) { [self recordFinish:nil]; } }@end
3 #pragma --播放录音 - (void)addVoiceButton:(DoorVoucherCell *)cell{UIButton *voiceBtn = [[UIButton alloc]initWithFrame:CGRectMake(cell.contentValue.left, 0, 150, 50)];[voiceBtn addTarget:self action:@selector(playRecoderVoice) forControlEvents:UIControlEventTouchUpInside];voice = [[UIImageView alloc]initWithFrame:CGRectMake(0, 12, 25, 25)];//动画未开始前的图片voice.image = [UIImage imageNamed:@"chat_animation_white3"];//进行动画效果的3张图片(按照播放顺序放置)voice.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"chat_animation_white1"],[UIImage imageNamed:@"chat_animation_white2"],[UIImage imageNamed:@"chat_animation_white3"],nil];//设置动画间隔voice.animationDuration = 1;voice.animationRepeatCount = 0;voice.userInteractionEnabled = NO;voice.backgroundColor = [UIColor clearColor];[voiceBtn addSubview:voice];[cell addSubview:voiceBtn]; }- (NSURL *)writeRecoderToFile{//播放NSURL *url = [NSURL URLWithString:self.dataModel.voice];//把音频文件保存到本地NSData *audioData = [NSData dataWithContentsOfURL:url];NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioData"];path = [path stringByAppendingPathComponent:@"myRecord.aac"];// DDLogWarn(@" 从网络拿到的音频数据写入的本地路径 %@",filePath);[audioData writeToFile:path atomically:YES];NSURL *fileURL = [NSURL fileURLWithPath:path];return fileURL; }- (void)playRecoderVoice{[self setAudioPlayer];[self.audioPlayer play];dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{[voice startAnimating];}); }- (void)playerItemDidReachEnd{[self playthebell];[voice stopAnimating];voice.image = [UIImage imageNamed:@"chat_animation_white3"]; }- (AVPlayer *)setAudioPlayer{NSError *error=nil;AVPlayerItem * songItem = [[AVPlayerItem alloc]initWithURL:[self writeRecoderToFile]];AVAudioSession *session = [AVAudioSession sharedInstance];[session setActive:YES error:nil];[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];[session setCategory:AVAudioSessionCategoryPlayback error:nil];_audioPlayer = [[AVPlayer alloc] initWithPlayerItem:songItem];// 监听音乐是否播放完成[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(playerItemDidReachEnd)name:AVPlayerItemDidPlayToEndTimeNotificationobject:nil];if (error) {NSLog(@"创建播放器过程中发生错误,错误信息:%@",error.localizedDescription);return nil;}return _audioPlayer; }#pragma --提示音 - (void)playthebell{NSString *mp3Str;mp3Str = @"talkroom_up";NSString *filePath = [[NSBundle mainBundle] pathForResource:mp3Str ofType:@"mp3"];self.bellplayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:nil];self.bellplayer.volume = 1.0;self.bellplayer.numberOfLoops = -1;[self.bellplayer prepareToPlay];[self.bellplayer play];dispatch_after(dispatch_time(DISPATCH_TIME_NOW, ( 0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{[self.bellplayer stop];}); }





有问题欢迎提问,喜欢请点赞,Star。谢谢。

总结

以上是生活随笔为你收集整理的ios 音频录音、上传至7牛、播放及其与android兼容的问题的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。