解決ReplayKit開啟Microphone哨啃,AVAssetWriter寫入失敗

最近在做直播內(nèi)錄制視頻分享的功能烧栋,便嘗試使用了ReplayKit,期間遇到一些問題拳球,在這里記錄下來审姓。

在嘗試過程中,遇到兩種場(chǎng)景:

場(chǎng)景1
  1. 開啟 AVAssetWriter (包含 Audio / Video Writer Input)
  2. 使用RPScreenRecorder開始錄制(不啟動(dòng)Microphone)
  3. 錄制成功并成功獲得視頻
場(chǎng)景2
  1. 開啟 AVAssetWriter (包含 Audio / Video Writer Input)
  2. 使用RPScreenRecorder開始錄制(啟動(dòng)Microphone)
  3. 錄制失敗

針對(duì)第二種情況祝峻,網(wǎng)上相應(yīng)的解決方案很少(不知道是不是只有我遇到了)魔吐。所以在經(jīng)過n次google(stackoverflow上的解決方案)和自己嘗試之后,終于成功解決莱找。下面是我的代碼

    if (openMic) {
        [RPScreenRecorder sharedRecorder].microphoneEnabled = YES;
    } else {
        [RPScreenRecorder sharedRecorder].microphoneEnabled = NO;
    }
    [self.videoWriter startWriting];
    __weak typeof(self) weakSelf = self;
    [[RPScreenRecorder sharedRecorder] startCaptureWithHandler:^(CMSampleBufferRef _Nonnull sampleBuffer,RPSampleBufferType bufferType, NSError *_Nullable error) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (!CMSampleBufferDataIsReady(sampleBuffer)) {
            return;
        }
        if (strongSelf.videoWriter.status == AVAssetWriterStatusFailed) {
            NSLog(@"[錄屏]AVAssetWriterStatusFailed");
            return;
        }
        if (strongSelf.videoWriter.status == AVAssetWriterStatusWriting) {
            if (bufferType == RPSampleBufferTypeVideo) {
                if (!strongSelf.startedSession) {
                    [strongSelf.videoWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStam(sampleBuffer)];
                    strongSelf.startedSession = YES;
                    NSLog(@"[錄屏]開啟session 視頻處");
                }
                if (CMTimeCompare(kCMTimeInvalid, strongSelf.firstVideoFramTime) == 0) {
                    strongSelf.firstVideoFramTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
                }
                if ([strongSelf.videoWriterInput isReadyForMoreMediaData]) {
                    @try {
                        [strongSelf.videoWriterInput appendSampleBuffer:sampleBuffer];
                        NSLog(@"[錄屏]寫入視頻數(shù)據(jù)");
                    } @catch (NSException *exception) {
                        NSLog(@"[錄屏]寫入視頻數(shù)據(jù)失敗");
                    }
                }
            }
            if (bufferType == RPSampleBufferTypeAudioApp || bufferType == RPSampleBufferTypeAudioMic) {
                // 可以在這里做一些過濾操作
                // if (onlyMicAudio && bufferType == RPSampleBufferTypeAudioApp) {
                //     return;
                // }
                
                if (CMTimeCompare(kCMTimeInvalid, strongSelf.firstVideoFramTime) == 0 || CMTimeCompar(strongSelf.firstVideoFramTime, CMSampleBufferGetPresentationTimeStamp(sampleBuffer)) == 1) {
                    return;
                }
                if (!strongSelf.startedSession) {
                    [strongSelf.videoWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStam(sampleBuffer)];
                    strongSelf.startedSession = YES;
                    NSLog(@"[錄屏]開啟session 音頻處");
                }
                if ([strongSelf.audioWriterInput isReadyForMoreMediaData]) {
                    @try {
                        [strongSelf.audioWriterInput appendSampleBuffer:sampleBuffer];
                        NSLog(@"[錄屏]寫入音頻數(shù)據(jù)");
                    } @catch (NSException *exception) {
                        NSLog(@"[錄屏]寫入音頻數(shù)據(jù)失敗");
                    }
                }
            }
        }
    } completionHandler:^(NSError *_Nullable error) {
       
    }];

下面是 AVAssetWriter 和 AVAssetWriterInput 的配置(因?yàn)椴皇菍I(yè)的多媒體工程師酬姆,所以很多參數(shù)配置不一定合理,僅供大家參考)

- (void)setupVideoWriter
{
    if (!_videoWriter) {
        NSURL *outputURL = [NSURL fileURLWithPath:self.videoOutputPath];

        NSError *error = nil;
        _videoWriter = [AVAssetWriter assetWriterWithURL:outputURL fileType:AVFileTypeQuickTimeMovie error:&error];
        if (error) {
            NSLog(@"創(chuàng)建Video Writer失敯履纭:%@", [error localizedDescription]);
        }
    }
}

- (void)setupVideoWriterInput
{
    if (!_videoWriterInput) {
        CGFloat scale = [UIScreen mainScreen].scale;
        CGSize size = CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds) * scale, CGRectGetHeight([UIScreen mainScreen].bounds) * scale);
        NSDictionary *copressionProperties = @{ AVVideoAverageBitRateKey : @(1200 * 1024) };
        _videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
                                                               outputSettings:@{
                                                                   AVVideoCodecKey : AVVideoCodecH264,
                                                                   AVVideoWidthKey : @(size.width),
                                                                   AVVideoHeightKey : @(size.height),
                                                                   AVVideoCompressionPropertiesKey : copressionProperties
                                                               }];
        _videoWriterInput.expectsMediaDataInRealTime = YES;
        if ([self.videoWriter canAddInput:_videoWriterInput]) {
            [self.videoWriter addInput:_videoWriterInput];
        } else {
            NSLog(@"無法添加Video Writer Input");
        }
    }
}

- (void)setupAudioWriterInput
{
    if (!_audioWriterInput) {
        AudioChannelLayout acl;
        bzero(&acl, sizeof(acl));
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;

        _audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
                                                               outputSettings:@{
                                                                   AVSampleRateKey : @(44100),
                                                                   AVFormatIDKey : @(kAudioFormatAppleLossless),
                                                                   AVEncoderBitDepthHintKey : @(16),
                                                                   AVNumberOfChannelsKey : @(1),
                                                                   AVChannelLayoutKey : [NSData dataWithBytes:&acl length:sizeof(acl)],
                                                               }];
        _audioWriterInput.expectsMediaDataInRealTime = YES;
        if ([self.videoWriter canAddInput:_audioWriterInput]) {
            [self.videoWriter addInput:_audioWriterInput];
        } else {
            NSLog(@"無法添加Video Writer Input");
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辞色,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子浮定,更是在濱河造成了極大的恐慌相满,老刑警劉巖层亿,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異立美,居然都是意外死亡匿又,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門悯辙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琳省,“玉大人,你說我怎么就攤上這事躲撰≌氡幔” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拢蛋,是天一觀的道長(zhǎng)桦他。 經(jīng)常有香客問我,道長(zhǎng)谆棱,這世上最難降的妖魔是什么快压? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮垃瞧,結(jié)果婚禮上蔫劣,老公的妹妹穿的比我還像新娘。我一直安慰自己个从,他們只是感情好脉幢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗦锐,像睡著了一般嫌松。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奕污,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天萎羔,我揣著相機(jī)與錄音,去河邊找鬼碳默。 笑死贾陷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嘱根。 我是一名探鬼主播昵宇,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼儿子!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砸喻,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤柔逼,失蹤者是張志新(化名)和其女友劉穎蒋譬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愉适,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡犯助,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了维咸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剂买。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖癌蓖,靈堂內(nèi)的尸體忽然破棺而出瞬哼,到底是詐尸還是另有隱情,我是刑警寧澤租副,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布坐慰,位于F島的核電站,受9級(jí)特大地震影響用僧,放射性物質(zhì)發(fā)生泄漏结胀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一责循、第九天 我趴在偏房一處隱蔽的房頂上張望糟港。 院中可真熱鬧,春花似錦院仿、人聲如沸秸抚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耸别。三九已至,卻和暖如春县钥,著一層夾襖步出監(jiān)牢的瞬間秀姐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工若贮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留省有,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓谴麦,卻偏偏與公主長(zhǎng)得像蠢沿,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匾效,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容