PoseProvider
public protocol PoseProvider: Sendable { func poses() -> AsyncStream<Pose>}Anything that produces poses. Every call to poses() starts a new stream. When the consumer stops iterating (breaks out of the loop or cancels its task), the stream ends and the provider releases what it was using.
VisionPoseProvider
Section titled “VisionPoseProvider”Module KinesiaMotionVision, iOS only. See the guide.
init(camera: Camera = .front, minimumConfidence: Float = 0.3)| Member | |
|---|---|
captureSession: AVCaptureSession |
For an AVCaptureVideoPreviewLayer. |
camera: Camera |
.front or .back. |
minimumConfidence: Float |
Points with less confidence are dropped. |
static isAuthorized: Bool |
Whether camera permission is already granted. |
static requestAccess() async -> Bool |
Asks for permission. |
VideoPoseProvider
Section titled “VideoPoseProvider”Module KinesiaMotionVision, iOS and macOS. Since 0.2.0. See Tests and recordings.
init(url: URL, mirrored: Bool = false, minimumConfidence: Float = 0.3, maximumFrameRate: Double = 30, realTime: Bool = false)| Member | |
|---|---|
url: URL |
The video (.mov, .mp4). Processed on the device. |
mirrored: Bool |
true when the video looks like a mirror; sides become the patient’s. |
minimumConfidence: Float |
Points below this confidence are dropped. |
maximumFrameRate: Double |
Skips frames closer than 1 / maximumFrameRate. |
realTime: Bool |
Waits between frames as in the video. |
readAll() async throws -> [Pose] |
Every pose at once. Throws ReadError if the file can’t be read. |
RecordedPoseProvider
Section titled “RecordedPoseProvider”Module KinesiaMotion. See Tests and recordings.
init(_ recording: [Pose], realTime: Bool = false)Writing your own
Section titled “Writing your own”For example, for poses coming from another detector:
struct MyDetectorProvider: PoseProvider { let detector: MyDetector
func poses() -> AsyncStream<Pose> { AsyncStream(bufferingPolicy: .bufferingNewest(1)) { continuation in let token = detector.onFrame { result in continuation.yield(Pose( points: result.pointsInPixels, // y pointing down timestamp: result.time, imageSize: result.imageSize, confidence: result.confidence )) } continuation.onTermination = { _ in detector.stop(token) } } }}Respect the Pose contract: pixels with y pointing down, anatomical sides and only confident points. .bufferingNewest(1) avoids piling up old frames if the consumer is slow.