You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 17中RPSystemBroadcastPickerView录屏仅2秒自动停止问题

iOS 17录屏2秒自动停止问题排查与修复建议

现有代码在iOS 17以下设备可正常同时录制屏幕与音频,但在iOS 17设备上录屏仅2秒后自动停止。由于是扩展程序,无法获取日志进行调试,且同款代码在其他低版本iOS设备上运行正常。

初始化AVAssetWriter代码

@try {
        NSLog(@"initAssesWriter");
        
        
        NSError *error = nil;
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        _videoWriter = [[AVAssetWriter alloc] initWithURL:
                        _filePath fileType:AVFileTypeMPEG4
            error:&error];
        NSParameterAssert(_videoWriter);

        //Configure video
        NSDictionary* videoCompressionProps = [NSDictionary dictionaryWithObjectsAndKeys:
                                               [NSNumber numberWithDouble:2048*1024.0], AVVideoAverageBitRateKey,
                                               nil ];
        
        NSDictionary* videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                       AVVideoCodecTypeH264, AVVideoCodecKey,
                                       [NSNumber numberWithInt:screenRect.size.width * 4], AVVideoWidthKey,
                                       [NSNumber numberWithInt:screenRect.size.height * 4], AVVideoHeightKey,
                                       videoCompressionProps, AVVideoCompressionPropertiesKey,
                                       nil];
        
        _writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] ;
        _writerInput.expectsMediaDataInRealTime = YES;
        
        NSParameterAssert(_writerInput);
        NSParameterAssert([_videoWriter canAddInput:_writerInput]);
        [_videoWriter addInput:_writerInput];
        

        AudioChannelLayout acl;
        bzero( &acl, sizeof(acl));
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;

        
        NSDictionary*  audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                        [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey,
                                        [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,
                                        [ NSData dataWithBytes: &acl length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
                                        [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey,
                                              nil];
        
     
         _audioWriterInput = [AVAssetWriterInput
                               assetWriterInputWithMediaType: AVMediaTypeAudio
                               outputSettings: audioOutputSettings ];
         _audioWriterInput.expectsMediaDataInRealTime = YES; // seems to work slightly better

        NSParameterAssert(_audioWriterInput);
        NSParameterAssert([_videoWriter canAddInput:_audioWriterInput]);
        [_videoWriter addInput:_audioWriterInput];
        [_videoWriter setMovieFragmentInterval:CMTimeMake(1, 600)];
        
        [_videoWriter startWriting];

    } @catch (NSException *exception) {
    } @finally {
        
    }

处理SampleBuffer代码

-(void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType{
    @try {
        if(!_isRecordingStarted){
            [_videoWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
            _isRecordingStarted = YES;
            [self saveFlurryLogs:@"Assest writer Start Recording" Details:@""];
            NSLog(@"CMSampleBufferGetPresentationTimeStamp");
        }
    } @catch (NSException *exception) {
        [self saveFlurryLogs:@"Recording Start Execption" Details:exception.description];
    } @finally {
        
    }
    
    @try {
        switch (sampleBufferType) {
            case RPSampleBufferTypeVideo:
                // Handle video sample buffer
                if([_writerInput isReadyForMoreMediaData]){
                    [_writerInput appendSampleBuffer:sampleBuffer];
                    NSLog(@"writing matadata Video");
                }
                break;
            case RPSampleBufferTypeAudioApp:
                // Handle audio sample buffer for app audio
                break;
            case RPSampleBufferTypeAudioMic:
                if([_audioWriterInput isReadyForMoreMediaData]){
                    [_audioWriterInput appendSampleBuffer:sampleBuffer];
                    NSLog(@"writing matadata Audio");
                }
                // Handle audio sample buffer for mic audio
                break;
                
            default:
                break;
        }
    } @catch (NSException *exception) {
        [self saveFlurryLogs:@"Packet Write Execption" Details:exception.description];
    } @finally {
        
    }
}

修复建议

  • 捕获AVAssetWriter错误信息:扩展环境下虽然无法直接查看NSLog,但可以通过_videoWriter.error获取具体错误,将错误信息通过你已有的saveFlurryLogs方法上报,或者写入本地文件,这是定位问题的关键。
  • 补全App音频处理分支:当前代码忽略了RPSampleBufferTypeAudioApp类型的样本,如果你的录制包含App音频,iOS 17会因音频输入长时间无数据而终止录制。需要补上该分支的处理:
case RPSampleBufferTypeAudioApp:
    if([_audioWriterInput isReadyForMoreMediaData]){
        [_audioWriterInput appendSampleBuffer:sampleBuffer];
    }
    break;
  • 修正视频分辨率设置:直接使用屏幕原生像素尺寸,避免固定乘以4导致的分辨率异常,替换为:
CGRect screenBounds = [[UIScreen mainScreen] nativeBounds];
// 后续用screenBounds.size.width和height作为视频宽高
  • 调整Movie Fragment Interval:尝试注释掉[_videoWriter setMovieFragmentInterval:CMTimeMake(1, 600)],或者将间隔调整为CMTimeMake(1, 30),iOS 17对该参数的兼容性可能有变化。
  • 优化会话启动时机:优先等待第一个视频样本到来时再启动录制会话,避免因先收到音频样本导致视频后续跟不上触发超时:
@try {
    switch (sampleBufferType) {
        case RPSampleBufferTypeVideo:
            if(!_isRecordingStarted){
                [_videoWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
                _isRecordingStarted = YES;
                [self saveFlurryLogs:@"Assest writer Start Recording" Details:@""];
            }
            if([_writerInput isReadyForMoreMediaData]){
                [_writerInput appendSampleBuffer:sampleBuffer];
            }
            break;
        // 其他分支...
    }
}

内容的提问来源于stack exchange,提问作者user1115985

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:29:58