iOS录音wav caf 及mp3转码 音频的曲线
来源:互联网 发布:小米手机远程擦除数据 编辑:程序博客网 时间:2024/04/30 21:34
一 : 定义一个全局变量AVAudioRecorder的录音对象,并启动录音
- PCM格式设置如下:
//设置属性的字典recordSetting = [[NSMutableDictionary alloc] init];//1.格式 [recordSetting setObject:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey]; //2.采样率 [recordSetting setObject:[NSNumber numberWithInt:1600] forKey:AVSampleRateKey]; //3.声道 要转换mp3格式声道就必须设置为2 [recordSetting setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey]; //4.采样位数 [recordSetting setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
非PCM格式 比如IMA4
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey]; [recordSetting setValue:[NSNumber numberWithFloat:1600.0] forKey:AVSampleRateKey]; [recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
2.设置路径及其url,并清除上一次缓存录音文件,录取新的文件
NSString *recprderPath = [NSHomeDirectory() stringByAppendingPathComponent:@"recorder.wav"];//路劲另一个方法:[NSString stringWithFormat:@"%@/Documents/MySound.caf", NSHomeDirectory()]];}NSURL *url = [NSURL fileURLWithPath:recprderPath];NSError *err = nil; err = nil; //从路径下检查是否有文件 NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err]; if(audioData) { //如果有使用文件管理移除上一次录音文件 NSFileManager *fm = [NSFileManager defaultManager]; [fm removeItemAtPath:[url path] error:&err]; } err = nil;//用字典定义的属性配置录音(初始化) recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];//如果录音配置失败 if(!recorder){ //打印错误信息 NSLog(@"recorder: %@ %ld %@", [err domain], [err code], [[err userInfo] description]); UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"Warning" message: [err localizedDescription] delegate: nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; return; } [recorder setDelegate:self];//设置代理 [recorder prepareToRecord];//准备录音 recorder.meteringEnabled = YES;//开启音量检测 [recorder recordForDuration:(NSTimeInterval) 180.0];//录音有效时长//设置定时器,每0.05秒调用updateMeters的方法画出音频曲线timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(updateMeters) userInfo:nil repeats:YES];//这里的updateMeters是重写父类方法
二 : 关于定时器启动 以及音频曲线
1. 写父类方法 获得当前音频功率值,调用averagePowerForChannel之前你必须调用这个方法- (void)updateMeters { [recorder updateMeters];//如果录音的分贝小于-60并且时间超过180秒提交录音 if (([recorder averagePowerForChannel:0] < -60.0) && (recordTime > 180.0)) { [self commitRecording]; return; } recordTime += 0.05;//和定时器时间一样 [self addSoundMeterItem:[recorder averagePowerForChannel:0]];}2. Sound meter operations//定义一个宏和soundMeters[i]数值要一样#define SOUND_METER_COUNT 40- (void)shiftSoundMeterLeft { for(int i=0; i<SOUND_METER_COUNT - 1; i++) { soundMeters[i] = soundMeters[i+1]; }}- (void)addSoundMeterItem:(int)lastValue { [self shiftSoundMeterLeft]; [self shiftSoundMeterLeft]; soundMeters[SOUND_METER_COUNT - 1] = lastValue; soundMeters[SOUND_METER_COUNT - 2] = lastValue; [self setNeedsDisplay];}3. 设置取消按钮,即图中的标注中,以及其方法#define HUD_SIZE 220#define CANCEL_BUTTON_HEIGHT 40 //麦克风位置 CGRect hudRect; hudRect = CGRectMake(self.center.x - (HUD_SIZE / 2), self.center.y - (HUD_SIZE / 2) - 20, HUD_SIZE, HUD_SIZE); int x = (frame.size.width - HUD_SIZE) / 2; btnCancel = [[UIButton alloc] initWithFrame:CGRectMake(x, hudRect.origin.y + HUD_SIZE - CANCEL_BUTTON_HEIGHT, HUD_SIZE, CANCEL_BUTTON_HEIGHT)]; [btnCancel setTitle:NSLocalizedString(@"标注中", nil) forState:UIControlStateNormal]; [btnCancel addTarget:self action:@selector(cancelled:) forControlEvents:UIControlEventTouchUpInside]; btnCancel.enabled = NO; [self addSubview:btnCancel];//取消按钮点击事件- (void)cancelled:(id)sender { self.alpha = 0.0; [self setNeedsDisplay]; [timer invalidate]; [self cancelRecording];}//取消事件- (void)cancelRecording { //配合代理使用事件 if ([self.delegate respondsToSelector:@selector(voiceRecordCancelledByUser:)]) { [self.delegate voiceRecordCancelledByUser:self]; } [recorder stop];}4. 画出录音曲线 以及 - (void)drawRect:(CGRect)rect { CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = UIGraphicsGetCurrentContext();//上下文 UIColor *strokeColor = [UIColor colorWithRed:0.886 green:0.0 blue:0.0 alpha:0.8]; UIColor *fillColor = [UIColor colorWithRed:0.5827 green:0.5827 blue:0.5827 alpha:1.0]; UIColor *gradientColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8]; UIColor *color = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; NSArray *gradientColors = [NSArray arrayWithObjects: (id)fillColor.CGColor, (id)gradientColor.CGColor, nil]; CGFloat gradientLocations[] = {0, 1}; CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations); UIBezierPath *border = [UIBezierPath bezierPathWithRoundedRect:hudRect cornerRadius:10.0]; CGContextSaveGState(context); [border addClip]; CGContextDrawRadialGradient(context, gradient, CGPointMake(hudRect.origin.x+HUD_SIZE/2, 120), 10, CGPointMake(hudRect.origin.x+HUD_SIZE/2, 195), 215, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); CGContextRestoreGState(context); [strokeColor setStroke]; border.lineWidth = 3.0; [border stroke]; // 画出音频波浪 [[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.4] set]; CGContextSetLineWidth(context, 3.0); CGContextSetLineJoin(context, kCGLineJoinRound); int baseLine = 250;//不同的机型 定义不一样 距离screen上端距离可能是310mm int multiplier = 1; int maxLengthOfWave = 50; int maxValueOfMeter = 70; for(CGFloat x = SOUND_METER_COUNT - 1; x >= 0; x--) { multiplier = ((int)x % 2) == 0 ? 1 : -1; CGFloat y = baseLine + ((maxValueOfMeter * (maxLengthOfWave - abs(soundMeters[(int)x]))) / maxLengthOfWave) * multiplier; if(x == SOUND_METER_COUNT - 1) { CGContextMoveToPoint(context, x * (HUD_SIZE / SOUND_METER_COUNT) + hudRect.origin.x + 10, y); CGContextAddLineToPoint(context, x * (HUD_SIZE / SOUND_METER_COUNT) + hudRect.origin.x + 7, y); } else { CGContextAddLineToPoint(context, x * (HUD_SIZE / SOUND_METER_COUNT) + hudRect.origin.x + 10, y); CGContextAddLineToPoint(context, x * (HUD_SIZE / SOUND_METER_COUNT) + hudRect.origin.x + 7, y); } } CGContextStrokePath(context); // 画出标题 即图中大字标注中 [color setFill]; [self.title drawInRect:CGRectInset(hudRect, 0, 20) withFont:[UIFont systemFontOfSize:30.0] lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter];//标题的位置文字大小 等等 [imgMicrophone drawAtPoint:CGPointMake(hudRect.origin.x + hudRect.size.width/2 - imgMicrophone.size.width/2, hudRect.origin.y + hudRect.size.height/2 - imgMicrophone.size.height/2)]; [[UIColor colorWithWhite:0.8 alpha:1.0] setFill]; UIBezierPath *line = [UIBezierPath bezierPath]; [line moveToPoint:CGPointMake(hudRect.origin.x, hudRect.origin.y + HUD_SIZE - CANCEL_BUTTON_HEIGHT)]; [line addLineToPoint:CGPointMake(hudRect.origin.x + HUD_SIZE, hudRect.origin.y + HUD_SIZE - CANCEL_BUTTON_HEIGHT)]; [line setLineWidth:3.0]; [line stroke];}
三 : 录音完成之后 开始转码 mp3
//导入头文件lame.h和其静态库- (BOOL)audio_PCMtoMP3{ NSString *mp3FilePath = [NSHomeDirectory() stringByAppendingPathComponent:@"mp3FilePath.mp3"]; mp3Path = mp3FilePath; NSFileManager * fileManager=[ NSFileManager defaultManager ]; if ([fileManager removeItemAtPath :mp3FilePath error : nil ]) { NSLog ( @" 删除 " ); } @try { int read, write; FILE *pcm = fopen ([recorderFilePath cStringUsingEncoding : 1 ], "rb" ); //source 被 转换的音频文件位置 if (pcm == NULL ) { NSLog ( @"file not found" ); } else { 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_num_channels (lame, 1 ); // 设置 1 为单通道,默认为 2 双通道 lame_set_in_samplerate (lame, 1600.0 ); //11025.0取频 采样 //lame_set_VBR(lame, vbr_default); lame_set_brate (lame, 8 ); lame_set_mode (lame, 3 ); lame_set_quality (lame, 2 ); /* 2=high 5 = medium 7=low 音 质 */ 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);//释放lame fclose (mp3); fclose (pcm); return YES ; } return NO ; } @catch (NSException *exception) { NSLog ( @"%@" ,[exception description ]); return NO ; } @finally { NSLog ( @" 转码执行完成 " ); }}
0 0
- iOS录音wav caf 及mp3转码 音频的曲线
- iOS录音后的.caf格式转MP3格式
- iOS利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- ios 录音使用lame.h转化caf为mp3
- ios自带录音格式(caf)转MP3格式
- iPhone convert mp3 to wav or caf
- Elastix 录音wav转MP3
- iOS 录音Wav 音频 转换 Amr ,Android 播放
- iOS 录音Wav 音频 转换 Amr ,Android 播放
- iOS 录音Wav 音频 转换 Amr ,Android 播放
- 录音播放系统(实现pcm转码mp3,wav)
- iphone利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- iphone利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- iphone利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- 利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- iphone利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- iphone利用AudioQueue播放音频文件(mp3,aac,caf,wav等)
- 关于Wav音频压缩MP3
- Android 避免APP启动闪黑屏的解决办法(Theme和Style)
- matlab中的一些函数(上)使用格式
- 《netty权威指南》12 UDP协议开发
- ios存储加密信息-GSkeychain使用
- 花18万元脸部整形后不满意 事主诉退一赔三被驳
- iOS录音wav caf 及mp3转码 音频的曲线
- usb_modeswitch使用详解(翻译)
- 为ListView加入点击和长按响应
- 北京2女司机相撞 互呛对方:你全家都是女司机
- 动态给TextView的背景赋值图片
- activity 启动白屏黑屏问题
- 《netty权威指南》13文件传输
- GEM5: Different cache latency for read and write access 设置不同的读写latency
- 浅谈策略模式(strategy)