在网络视图中播放视频意外结束后台视频录制?

Playing video in web view unexpectedly ends background video recording?

我正在使用 WKWebView 在我的应用程序中显示全屏 YouTube 视频,并使用 AVCaptureSession 在后台录制音频和视频,同时在 YouTube 上浏览和播放视频。按下按钮时捕获会话开始。 However, whilst a recording is in process, when a YouTube video is selected and starts playing in fullscreen, it immediately ends the recording unexpectedly as the delegate method that handles the ending of a recording is called.

有人可以向我解释如何解决这个问题吗?不太确定这是否完全相关,但我收到了诸如 _BSMachError: (os/kern) invalid capability (20) _BSMachError: (os/kern) invalid name (15) and Unable to simultaneously satisfy constraints. 之类的错误消息,尽管后者似乎引用了一个单独的 AutoLayout 问题。任何帮助将不胜感激。

此外,我尝试使用 UIWebView 而不是 WKWebView。当我使用 UIWebView 时,问题是在录制视频时甚至无法播放 YouTube 视频。它只会打开并在黑屏上停留在 0:00。

这是最初开始录制时按下的按钮。

- (void) buttonClickedStart:(UIButton*)sender //button to start/end recording {
    if (!WeAreRecording) {
        [self setupVideoCapture]; 
        //----- START RECORDING -----
        WeAreRecording = YES;
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:nil];

        //Create temporary URL to record the video to for later viewing
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *basePath = [paths objectAtIndex:0];
        NSString *outputPath = [[NSString alloc] initWithFormat:@"%@", [basePath stringByAppendingPathComponent:@"output.mp4"]];
        if ([[NSFileManager defaultManager] isDeletableFileAtPath:outputPath])
            [[NSFileManager defaultManager] removeItemAtPath:outputPath error:NULL];
        NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
        [MovieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
        self.outputURLs = outputURL;
    }
    else {
        //----- STOP RECORDING -----
        WeAreRecording = NO;
        [MovieFileOutput stopRecording];
    }
}

这是按下按钮时调用的方法。它设置并启动表示为 CaptureSession.

的捕获会话
- (void)setupVideoCapture { 
    // Sets up recording capture session
    CaptureSession = [[AVCaptureSession alloc] init];

    // Add video input to capture session
    AVCaptureDevice *VideoDevice = [AVCaptureDevice     defaultDeviceWithMediaType:AVMediaTypeVideo];
    if (VideoDevice) {
        NSError *error;
        VideoInputDevice = [[AVCaptureDeviceInput alloc] initWithDevice:[self CameraWithPosition:AVCaptureDevicePositionFront] error:&error];
        if (!error) {
            if ([CaptureSession canAddInput:VideoInputDevice])
                [CaptureSession addInput:VideoInputDevice];
         }
    }

    // Add audio input to capture session
    AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice   defaultDeviceWithMediaType:AVMediaTypeAudio];
    NSError *error = nil;
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput  deviceInputWithDevice:audioCaptureDevice error:&error];
    if (audioInput) {
        [CaptureSession addInput:audioInput];
    }

    // Add movie file output to the capture session
    MovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    [MovieFileOutput setMovieFragmentInterval:kCMTimeInvalid];
    if ([CaptureSession canAddOutput:MovieFileOutput])
        [CaptureSession addOutput:MovieFileOutput];

    // Set the output properties (you don't really need to see this code)
    [self CameraSetOutputProperties]; // (We call a method as it also has to be done after changing camera)
    [CaptureSession setSessionPreset:AVCaptureSessionPresetMedium];

    //----- START THE CAPTURE SESSION RUNNING -----
    [CaptureSession startRunning];
}

这是声明和设置 WKWebView 的地方。

- (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];

        // Add recording button
        CGSize screenSize = [[UIScreen mainScreen] bounds].size;
        CGRect rect = CGRectMake(0, 0, screenSize.width, 337);
        UIButton *start = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [start addTarget:self action:@selector(buttonClickedStart:) forControlEvents:UIControlEventTouchUpInside];
        [start setFrame:CGRectMake(30, 338, 35, 35)];
        [start setTitle:@"" forState:UIControlStateNormal];
        [start setExclusiveTouch:YES];
        [start setBackgroundImage:[UIImage imageNamed:@"start.png"] forState:UIControlStateNormal];
        [self.view addSubview:start];

        // Add web view
        webView = [[WKWebView alloc] initWithFrame:rect];
        [self.view addSubview:webView];
        NSString *webSite = @"http://www.youtube.com";
        NSURL *url = [NSURL URLWithString:webSite];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        webView.navigationDelegate = self;
        webView.UIDelegate = self;
        [webView loadRequest:request]; // Load up Youtube           
        [self.view addSubview:webView];
}

的原因

_BSMachError: (os/kern) invalid capability (20) _BSMachError: (os/kern) invalid name (15)

可能是因为 Apple 引入了强制使用 'HTTPS' URL 的 App Transport Security。尽管您可以修改您的 info.plist 以进行例外处理,但对于旧版 URLS,他们强烈建议对任何新的 URLs 使用 HTTPS。

对于您的情况,只要将 youtube URL 更新为 'https:'

即可轻松解决

看起来唯一缺少的是在音频会话中设置 与其他人混合 选项和 播放和录制 类别。

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];

编辑:设置了一个简单的测试并且成功了,希望这对您有所帮助!