日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/31 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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兼容的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。