您的位置:首页 > 移动开发 > 微信开发

类似于微信发语音Demo

2016-03-29 21:17 639 查看
AVAudioSession类从AVFoundation框架中引入, 每个IOS应用都有一个音频会话, 这个会话可以被AVAudioSession的sharedInstance类方法访问.

AVAudioSessionCategoryPlayAndRecord 这个类别中允许你的应用同时进行声音的播放和录制.当你的声音播放和录制开始后, 其他应用的声音播放将会停止,主UI界面会照常工作, 这时即使屏幕被锁定或者设备为静音模式,音频的播放都会继续.

demo写的异常粗糙, 以后再重新写一个

#import "ViewController.h"

#import "UIImage+Extension.h"

#import <AVFoundation/AVFoundation.h>

#define WIDTH [[UIScreen mainScreen] bounds].size.width

#define HEIGHT [[UIScreen mainScreen] bounds].size.height

@interface ViewController ()

// 录音名字

@property (nonatomic,copy) NSString *playName;

// 录音器

@property (nonatomic,strong) AVAudioRecorder *recorder;

// 播放器

@property (nonatomic,strong) AVAudioPlayer *player;

// 属性设置

@property (nonatomic,copy) NSDictionary *recorderSettingsDict;

// 声音标识

@property (nonatomic,copy) NSMutableArray *volumImages;

// 定时器

@property (nonatomic,strong) NSTimer *timer;

//

@property (nonatomic,assign) double lowPassResults;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    

    // 创建button

    UIButton *button = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.6,WIDTH-60, 40)];

    [self.viewaddSubview:button];

    

    [button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_Black"]forState:UIControlStateNormal];

    [button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_BlackHL"]forState:UIControlStateHighlighted];

    

    [button setTitle:@"发送新消息"forState:UIControlStateNormal];

    [button setTitle:@"按住说话"forState:UIControlStateHighlighted];

    [button setTitleColor:[UIColordarkGrayColor] forState:UIControlStateNormal];

    button.titleLabel.font = [UIFontsystemFontOfSize:14];

    [button addTarget:selfaction:@selector(holdDownButtonTouchDown)forControlEvents:UIControlEventTouchDown];

    [button addTarget:selfaction:@selector(holdDownButtonTouchUpInside)forControlEvents:UIControlEventTouchUpInside];

    [button addTarget:selfaction:@selector(holdDownDragOutside)forControlEvents:UIControlEventTouchDragExit];

    

    UIButton *buttonPlay = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.7,WIDTH-60, 40)];

    [self.viewaddSubview:buttonPlay];

    buttonPlay.backgroundColor = [UIColorredColor];

    

    [buttonPlay addTarget:selfaction:@selector(buttonPlayMedia)forControlEvents:UIControlEventTouchDown];

    // 创建语音控件

    AVAudioSession *session = [AVAudioSession sharedInstance];

    NSError *sessionError;

    

    //AVAudioSessionCategoryPlayAndRecord用于录音和播放

    [session setCategory:AVAudioSessionCategoryPlayAndRecorderror:&sessionError];

    if(session == nil)

        NSLog(@"Error creating session: %@", [sessionErrordescription]);

    else

        [session setActive:YESerror:nil];

    

    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)objectAtIndex:0];

    self.playName = [NSStringstringWithFormat:@"%@/play.aac",docDir];

    //录音设置

    self.recorderSettingsDict = [[NSDictionaryalloc] initWithObjectsAndKeys:

                                   [NSNumber numberWithFloat: 8000.0],AVSampleRateKey,//采样率

                                   [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,

                                   [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数默认 16

                                   [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,//通道的数目

                                   //                                   [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端是内存的组织方式

                                   //                                   [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,//采样信号是整数还是浮点数

                                   //                                   [NSNumber numberWithInt: AVAudioQualityMedium],AVEncoderAudioQualityKey,//音频编码质量

                                   nil];

    //音量图片数组

    self.volumImages = [[NSMutableArrayalloc]initWithObjects:@"RecordingSignal001",@"RecordingSignal002",@"RecordingSignal003",

                   @"RecordingSignal004",@"RecordingSignal005",@"RecordingSignal006",

                   @"RecordingSignal007",@"RecordingSignal008",  nil];

    

}

- (void)holdDownButtonTouchDown {

    

    NSLog(@"holdDownButtonTouchDown");

    

    //按下录音

    if ([selfcanRecord]) {

        

        NSError *error = nil;

        //必须真机上测试,模拟器上可能会崩溃

        self.recorder = [[AVAudioRecorderalloc] initWithURL:[NSURLURLWithString:self.playName]settings:self.recorderSettingsDicterror:&error];

        

        if (self.recorder) {

            self.recorder.meteringEnabled =YES;

            [self.recorder prepareToRecord];

            [self.recorder record];

            

            //启动定时器

            self.timer = [NSTimerscheduledTimerWithTimeInterval:0.1target:selfselector:@selector(levelTimer:)userInfo:nilrepeats:YES];

            

        } else

        {

            int errorCode = CFSwapInt32HostToBig ([error code]);

            NSLog(@"Error: %@ [%4.4s])" , [errorlocalizedDescription], (char*)&errorCode);

            

        }

    }

}

- (void)holdDownButtonTouchUpInside {

    

    NSLog(@"holdDownButtonTouchUpInside");

    

    //录音停止

    [self.recorderstop];

    self.recorder =nil;

    //结束定时器

    [self.timerinvalidate];

    self.timer =nil;

    //图片重置

//    self.soundLodingImageView.image = [UIImage imageNamed:[self.volumImages objectAtIndex:0]];

    

}

- (void)holdDownDragOutside {

    

    NSLog(@"holdDownDragOutside");

}

- (void)buttonPlayMedia {

    NSError *playerError;

    

    //播放

    self.player =nil;

    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURLURLWithString:self.playName]error:&playerError];

    

    if (self.player ==nil)

    {

        NSLog(@"ERror creating player: %@", [playerErrordescription]);

    }else{

        [self.player play];

    }

}

-(void)levelTimer:(NSTimer*)timer_ {

    [self.recorder updateMeters];

    

    const double ALPHA =0.05;

    double peakPowerForChannel = pow(10, (0.05 * [self.recorderpeakPowerForChannel:0]));

    self.lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) *self.lowPassResults;

    

    NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.recorderaveragePowerForChannel:0],
[self.recorderpeakPowerForChannel:0],self.lowPassResults);

}

//判断是否允许使用麦克风7.0新增的方法requestRecordPermission

-(BOOL)canRecord

{

    __block BOOL bCanRecord =YES;

    if ([[[UIDevicecurrentDevice] systemVersion]compare:@"7.0"]
!=NSOrderedAscending)

    {

        AVAudioSession *audioSession = [AVAudioSessionsharedInstance];

        if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {

            [audioSession performSelector:@selector(requestRecordPermission:)withObject:^(BOOLgranted)
{

                if (granted) {

                    bCanRecord = YES;

                }

                else {

                    bCanRecord = NO;

                    dispatch_async(dispatch_get_main_queue(), ^{

                        [[[UIAlertView alloc] initWithTitle:nil

                                                    message:@"app需要访问您的麦克风。\n请启用麦克风-设置/隐私/麦克风"

                                                   delegate:nil

                                          cancelButtonTitle:@"关闭"

                                          otherButtonTitles:nil]show];

                    });

                }

            }];

        }

    }

    

    return bCanRecord;

}

AVAudioSession类从AVFoundation框架中引入, 每个IOS应用都有一个音频会话, 这个会话可以被AVAudioSession的sharedInstance类方法访问.

AVAudioSessionCategoryPlayAndRecord 这个类别中允许你的应用同时进行声音的播放和录制.当你的声音播放和录制开始后, 其他应用的声音播放将会停止,主UI界面会照常工作, 这时即使屏幕被锁定或者设备为静音模式,音频的播放都会继续.

demo写的异常粗糙, 以后再重新写一个

#import "ViewController.h"

#import "UIImage+Extension.h"

#import <AVFoundation/AVFoundation.h>

#define WIDTH [[UIScreen mainScreen] bounds].size.width

#define HEIGHT [[UIScreen mainScreen] bounds].size.height

@interface ViewController ()

// 录音名字

@property (nonatomic,copy) NSString *playName;

// 录音器

@property (nonatomic,strong) AVAudioRecorder *recorder;

// 播放器

@property (nonatomic,strong) AVAudioPlayer *player;

// 属性设置

@property (nonatomic,copy) NSDictionary *recorderSettingsDict;

// 声音标识

@property (nonatomic,copy) NSMutableArray *volumImages;

// 定时器

@property (nonatomic,strong) NSTimer *timer;

//

@property (nonatomic,assign) double lowPassResults;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    

    // 创建button

    UIButton *button = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.6,WIDTH-60, 40)];

    [self.viewaddSubview:button];

    

    [button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_Black"]forState:UIControlStateNormal];

    [button setBackgroundImage:[UIImageresizedImageWithName:@"VoiceBtn_BlackHL"]forState:UIControlStateHighlighted];

    

    [button setTitle:@"发送新消息"forState:UIControlStateNormal];

    [button setTitle:@"按住说话"forState:UIControlStateHighlighted];

    [button setTitleColor:[UIColordarkGrayColor] forState:UIControlStateNormal];

    button.titleLabel.font = [UIFontsystemFontOfSize:14];

    [button addTarget:selfaction:@selector(holdDownButtonTouchDown)forControlEvents:UIControlEventTouchDown];

    [button addTarget:selfaction:@selector(holdDownButtonTouchUpInside)forControlEvents:UIControlEventTouchUpInside];

    [button addTarget:selfaction:@selector(holdDownDragOutside)forControlEvents:UIControlEventTouchDragExit];

    

    UIButton *buttonPlay = [[UIButtonalloc] initWithFrame:CGRectMake(30,HEIGHT*0.7,WIDTH-60, 40)];

    [self.viewaddSubview:buttonPlay];

    buttonPlay.backgroundColor = [UIColorredColor];

    

    [buttonPlay addTarget:selfaction:@selector(buttonPlayMedia)forControlEvents:UIControlEventTouchDown];

    // 创建语音控件

    AVAudioSession *session = [AVAudioSession sharedInstance];

    NSError *sessionError;

    

    //AVAudioSessionCategoryPlayAndRecord用于录音和播放

    [session setCategory:AVAudioSessionCategoryPlayAndRecorderror:&sessionError];

    if(session == nil)

        NSLog(@"Error creating session: %@", [sessionErrordescription]);

    else

        [session setActive:YESerror:nil];

    

    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)objectAtIndex:0];

    self.playName = [NSStringstringWithFormat:@"%@/play.aac",docDir];

    //录音设置

    self.recorderSettingsDict = [[NSDictionaryalloc] initWithObjectsAndKeys:

                                   [NSNumber numberWithFloat: 8000.0],AVSampleRateKey,//采样率

                                   [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,

                                   [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数默认 16

                                   [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,//通道的数目

                                   //                                   [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端是内存的组织方式

                                   //                                   [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,//采样信号是整数还是浮点数

                                   //                                   [NSNumber numberWithInt: AVAudioQualityMedium],AVEncoderAudioQualityKey,//音频编码质量

                                   nil];

    //音量图片数组

    self.volumImages = [[NSMutableArrayalloc]initWithObjects:@"RecordingSignal001",@"RecordingSignal002",@"RecordingSignal003",

                   @"RecordingSignal004",@"RecordingSignal005",@"RecordingSignal006",

                   @"RecordingSignal007",@"RecordingSignal008",  nil];

    

}

- (void)holdDownButtonTouchDown {

    

    NSLog(@"holdDownButtonTouchDown");

    

    //按下录音

    if ([selfcanRecord]) {

        

        NSError *error = nil;

        //必须真机上测试,模拟器上可能会崩溃

        self.recorder = [[AVAudioRecorderalloc] initWithURL:[NSURLURLWithString:self.playName]settings:self.recorderSettingsDicterror:&error];

        

        if (self.recorder) {

            self.recorder.meteringEnabled =YES;

            [self.recorder prepareToRecord];

            [self.recorder record];

            

            //启动定时器

            self.timer = [NSTimerscheduledTimerWithTimeInterval:0.1target:selfselector:@selector(levelTimer:)userInfo:nilrepeats:YES];

            

        } else

        {

            int errorCode = CFSwapInt32HostToBig ([error code]);

            NSLog(@"Error: %@ [%4.4s])" , [errorlocalizedDescription], (char*)&errorCode);

            

        }

    }

}

- (void)holdDownButtonTouchUpInside {

    

    NSLog(@"holdDownButtonTouchUpInside");

    

    //录音停止

    [self.recorderstop];

    self.recorder =nil;

    //结束定时器

    [self.timerinvalidate];

    self.timer =nil;

    //图片重置

//    self.soundLodingImageView.image = [UIImage imageNamed:[self.volumImages objectAtIndex:0]];

    

}

- (void)holdDownDragOutside {

    

    NSLog(@"holdDownDragOutside");

}

- (void)buttonPlayMedia {

    NSError *playerError;

    

    //播放

    self.player =nil;

    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURLURLWithString:self.playName]error:&playerError];

    

    if (self.player ==nil)

    {

        NSLog(@"ERror creating player: %@", [playerErrordescription]);

    }else{

        [self.player play];

    }

}

-(void)levelTimer:(NSTimer*)timer_ {

    [self.recorder updateMeters];

    

    const double ALPHA =0.05;

    double peakPowerForChannel = pow(10, (0.05 * [self.recorderpeakPowerForChannel:0]));

    self.lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) *self.lowPassResults;

    

    NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.recorderaveragePowerForChannel:0],
[self.recorderpeakPowerForChannel:0],self.lowPassResults);

}

//判断是否允许使用麦克风7.0新增的方法requestRecordPermission

-(BOOL)canRecord

{

    __block BOOL bCanRecord =YES;

    if ([[[UIDevicecurrentDevice] systemVersion]compare:@"7.0"]
!=NSOrderedAscending)

    {

        AVAudioSession *audioSession = [AVAudioSessionsharedInstance];

        if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {

            [audioSession performSelector:@selector(requestRecordPermission:)withObject:^(BOOLgranted)
{

                if (granted) {

                    bCanRecord = YES;

                }

                else {

                    bCanRecord = NO;

                    dispatch_async(dispatch_get_main_queue(), ^{

                        [[[UIAlertView alloc] initWithTitle:nil

                                                    message:@"app需要访问您的麦克风。\n请启用麦克风-设置/隐私/麦克风"

                                                   delegate:nil

                                          cancelButtonTitle:@"关闭"

                                          otherButtonTitles:nil]show];

                    });

                }

            }];

        }

    }

    

    return bCanRecord;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: