我想使用RxSwift来处理从iPhone相机捕获的视频帧。我正在使用一个社区维护的项目,https://github.com/RxSwiftCommunity/RxAVFoundation,它桥接了AVFoundation(用于捕捉相机输出(和RxSwift。
每当新的视频帧被写入输出缓冲区时,我试图只打印一个伪日志语句。以下是我的ViewController。我配置AVCaptureSession,设置Rx链,然后启动会话。但是,.next情况下的print语句从未被触发。我联系了项目负责人。以下代码正确吗?以下是社区维护项目中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)