簡體   English   中英

訂閱 RxSwift Observable<VideoCaptureOutput> 不觸發 onNext()

[英]Subscription to RxSwift Observable<VideoCaptureOutput> not triggering onNext()

我想使用 RxSwift 處理從 iPhone 相機捕獲的視頻幀。 我正在使用一個社區維護的項目https://github.com/RxSwiftCommunity/RxAVFoundation ,它連接了 AVFoundation(用於捕獲相機輸出)和 RxSwift。

每當新的視頻幀寫入輸出緩沖區時,我都試圖只打印一個虛擬日志語句。 以下是我的 ViewController。 我配置了 AVCaptureSession,設置了 Rx 鏈,然后開始會話。 但是,永遠不會觸發 .next 情況下的打印語句。 我聯系了項目所有者。 下面的代碼正確嗎? 這是來自社區維護項目的 AVCaptureSession 類的 Reactive 擴展: https : //github.com/RxSwiftCommunity/RxAVFoundation/blob/master/RxAVFoundation/AVCaptureSession%2BRx.swift

//  ViewController.swift
import UIKit
import AVFoundation
import RxSwift

class ViewController: UIViewController {

    // capture session
    private let session = AVCaptureSession()
    private var videoDevice: AVCaptureDevice!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
    
        session
            .rx
            .configure(captureDevice: videoDevice)
    
        let disposeBag = DisposeBag()
        
        let videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_32BGRA)] as [String : Any]
        session
            .rx
            .videoCaptureOutput(settings: videoSettings)
            .observeOn(MainScheduler.instance)
            .subscribe { [unowned self] (event) in
                switch event {
                    case .next(let captureOutput):
                        print("got a frame")
                    case .error(let error):
                        print("error: %@", "\(error)")
                    case .completed:
                        break // never happens
                }
            }
            .disposed(by: disposeBag)
        session
            .rx
            .startRunning()
    }
}

因為您已經在viewDidLoad本地定義了DisposeBag ,所以一旦viewDidLoad完成,添加到包中的所有訂閱都將被處理。

將您的DisposeBag聲明為ViewController的實例變量以修復:

...
// capture session
private let session = AVCaptureSession()
private var videoDevice: AVCaptureDevice!

private let disposeBag = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()
    ...

使用.debug()是捕捉這種事情的好方法,因為它會打印包括處置在內的所有事件,例如:

session
    .rx
    .videoCaptureOutput(settings: videoSettings)
    .observeOn(MainScheduler.instance)
    .debug("Video Capture Output Observable:")
    .subscribe { [unowned self] (event) in
        switch event {
            case .next(let captureOutput):
                print("got a frame")
            case .error(let error):
                print("error: %@", "\(error)")
            case .completed:
                break // never happens
        }
    }
    .disposed(by: disposeBag)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM