2

我正在使用 ReplayKit 进行屏幕录制,我需要保留视频而不是在 viewController 中呈现它,我尝试了以下方法:

- (void)stopScreenRecording {
    RPScreenRecorder *sharedRecorder = RPScreenRecorder.sharedRecorder;
    [sharedRecorder stopRecordingWithHandler:^(RPPreviewViewController *previewViewController, NSError *error) {
        if (error) {
            NSLog(@"stopScreenRecording: %@", error.localizedDescription);
        }

        if (previewViewController) {
            previewViewController.previewControllerDelegate = self;
            self.previewViewController = previewViewController;

            // RPPreviewViewController only supports full screen modal presentation.
            //self.previewViewController.modalPresentationStyle = UIModalPresentationFullScreen;

           // [self presentViewController:previewViewController animated:YES completion:nil];

            NSURL *aMovieUrl = [previewViewController valueForKey:@"movieURL"];
            [self writeVideoToAlbum:aMovieUrl];
        }
    }];

}
- (void)writeVideoToAlbum:(NSURL *)assetURL{
    __block PHObjectPlaceholder *placeholder;

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:assetURL];
        placeholder = [createAssetRequest placeholderForCreatedAsset];

    } completionHandler:^(BOOL success, NSError *error) {
        if (success)
        {
            NSLog(@"Video successfully saved!");

        }
        else
        {
            NSLog(@"%@", error);
        }
    }];
}

但它似乎不起作用,任何建议将不胜感激。

4

1 回答 1

6

您可以使用以下功能使用 ReplayKit 录制屏幕,将视频写入 NSDocumentDirectory。

对于以下代码,您也可以录制视频屏幕。

@property (strong, nonatomic) RPScreenRecorder *screenRecorder;
@property (strong, nonatomic) AVAssetWriter *assetWriter;
@property (strong, nonatomic) AVAssetWriterInput *assetWriterInput;

- (IBAction)startScreenRecording:(UIButton *)button {
    self.screenRecorder = [RPScreenRecorder sharedRecorder];
    if (self.screenRecorder.isRecording) {
        return;
    }
    NSError *error = nil;
    NSArray *pathDocuments = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *outputURL = pathDocuments[0];

    NSString *videoOutPath = [[outputURL stringByAppendingPathComponent:[NSString stringWithFormat:@"%u", arc4random() % 1000]] stringByAppendingPathExtension:@"mp4"];
    self.assetWriter = [AVAssetWriter assetWriterWithURL:[NSURL fileURLWithPath:videoOutPath] fileType:AVFileTypeMPEG4 error:&error];

    NSDictionary *compressionProperties = @{AVVideoProfileLevelKey         : AVVideoProfileLevelH264HighAutoLevel,
                                            AVVideoH264EntropyModeKey      : AVVideoH264EntropyModeCABAC,
                                            AVVideoAverageBitRateKey       : @(1920 * 1080 * 11.4),
                                            AVVideoMaxKeyFrameIntervalKey  : @60,
                                            AVVideoAllowFrameReorderingKey : @NO};
    NSNumber* width= [NSNumber numberWithFloat:self.view.frame.size.width];
    NSNumber* height = [NSNumber numberWithFloat:self.view.frame.size.height];

    if (@available(iOS 11.0, *)) {
        NSDictionary *videoSettings = @{AVVideoCompressionPropertiesKey : compressionProperties,
                                        AVVideoCodecKey                 : AVVideoCodecTypeH264,
                                        AVVideoWidthKey                 : width,
                                        AVVideoHeightKey                : height};

        self.assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
    } else {
        // Fallback on earlier versions
    }

    [self.assetWriter addInput:self.assetWriterInput];
    [self.assetWriterInput setMediaTimeScale:60];
    [self.assetWriter setMovieTimeScale:60];
    [self.assetWriterInput setExpectsMediaDataInRealTime:YES];

    if (@available(iOS 11.0, *)) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (granted)
                {
                    [self.screenRecorder setMicrophoneEnabled:YES];
                    [self.screenRecorder startCaptureWithHandler:^(CMSampleBufferRef  _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) {
                        if (CMSampleBufferDataIsReady(sampleBuffer)) {
                            if (self.assetWriter.status == AVAssetWriterStatusUnknown && bufferType == RPSampleBufferTypeVideo) {
                                [self.assetWriter startWriting];
                                [self.assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
                            }

                            if (self.assetWriter.status == AVAssetWriterStatusFailed) {
                                NSLog(@"An error occured.");
                                //show alert
                                [[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) {}];
                                return;
                            }
                            if (bufferType == RPSampleBufferTypeVideo) {
                                if (self.assetWriterInput.isReadyForMoreMediaData) {
                                    [self.assetWriterInput appendSampleBuffer:sampleBuffer];
                                }else{
                                    NSLog(@"Not ready for video");
                                }
                            }
                        }
                    } completionHandler:^(NSError * _Nullable error) {
                        if (!error) {
                            AVAudioSession *session = [AVAudioSession sharedInstance];
                            [session setActive:YES error:nil];
                            // Start recording
                            NSLog(@"Recording started successfully.");
                        }else{
                            //show alert
                        }
                    }];
                }
            });
        }];


    } else {
        // Fallback on earlier versions
    }

} 

- (IBAction)stopScreenRecording:(UIButton *)button {

    if (@available(iOS 11.0, *)) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) {
                if (!error) {
                    NSLog(@"Recording stopped successfully. Cleaning up...");
                    [self.assetWriterInput markAsFinished];
                    [self.assetWriter finishWritingWithCompletionHandler:^{
                        NSLog(@"File Url:  %@",self.assetWriter.outputURL);
                        self.assetWriterInput = nil;
                        self.assetWriter = nil;
                        self.screenRecorder = nil;
                    }];
                }
            }];
        });


    } else {
        // Fallback on earlier versions
        NSLog(@"hello");
    }
}
于 2017-11-20T10:42:42.380 回答