录制wav格式的音频
项目中有面部认证、声纹认证,服务器端要求上传wav格式的音频,所以写了这样一个小demo。
刚刚开始写博客还不知道怎么上传代码,就复制了,嘻嘻
DotimeManage.h
@class DotimeManage;
@protocol DotimeManageDelegate <NSObject>
- (void)TimerActionValueChange:(int)time; //时间改变
@end
#import <Foundation/Foundation.h>
@interface DotimeManage : NSObject
{
NSTimer *BBtimer;
}
@property (nonatomic)int timeValue;
@property (nonatomic,assign)id<DotimeManageDelegate> delegate;
+ (DotimeManage *)DefaultManage;
//开始计时
- (void)startTime;
//停止计时
- (void)stopTimer;
@end
DotimeManage.m
#import "DotimeManage.h"
@implementation DotimeManage
static DotimeManage *timeManage = nil;
+ (DotimeManage *)DefaultManage{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
timeManage = [[DotimeManage alloc] init];
});
return timeManage;
}
- (id)init {
self = [super init];
if (self) {
}
return self;
}
//开始计时
- (void)startTime {
//停止上次计时器
[self stopTimer];
if (BBtimer == nil) {
self.timeValue = 0;
BBtimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(TimerAction) userInfo:nil repeats:YES];
NSRunLoop *main=[NSRunLoop currentRunLoop];
[main addTimer:BBtimer forMode:NSRunLoopCommonModes];
}
}
//停止计时
- (void)stopTimer {
if (BBtimer != nil) {
[BBtimer invalidate];
BBtimer = nil;
}
}
//倒计时
- (void)TimerAction {
self.timeValue ++;
if ([self.delegate respondsToSelector:@selector(TimerActionValueChange:)]) {
[self.delegate TimerActionValueChange:self.timeValue];
}
}
@end
Recorder.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <UIKit/UIKit.h>
#define DefaultSubPath @"Voice" //默认 二级目录 可以修改自己想要的 例如 "文件夹1/文件夹2/文件夹3"
#define SampleRateKey 44100.0 //采样率8000.0
#define LinearPCMBitDepth 16 //采样位数 默认 16
#define NumberOfChannels 1 //通道的数目
@protocol RecorderDelegate <NSObject>
/**
* 录音进行中
* currentTime 录音时长
**/
-(void)recorderCurrentTime:(NSTimeInterval)currentTime;
/**
* 录音完成
* filePath 录音文件保存路径
* fileName 录音文件名
* duration 录音时长
**/
-(void)recorderStop:(NSString *)filePath voiceName:(NSString *)fileName duration:(NSTimeInterval)duration;
/**
* 开始录音
**/
-(void)recorderStart;
@end
@interface Recorder : NSObject<AVAudioRecorderDelegate>
@property (assign, nonatomic) id<RecorderDelegate> recorderDelegate;
@property(strong, nonatomic) NSString *filename,*filePath;
/**
* 录音控件 单例对象
**/
+(Recorder *)shareRecorder;
/**
* 开始录音
* //默认的录音存储的文件夹在 "Document/Voice/文件名(文件名示例: 2015-01-06_12:41).wav"
* 录音的文件名 "2015-01-06_12:41"
**/
-(void)startRecord;
/**
* 停止录音
**/
-(void)stopRecord;
/**
* 获得峰值
**/
-(float)getPeakPower;
/**
* 是否可以录音
**/
- (BOOL)canRecord;
@end
Recorder.m
#import "Recorder.h"
#ifdef DEBUG
#define VSLog(log, ...) NSLog(log, ## __VA_ARGS__)
#else
#define VSLog(log, ...)
#endif
#define IOS7 ( [[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending )
@interface Recorder ()
{
NSMutableArray *cacheDelegates;
NSMutableArray *cacheURLs;
NSTimer *countDownTimer_;//定时器,每秒调用一次
}
@property(strong, nonatomic) AVAudioRecorder *audioRecorder;
@property(strong, nonatomic) NSMutableDictionary *cacheDic;
@end
@implementation Recorder
+(Recorder *)shareRecorder
{
static Recorder *sharedRecorderInstance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedRecorderInstance = [[self alloc] init];
});
return sharedRecorderInstance;
}
-(BOOL)canRecord
{
__block BOOL bCanRecord = YES;
if (IOS7)
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
[audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
if (granted) {
bCanRecord = YES;
} else {
bCanRecord = NO;
}
}];
}
}
return bCanRecord;
}
-(id)init
{
self = [super init];
if (self) {
self.cacheDic = [NSMutableDictionary dictionaryWithCapacity:1];
cacheDelegates = [[NSMutableArray alloc] init];
cacheURLs = [[NSMutableArray alloc] init];
[self resetTimerCount];
}
return self;
}
-(void)stopTimerCountRun
{
if (countDownTimer_) {
[countDownTimer_ invalidate];
countDownTimer_ = nil;
}
}
-(void)resetTimerCount
{
[self stopTimerCountRun];
countDownTimer_ = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeCountDown) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:countDownTimer_ forMode:NSRunLoopCommonModes];
}
- (void)timeCountDown
{
if (self.audioRecorder.isRecording) {
//当前时间
if ([self.recorderDelegate respondsToSelector:@selector(recorderCurrentTime:)]) {
[self.recorderDelegate recorderCurrentTime:self.audioRecorder.currentTime];
}
}
}
#pragma mark - 广播停止录音
//停止录音
-(void)stopAVAudioRecord
{
}
-(void)startRecordWithFilePath:(NSString *)filePath
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[session setActive:YES error:nil];
NSDictionary *recordSetting = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat: SampleRateKey],AVSampleRateKey, //采样率
[NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumber numberWithInt:LinearPCMBitDepth],AVLinearPCMBitDepthKey,//采样位数 默认 16
[NSNumber numberWithInt: NumberOfChannels], AVNumberOfChannelsKey,//通道的数目,
nil];
NSURL *url = [NSURL fileURLWithPath:filePath];
self.filePath = filePath;
NSError *error = nil;
if (self.audioRecorder) {
if (self.audioRecorder.isRecording) {
[self.audioRecorder stop];
}
self.audioRecorder = nil;
}
AVAudioRecorder *tmpRecord = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&error];
self.audioRecorder = tmpRecord;
self.audioRecorder.meteringEnabled = YES;
self.audioRecorder.delegate = self;
if ([self.audioRecorder prepareToRecord] == YES){
self.audioRecorder.meteringEnabled = YES;
[self.audioRecorder record];
if ([self.recorderDelegate respondsToSelector:@selector(recorderStart)]) {
[self.recorderDelegate recorderStart];
}
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];//保持屏幕长亮
[[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; //建议在播放之前设置yes,播放结束设置NO,这个功能是开启红外感应
}else {
int errorCode = CFSwapInt32HostToBig ([error code]);
VSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode);
}
}
-(void)startRecord
{
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
//录音文件名采用时间标记 例如"2015-01-06_12:41"
// self.filename = [self createFilename];
self.filename = @"RecordingFile";
NSString *soundFilePath = [docsDir
stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@.wav",DefaultSubPath,self.filename]];
[self createFilePath];
[self startRecordWithFilePath:soundFilePath];
}
//创建录音文件名字
- (NSString *)createFilename {
NSDate *date_ = [NSDate date];
NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];
[dateformater setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];
NSString *timeFileName = [dateformater stringFromDate:date_];
return timeFileName;
}
//创建存储路径
-(void)createFilePath
{
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString *savedImagePath = [docsDir
stringByAppendingPathComponent:DefaultSubPath];
BOOL isDir = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL existed = [fileManager fileExistsAtPath:savedImagePath isDirectory:&isDir];
if ( !(isDir == YES && existed == YES) )
{
[fileManager createDirectoryAtPath:savedImagePath withIntermediateDirectories:YES attributes:nil error:nil];
}
}
-(void)stopRecord
{
if (self.audioRecorder) {
if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
[self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
}
self.recorderDelegate = nil;
[self.audioRecorder stop];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO error:nil];
[session setCategory:AVAudioSessionCategoryAmbient error:nil];
}
}
-(float)getPeakPower
{
[self.audioRecorder updateMeters];
float linear = pow (10, [self.audioRecorder peakPowerForChannel:0] / 20);
float linear1 = pow (10, [self.audioRecorder averagePowerForChannel:0] / 20);
float Pitch = 0;
if (linear1>0.03) {
Pitch = linear1+.20;//pow (10, [audioRecorder averagePowerForChannel:0] / 20);//[audioRecorder peakPowerForChannel:0];
}
else {
Pitch = 0.0;
}
float peakPowerForChannel = (linear + 160)/160;
return peakPowerForChannel;
}
//-(void)dealloc
//{
// self.audioRecorder = nil;
// [[NSNotificationCenter defaultCenter] removeObserver:self];
// [super dealloc];
//}
//
#pragma mark -
#pragma mark AVAudioRecorderDelegate Methods
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
[[UIApplication sharedApplication] setIdleTimerDisabled: NO];
if (flag) {
if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
[self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
}
self.recorderDelegate = nil;
}else{
if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
[self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
}
self.recorderDelegate = nil;
}
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO error:nil];
[session setCategory:AVAudioSessionCategoryAmbient error:nil];
}
-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error
{
[[UIApplication sharedApplication] setIdleTimerDisabled: NO];
if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {
[self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];
}
self.recorderDelegate = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO error:nil];
[session setCategory:AVAudioSessionCategoryAmbient error:nil];
}
@end
在需要录制音频的界面调用这两个文件
录制音频的按钮有两个响应事件,代码如下
[recordingBtn addTarget:self action:@selector(buttonSayBegin) forControlEvents:UIControlEventTouchDown];
[recordingBtn addTarget:self action:@selector(buttonSayEnd) forControlEvents:UIControlEventTouchUpInside];
- (void)buttonSayBegin
{
[self stopAudio];
[[Recorder shareRecorder]startRecord];
}
- (void)buttonSayEnd
{
[[Recorder shareRecorder]stopRecord];
[self stopAudio];
// [StateLable setText:@"播放录音文件中。。"];
NSString * string = [Recorder shareRecorder].filePath;
[self playAudio:string];
}
//播放
- (void)playAudio:(NSString *)path {
NSURL *url = [NSURL URLWithString:path];
NSError *err = nil;
audioPalyer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
audioPalyer.delegate = self;
[audioPalyer prepareToPlay];
[audioPalyer play];
}
//停止播放
- (void)stopAudio {
if (audioPalyer) {
[audioPalyer stop];
audioPalyer = nil;
}
}
- (void)playing
{
if([audioPalyer isPlaying])
{
[audioPalyer pause];
}
else
{
[audioPalyer play];
}
}
#pragma mark -AVAudio 代理方法-
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
}
OK 问题解决
录制wav格式的音频相关推荐
- Android 手机录制wav格式音频文件实现
上一篇文章已经实现了在Android手机上使用MediaRecorder录音,但是后期在处理这些音频文件的时候发现3gp格式的音频不大方便处理,使用wav格式的音频处理起来更方便一些! 这里需要用到A ...
- Android 录音机小米商业项目开源代码 AudioRecord录音暂停 播放 Wav格式(音频二)
Android MediaRecorder录音录像 暂停 继续录音 播放 ARM格式(音频一) https://blog.csdn.net/WHB20081815/article/details/88 ...
- html中怎么写播放音乐格式,HTML+CSS入门 如何实现多浏览器播放wav格式的音频文件...
本篇教程介绍了HTML+CSS入门 如何实现多浏览器播放wav格式的音频文件,希望阅读本篇文章以后大家有所收获,帮助大家HTML+CSS入门. < 使用audioplayer.js 基本上能支持 ...
- 用C#来播放.wav格式的音频文件
.net自带的有播放.wav格式音频文件的类:System.Media.SoundPlayer,只要调用这个类就可以了. 代码如下: string path = "....../so ...
- WAV 格式和音频裁剪、转码处理
文章目录 0.参考资料 1.WAV 格式了解 1.1 WAV 文件头 1.2 RIFF Chunk 区块 1.3 Format Chunk 区块 1.4 Data Chunk 区块 2.音频剪裁 -& ...
- java实现录音并保存为wav格式的音频文件
前言:本意是想像个录屏的软件,这篇先从录音功能开始. 整体思路:采用java官方API--TargetDataLine,从声卡中采集音频数据达到录音效果,采集的数据为PCM裸流,再将PCM转为wav格 ...
- java 音频转为wav格式标准音频 | Java工具类
目录 简述 环境依赖 maven依赖 ffmpeg依赖 工具类代码 总结 简述 该工具类主要是为了将各类音频转为wav标准格式,其中可以调节采样率.声道数等指标.主要是使用ffmpeg命令进行转换. ...
- ffmpeg 从视频中提取WAV格式的音频
步骤 1.下载ffmpeg 2.把下载回来的ffmpeg解压后的bin目录路径添加到环境变量里面的path里面 3. ffmpeg -i .[迅雷下载xunbo.cc]爱情公寓第二季EP20.rmvb ...
- wav格式的音频文件 16位转化成8位的
1.下载 安装cool edit文件 http://www.xue51.com/soft/1252.html 2.file->batch file convert 2.添加文件 3.选择要修改的 ...
最新文章
- == Equals ReferenceEquals 的区别
- 启动转换安装失败 拷贝windows安装文件时出错_男人的生产力工具:极速拷贝 效率神器 TeraCopy精品推荐...
- linux 脚本$字符,一文看懂shell脚本中$0 $1 $# $@ $* $? $$ 的各种符号意义
- Smoothing滤波处理halcon算子,持续更新
- LeetCode 1941. 检查是否所有字符出现次数相同
- getHibernateTemplate 抛出NullPointer 异常 其中一个容易被忽略的原因
- vue-Resource(与后端数据交互)
- 深度强化学习笔记(一)——深度强化学习简述
- 建模国赛2016A-系泊系统的设计优秀论文
- 打印 条码 CodeSoft JsBarCode
- Python实现箱形图的绘制
- 素食崇尚的是养身和修心的生活方式,鼎沐素食让你身心共融
- 拯救者R9000X显卡驱动安装
- eclipse不能启动
- OA系统都能为企业带来什么
- RabbitMQ学习笔记(一)
- 虚拟邮箱怎么设置方法_商务邮箱一般用什么邮箱正式?VIP邮箱名怎么设置好?...
- hbulider初学教程及html5五子棋小程序
- 我的世界java版特别卡怎么办_我的世界卡顿延迟怎么办
- 冰河指南AI技术社区基于ChatGPT正式启动运营