【问题标题】:AVCaptureSession and AVAudioSession recording video while background music playing only works onceAVCaptureSession 和 AVAudioSession 在播放背景音乐时录制视频只能工作一次
【发布时间】:2017-09-15 03:25:42
【问题描述】:

看了这个问题后:AVAudioSession AVAudioSessionCategoryPlayAndRecord glitch,我试图尝试让视频录制与背景音乐正常播放。我正在解决录制开始时和结束时出现的音频故障,并且在第一次录制时它工作正常。但是如果我再次尝试录制,音乐就会停止。

有什么想法吗?

这是我的代码的 sn-p:

    captureSession = AVCaptureSession()
    captureSession?.automaticallyConfiguresApplicationAudioSession = false
    captureSession?.usesApplicationAudioSession = true

    guard let captureSession = self.captureSession else {
        print("Error making capture session")
        return;
    }

    captureSession.sessionPreset = AVCaptureSessionPresetHigh

    self.camera = self.defaultBackCamera()
    self.audioDeviceInput = try? AVCaptureDeviceInput(device: getAudioDevice())

    cameraInput = try AVCaptureDeviceInput(device: camera)
    captureSession.beginConfiguration()
    if captureSession.inputs.count > 0 {
        return
    }
    if captureSession.canAddInput(cameraInput) {
        captureSession.addInput(cameraInput)
        if captureSession.outputs.count == 0 {
            photoOutput = AVCapturePhotoOutput()
            if captureSession.canAddOutput(photoOutput!) {
                captureSession.addOutput(self.photoOutput!)
            }
    }
    captureSession.commitConfiguration()
    if !captureSession.isRunning {
        captureSession.startRunning()
        self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.previewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
        self.previewLayer!.connection.videoOrientation = .portrait
        self.previewLayer!.frame = cameraView.layer.bounds
        self.cameraView.layer.addSublayer(self.previewLayer!)
        captureSession.beginConfiguration()
        videoFileOut = AVCaptureMovieFileOutput()
        if (captureSession.canAddOutput(videoFileOut)) {
            captureSession.addOutput(videoFileOut)
            if (videoFileOut?.connection(withMediaType: AVMediaTypeVideo).isVideoStabilizationSupported)! {
                videoFileOut?.connection(withMediaType: AVMediaTypeVideo).preferredVideoStabilizationMode = .cinematic
            }
        }
        captureSession.commitConfiguration()
    }

这是开始录制的代码:

    let audioSession = AVAudioSession.sharedInstance()
    try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord,
                                                    with: [.mixWithOthers, .allowBluetoothA2DP, .allowAirPlay])
    try! audioSession.setActive(true)
    captureSession?.beginConfiguration()
    if (captureSession?.canAddInput(audioDeviceInput!))! {
        captureSession?.addInput(audioDeviceInput!)
    }
    captureSession?.commitConfiguration()

并停止录制:

    let audioSession = AVAudioSession.sharedInstance()
    try! audioSession.setCategory(AVAudioSessionCategoryAmbient, with: [.mixWithOthers, .allowAirPlay])

    captureSession?.beginConfiguration()
    captureSession?.removeInput(audioDeviceInput)
    captureSession?.commitConfiguration()

【问题讨论】:

  • 你有可以链接到的可运行代码sn-p吗?
  • 你演奏的音乐怎么样?我使用了AVAudioEngine,您的代码可以正常使用。

标签: ios swift avfoundation avcapturesession avaudiosession


【解决方案1】:

我正在做一个几乎相同的项目:录制视频并播放背景音频。 (在 Xamarin 中)

在我的代码中,我在 onViewLoad 中进行 AudioSession 设置。

在将类别设置为 PlayAndRecord 之前,我还会执行 audioSession.SetActive(false)。也许你应该在开始/停止录制时试试这个。

伯努瓦

【讨论】:

    【解决方案2】:

    在我看来,这与您的AVAudioSession 有关。停止录制时,不要将 audioSession 设置为非活动状态。当您在开始新录制时更改 AVAudioSession 类别时,这会导致立即更改路线。

    尝试在停止录制时将AVAudioSession 设置为非活动状态。

    另外,不同的AVAudioSession 类别对 AirPlay 的影响也不同。

    取自

    https://developer.apple.com/documentation/avfoundation/avaudiosession/audio_session_categories

    音频会话类别 AVAudioSessionCategoryPlayAndRecord 仅支持 AirPlay 的镜像变体”和

    "仅音频会话播放类别(AVAudioSessionCategoryAmbient、AVAudioSessionCategorySoloAmbient 和 AVAudioSessionCategoryPlayback)支持 AirPlay 的镜像和非镜像变体。 "

    我建议阅读一下 Apple 文档中的 AVAudioSession,因为有时需要经过深思熟虑才能控制 AVAudioSession 本身。

    https://developer.apple.com/documentation/avfoundation/avaudiosession

    【讨论】:

      【解决方案3】:

      记得在停用时使用 .notifyOthersOnDeactivation 标志调用 false:

      try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
      

      否则其他在后台播放音乐的应用程序将不知道在您的会话完成后重新打开他们的音乐。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-22
        • 2012-02-28
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        相关资源
        最近更新 更多