美文网首页
4-15 做1个播放视屏 同时录制音频的功能

4-15 做1个播放视屏 同时录制音频的功能

作者: 大也 | 来源:发表于2020-04-15 13:07 被阅读0次

    郁闷 音频录制 哪里出了问题 文件有 就是不对

    音频播放没问题

    经过 再三深挖之后发现
    音屏录制 没有问题
    音频播放也没有问题
    问题出现在 公司需求 边播放边录制
    用的是第三方播放器ZFplayer
    边录边播
    所以修改了 ZFPlayer的底层文件
    边录边播 会导致使用了听筒播放 然后占用了[AVAudioSession sharedInstance]是单例
    原来录音的时候
    [[AVAudioSession sharedInstance]setCategory: AVAudioSessionCategoryPlayAndRecord
    error: &error];
    设置category是AVAudioSessionCategoryPlayAndRecord
    但是播放视频的时候
    [[AVAudioSession sharedInstance]setCategory: AVAudioSessionCategoryPlayback
    error: &error];
    设置category为AVAudioSessionCategoryPlayback

    导致边录边播 无法实现 只好修改 ZFPlayer 底层[AVAudioSession sharedInstance]setCategory 代码测试成功

    最后找到方法

    //边录边播   会导致使用了听筒播放  按照官方文档的说法通过重写audio route属性来重定向音频。
    1.[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
    2.[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];//1-2两句效果相等
    
    [[AVAudioSession sharedInstance]setActive:YES error:nil];//马上设置
    [[AVAudioSession sharedInstance]setActive:NO error:nil];//交出音频会话
    

    相比于播放器 ZFPlayer 其实已经很完善了
    下面 附上完整可用的 音频录制播放 代码

    //
    //  VideoManager.h
    //  House
    //
    //  Created by FMNet on 2020/4/15.
    //  Copyright © 2020 fengwenxiao. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #import <AVFoundation/AVFoundation.h>
    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface AudioManager : NSObject
    
    + (instancetype)sharedvideoManager ;
    
    @property (nonatomic, strong) AVAudioRecorder* __nullable avAudioRecorder;
    @property (nonatomic, strong) AVAudioPlayer* __nullable avAudioPlayer;
    
    - (void)configRecording ;
    
    - (void)startRecording ;
    
    - (void)playRecording;
    
    - (void)stopRecording;
    
    - (void)continueRecording;
    
    - (void)pauseRecording;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    //
    //  VideoManager.m
    //  House
    //
    //  Created by FMNet on 2020/4/15.
    //  Copyright © 2020 fengwenxiao. All rights reserved.
    //
    
    #import "AudioManager.h"
    
    #define DOCUMENT_PATH                   [NSSearchPathForDirectoriesInDomains(   \
    NSDocumentDirectory, NSUserDomainMask, \
    YES) objectAtIndex: 0]
    #define AUDIO_FOLDER_NAME               @"audios"
    #define AUDIO_FOLDER_PATH               [DOCUMENT_PATH stringByAppendingPathComponent:  \
    AUDIO_FOLDER_NAME]
    
    @interface AudioManager (){
        NSString* _curWavFilePath;
        NSString* _curAmrFilePath;
    
        NSURL* _curWavFileUrl;
    
    }
    
    @property (nonatomic, strong) AVAudioSession* audioSession;
    
    @end
    
    @implementation AudioManager
    
    
    + (instancetype)sharedvideoManager {
        static AudioManager *videoManager;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (!videoManager) {
                videoManager = [[self alloc] init];
            }
        });
        return videoManager;
    }
    
    - (void)configRecording {
        AVAudioSession* audioSession = [AVAudioSession sharedInstance];
        NSError* error;
        
        [audioSession setCategory: AVAudioSessionCategoryPlayAndRecord
                            error: &error];
        
        [[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
        
        if (audioSession == nil) {
            UIAlertController* alertController = [UIAlertController
                                                  alertControllerWithTitle: @"Error"
                                                  message: error.description
                                                  preferredStyle: UIAlertControllerStyleAlert];
            
            UIAlertAction* okAction = [UIAlertAction actionWithTitle: @"确定"
                                                               style: UIAlertActionStyleDefault
                                                             handler: nil];
            
            [alertController addAction: okAction];
            
            [[AudioManager currentViewController] presentViewController: alertController animated: YES
                             completion: nil];
            
            return ;
        }
        
        [audioSession setActive: YES
                          error: nil];
        
        self.audioSession = audioSession;
        
        NSDate* nowDate = [NSDate date];
        
        _curWavFilePath = [self generateAudioFilePathWithDate: nowDate
                                                       andExt: @"wav"];
        _curAmrFilePath = [self generateAudioFilePathWithDate: nowDate
                                                       andExt: @"amr"];
        
        _curWavFileUrl = [NSURL fileURLWithPath: _curWavFilePath];
        
        NSDictionary* recordSettings = @{
                 AVSampleRateKey: @8000.0f,                         // 采样率
                 AVFormatIDKey: @(kAudioFormatLinearPCM),           // 音频格式
                 AVLinearPCMBitDepthKey: @16,                       // 采样位数
                 AVNumberOfChannelsKey: @1,                         // 音频通道
                 AVEncoderAudioQualityKey: @(AVAudioQualityHigh)    // 录音质量
                 };
        
        _avAudioRecorder = [[AVAudioRecorder alloc] initWithURL: _curWavFileUrl
                                                       settings: recordSettings
                                                          error: nil];
        
        if (!_avAudioRecorder) {
            UIAlertController* alertController = [UIAlertController
                                                  alertControllerWithTitle: @"Error"
                                                  message: @"Error init AVAudioRecorder"
                                                  preferredStyle: UIAlertControllerStyleAlert];
            
            UIAlertAction* okAction = [UIAlertAction actionWithTitle: @"OK"
                                                               style: UIAlertActionStyleDefault
                                                             handler: nil];
            
            [alertController addAction: okAction];
            
            [[AudioManager currentViewController] presentViewController: alertController
                               animated: YES
                             completion: nil];
            
            return ;
        }
        
        _avAudioRecorder.meteringEnabled = YES;
        [_avAudioRecorder prepareToRecord];
    
    }
    
    - (void)startRecording {
        [self configRecording];
        [_avAudioRecorder record];
    }
    
    
    
    
    
    
    
    /**
     *  播放音频
     */
    -(void)playRecording{
        if ([_avAudioRecorder isRecording])
            return ;
        
        if ([[NSFileManager defaultManager] fileExistsAtPath: _curWavFilePath]) {
            _avAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:
                              [NSURL fileURLWithPath: _curWavFilePath]
                                                                    error: nil];
            
            [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback
                                                   error: nil];
            
            [_avAudioPlayer play];
        }
    
    }
    
    - (void)stopRecording {
        if ([_avAudioRecorder isRecording]) {
            [_avAudioRecorder stop];
        }
        
        NSLog(@"文件大小为 %liKb",
             [self getFileSizeWithFilePath: _curWavFilePath]);
        
        // 可以在这里转换为amr文件
    }
    
    - (void)continueRecording {
        [_avAudioRecorder record];
    }
    
    - (void)pauseRecording {
        if ([_avAudioRecorder isRecording]) {
            [_avAudioRecorder pause];
        }
    }
    
    
    - (NSString*)generateAudioFilePathWithDate: (NSDate*)date
                                        andExt: (NSString*)ext {
        NSInteger timeStamp = [[NSNumber numberWithDouble:
                                [date timeIntervalSince1970]] integerValue];
        
        return [NSString stringWithFormat: @"%@/%li.%@", AUDIO_FOLDER_PATH,
                timeStamp, ext];
    }
    
    - (NSInteger)getFileSizeWithFilePath: (NSString*)filePath {
        if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]) {
            long long fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath: filePath
                                                                    error: nil].fileSize;
            
            return fileSize / 1024.0f;
            
        }
        
        return 0.0f;
    }
    
    
      + (UIViewController*)currentViewController{
    
          UIViewController* vc = [UIApplication sharedApplication].keyWindow.rootViewController;
    
          while (1) {
              if ([vc isKindOfClass:[UITabBarController class]]) {
                  vc = ((UITabBarController*)vc).selectedViewController;
              }
              if ([vc isKindOfClass:[UINavigationController class]]) {
                  vc = ((UINavigationController*)vc).visibleViewController;
              }
              if (vc.presentedViewController) {
                  vc = vc.presentedViewController;
              }else{
                  break;
              }
          }
          return vc;
    }
    @end
    

    相关文章

      网友评论

          本文标题:4-15 做1个播放视屏 同时录制音频的功能

          本文链接:https://www.haomeiwen.com/subject/npwwmhtx.html