ricohapi / theta-client

A library to control RICOH THETA
MIT License
17 stars 13 forks source link

How to use the bracket shooting added in 1.6? #57

Closed markd2 closed 7 months ago

markd2 commented 10 months ago

Hi! I'm really interested in the bracketed shooting that was recently added (not the Z1-specific burst bracketing, but the new autoBracket stuff). iOS/Swift

I'm not sure how to use it. I can set options on my theta repository before calling the builder (photoCaptureBuilder / also looking at shotCountSpecifiedIntervalCaptureBuilder), but the builder is creating its own options and (presumably) blowing away my bracket settings.

Can I use one of the existing builder objects and somehow get the bracket settings in, or do I need to implement my own Capture subclass? (or more likely something obvious I'm missing)

For example, this (hacked adapted from the demo app) takes three photos, but the bracketing information is not honored, and I get three photos back with the same exposure.

Thanks!

func bracket(_ callback: @escaping (_ url: [String]?) -> Void) async throws {
    try await initialize()
    let options = ThetaRepository.Options()

    let thing1: ThetaRepository.BracketSetting = ThetaRepository.BracketSetting(
        aperture: .aperture24, 
        colorTemperature: nil, 
        exposureCompensation: .zero, 
        exposureProgram: .manual, 
        iso: .iso400, 
        shutterSpeed: .shutterSpeedOneOver50, 
        whiteBalance: .auto_)
    let thing2: ThetaRepository.BracketSetting = ThetaRepository.BracketSetting(
        aperture: .aperture24, 
        colorTemperature: nil, 
        exposureCompensation: .zero, 
        exposureProgram: .manual, 
        iso: .iso400, 
        shutterSpeed: .shutterSpeedOneOver400, 
        whiteBalance: .auto_)
    let thing3: ThetaRepository.BracketSetting = ThetaRepository.BracketSetting(
        aperture: .aperture24, 
        colorTemperature: nil, 
        exposureCompensation: .zero, 
        exposureProgram: .manual, 
        iso: .iso400, 
        shutterSpeed: .shutterSpeedOneOver1600, 
        whiteBalance: .auto_)

    let settingArray: [ThetaRepository.BracketSetting] = [thing1, thing2, thing3]
    let wtfbbq = NSMutableArray(array: settingArray)
    let settingList = ThetaRepository.BracketSettingList(list: wtfbbq)
    options.autoBracket = settingList
    options.shootingMethod = .bracket

    try await thetaRepository?.setOptions(options: options)

    let shotCountSpecifiedIntervalCapture: ShotCountSpecifiedIntervalCapture = try await withCheckedThrowingContinuation { continuation in
        thetaRepository!
            // .getPhotoCaptureBuilder()
            .getShotCountSpecifiedIntervalCaptureBuilder(shotCount: 3)
            .build { capture, error in
                if let photoCapture = capture {
                    continuation.resume(returning: photoCapture)
                }
                if let thetaError = error {
                    continuation.resume(throwing: thetaError)
                }
            }
    }
    class Callback: ShotCountSpecifiedIntervalCaptureStartCaptureCallback {
        let callback: (_ url: [String]?, _ error: Error?) -> Void

        init(_ callback: @escaping (_ url: [String]?, _ error: Error?) -> Void) {
            self.callback = callback
        }

        func onCaptureCompleted(fileUrls: [String]?) {
            print("COMPLETED urls \(fileUrls)")
            callback(fileUrls, nil)
        }

        func onCaptureFailed(exception: ThetaRepository.ThetaRepositoryException) {
            callback(nil, exception.asError())
        }

        func onStopFailed(exception: ThetaRepository.ThetaRepositoryException) {
            print("ON STOP FAILED")
        }

        func onProgress(completion oop: Float) {
            print("PROGRESS \(oop)")
        }
    }

    let photoUrl: [String]? = try await withCheckedThrowingContinuation { continuation in
        shotCountSpecifiedIntervalCapture.startCapture(
            callback: Callback { fileUrls, error in
                if let thetaError = error {
                    print("ERRORING")
                    continuation.resume(throwing: thetaError)
                } else {
                    print("RESUMING with file urls")
                    continuation.resume(returning: fileUrls)
                }
            }
        )
    }

    // eventually exfiltrate the photos.
    // callback(photoUrl)
}
simago commented 10 months ago

@markd2 To use auto bracket shooting, its own builder class and capture sub class are needed. We are implementing MultiBracketCaptureclass and MultiBracketCapture.Builder class so that they will be included in the next release.

markd2 commented 10 months ago

Thanks! Appreciate the fast response!