| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /************************************************************
- * * Hyphenate CONFIDENTIAL
- * __________________
- * Copyright (C) 2016 Hyphenate Inc. All rights reserved.
- *
- * NOTICE: All information contained herein is, and remains
- * the property of Hyphenate Inc.
- * Dissemination of this information or reproduction of this material
- * is strictly forbidden unless prior written permission is obtained
- * from Hyphenate Inc.
- */
- #import "EMCDDeviceManager+Media.h"
- #import "EMAudioPlayerUtil.h"
- #import "EMAudioRecorderUtil.h"
- #import "EMVoiceConverter.h"
- #import "DemoErrorCode.h"
- #import "EaseLocalDefine.h"
- typedef NS_ENUM(NSInteger, EMAudioSession){
- EM_DEFAULT = 0,
- EM_AUDIOPLAYER,
- EM_AUDIORECORDER
- };
- @implementation EMCDDeviceManager (Media)
- #pragma mark - AudioPlayer
- + (NSString*)dataPath
- {
- NSString *dataPath = [NSString stringWithFormat:@"%@/Library/appdata/chatbuffer", NSHomeDirectory()];
- NSFileManager *fm = [NSFileManager defaultManager];
- if(![fm fileExistsAtPath:dataPath]){
- [fm createDirectoryAtPath:dataPath
- withIntermediateDirectories:YES
- attributes:nil
- error:nil];
- }
- return dataPath;
- }
- // Play the audio
- - (void)asyncPlayingWithPath:(NSString *)aFilePath
- completion:(void(^)(NSError *error))completon{
- BOOL isNeedSetActive = YES;
- // Cancel if it is currently playing
- if([EMAudioPlayerUtil isPlaying]){
- [EMAudioPlayerUtil stopCurrentPlaying];
- isNeedSetActive = NO;
- }
-
- if (isNeedSetActive) {
- [self setupAudioSessionCategory:EM_AUDIOPLAYER
- isActive:YES];
- }
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSString *wavFilePath = [[aFilePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"wav"];
- if (![fileManager fileExistsAtPath:wavFilePath]) {
- BOOL covertRet = [self convertAMR:aFilePath toWAV:wavFilePath];
- if (!covertRet) {
- if (completon) {
- completon([NSError errorWithDomain:NSEaseLocalizedString(@"error.initRecorderFail", @"File format conversion failed")
- code:EMErrorFileTypeConvertionFailure
- userInfo:nil]);
- }
- return ;
- }
- }
- [EMAudioPlayerUtil asyncPlayingWithPath:wavFilePath
- completion:^(NSError *error)
- {
- [self setupAudioSessionCategory:EM_DEFAULT
- isActive:NO];
- if (completon) {
- completon(error);
- }
- }];
- }
- - (void)stopPlaying{
- [EMAudioPlayerUtil stopCurrentPlaying];
- [self setupAudioSessionCategory:EM_DEFAULT
- isActive:NO];
- }
- - (void)stopPlayingWithChangeCategory:(BOOL)isChange{
- [EMAudioPlayerUtil stopCurrentPlaying];
- if (isChange) {
- [self setupAudioSessionCategory:EM_DEFAULT
- isActive:NO];
- }
- }
- - (BOOL)isPlaying{
- return [EMAudioPlayerUtil isPlaying];
- }
- #pragma mark - Recorder
- +(NSTimeInterval)recordMinDuration{
- return 1.0;
- }
- // Start recording
- - (void)asyncStartRecordingWithFileName:(NSString *)fileName
- completion:(void(^)(NSError *error))completion{
- NSError *error = nil;
-
- if ([self isRecording]) {
- if (completion) {
- error = [NSError errorWithDomain:NSEaseLocalizedString(@"error.recordStoping", @"Record voice is not over yet")
- code:EMErrorAudioRecordStoping
- userInfo:nil];
- completion(error);
- }
- return ;
- }
-
- if (!fileName || [fileName length] == 0) {
- error = [NSError errorWithDomain:NSEaseLocalizedString(@"error.notFound", @"File path not exist")
- code:-1
- userInfo:nil];
- completion(error);
- return ;
- }
-
- BOOL isNeedSetActive = YES;
- if ([self isRecording]) {
- [EMAudioRecorderUtil cancelCurrentRecording];
- isNeedSetActive = NO;
- }
-
- [self setupAudioSessionCategory:EM_AUDIORECORDER
- isActive:YES];
-
- _recorderStartDate = [NSDate date];
- NSString *recordPath = [NSString stringWithFormat:@"%@/%@", [EMCDDeviceManager dataPath], fileName];
- [EMAudioRecorderUtil asyncStartRecordingWithPreparePath:recordPath
- completion:completion];
- }
- // Stop recording
- -(void)asyncStopRecordingWithCompletion:(void(^)(NSString *recordPath,
- NSInteger aDuration,
- NSError *error))completion{
- NSError *error = nil;
- if(![self isRecording]){
- if (completion) {
- error = [NSError errorWithDomain:NSEaseLocalizedString(@"error.recordNotBegin", @"Recording has not yet begun")
- code:EMErrorAudioRecordNotStarted
- userInfo:nil];
- completion(nil,0,error);
- }
- return;
- }
-
- __weak typeof(self) weakSelf = self;
- _recorderEndDate = [NSDate date];
-
- if([_recorderEndDate timeIntervalSinceDate:_recorderStartDate] < [EMCDDeviceManager recordMinDuration]){
- if (completion) {
- error = [NSError errorWithDomain:NSEaseLocalizedString(@"error.recordTooShort", @"Recording time is too short")
- code:EMErrorAudioRecordDurationTooShort
- userInfo:nil];
- completion(nil,0,error);
- }
-
- // If the recording time is too shorty,in purpose delay one second
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)([EMCDDeviceManager recordMinDuration] * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [EMAudioRecorderUtil asyncStopRecordingWithCompletion:^(NSString *recordPath) {
- [weakSelf setupAudioSessionCategory:EM_DEFAULT isActive:NO];
- }];
- });
- return ;
- }
-
- [EMAudioRecorderUtil asyncStopRecordingWithCompletion:^(NSString *recordPath) {
- if (completion) {
- if (recordPath) {
- // Convert wav to amr
- NSString *amrFilePath = [[recordPath stringByDeletingPathExtension]
- stringByAppendingPathExtension:@"amr"];
- BOOL convertResult = [self convertWAV:recordPath toAMR:amrFilePath];
- NSError *error = nil;
- if (convertResult) {
- // Remove the wav
- NSFileManager *fm = [NSFileManager defaultManager];
- [fm removeItemAtPath:recordPath error:nil];
- }
- else {
- error = [NSError errorWithDomain:NSEaseLocalizedString(@"error.initRecorderFail", @"File format conversion failed")
- code:EMErrorFileTypeConvertionFailure
- userInfo:nil];
- }
- completion(amrFilePath,(int)[self->_recorderEndDate timeIntervalSinceDate:self->_recorderStartDate],error);
- }
- [weakSelf setupAudioSessionCategory:EM_DEFAULT isActive:NO];
- }
- }];
- }
- // Cancel recording
- -(void)cancelCurrentRecording{
- [EMAudioRecorderUtil cancelCurrentRecording];
- [self setupAudioSessionCategory:EM_DEFAULT isActive:NO];
- }
- -(BOOL)isRecording{
- return [EMAudioRecorderUtil isRecording];
- }
- #pragma mark - Private
- -(NSError *)setupAudioSessionCategory:(EMAudioSession)session
- isActive:(BOOL)isActive{
- BOOL isNeedActive = NO;
- if (isActive != _currActive) {
- isNeedActive = YES;
- _currActive = isActive;
- }
- NSError *error = nil;
- NSString *audioSessionCategory = nil;
- switch (session) {
- case EM_AUDIOPLAYER:
- audioSessionCategory = AVAudioSessionCategoryPlayback;
- break;
- case EM_AUDIORECORDER:
- audioSessionCategory = AVAudioSessionCategoryRecord;
- break;
- default:
- audioSessionCategory = AVAudioSessionCategoryAmbient;
- break;
- }
-
- AVAudioSession *audioSession = [AVAudioSession sharedInstance];
- if (![_currCategory isEqualToString:audioSessionCategory]) {
- [audioSession setCategory:audioSessionCategory error:nil];
- }
- if (isNeedActive) {
- BOOL success = [audioSession setActive:isActive
- withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
- error:&error];
- if(!success || error){
- error = [NSError errorWithDomain:NSEaseLocalizedString(@"error.initPlayerFail", @"Failed to initialize AVAudioPlayer")
- code:-1
- userInfo:nil];
- return error;
- }
- }
- _currCategory = audioSessionCategory;
-
- return error;
- }
- #pragma mark - Convert
- - (BOOL)convertAMR:(NSString *)amrFilePath
- toWAV:(NSString *)wavFilePath
- {
- BOOL ret = NO;
- BOOL isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:amrFilePath];
- if (isFileExists) {
- [EMVoiceConverter amrToWav:amrFilePath wavSavePath:wavFilePath];
- isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:wavFilePath];
- if (isFileExists) {
- ret = YES;
- }
- }
-
- return ret;
- }
- - (BOOL)convertWAV:(NSString *)wavFilePath
- toAMR:(NSString *)amrFilePath {
- BOOL ret = NO;
- BOOL isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:wavFilePath];
- if (isFileExists) {
- [EMVoiceConverter wavToAmr:wavFilePath amrSavePath:amrFilePath];
- isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:amrFilePath];
- if (!isFileExists) {
-
- } else {
- ret = YES;
- }
- }
-
- return ret;
- }
- @end
|