Ollin

VideoPlayback

loops a video file as a live image, draws it letterboxed with drawFrame, and draws a playback-progress line along the bottom; by default it plays a bundled clip (Voladores de Papantla México by José Millán, CC BY-SA, the Totonac pole-flying ritual dance), or you pass a path on launch to play your own video (VideoPlayer, drawFrame, duration/currentTime)

Run
swift run --package-path Examples Example-Video-VideoPlayback
Imports
OllinVideo
Beside it
voladores.mp4
Source
Examples/Video/VideoPlayback/Sketch.swift
import Foundation
import Ollin
import OllinVideo

/// Plays a video file as a live image. By default it loops a bundled clip —
/// *Voladores de Papantla México* by José Millán (Jmillan325), 2018, via
/// Wikimedia Commons, CC BY-SA 4.0; trimmed and re-encoded for bundling
/// (https://commons.wikimedia.org/wiki/File:Voladores_de_Papantla_México.webm)
/// — so it runs out of the box. Pass a path on launch to play your own video:
///
/// ```
/// swift run Example-Video-VideoPlayback /path/to/your/clip.mp4
/// ```
///
/// Each decoded frame arrives as a GPU texture wrapped in an `Image`, drawn
/// letterboxed with `drawFrame`; the thin line along the bottom is playback
/// progress (`currentTime` over `duration`).
@main
final class VideoPlayback: Sketch {
    var player: VideoPlayer?

    override func setup() {
        noStroke()
        let player = makePlayer()
        player?.loops = true
        player?.play()
        self.player = player
    }

    /// A readable file path passed on launch overrides the bundled clip.
    private func makePlayer() -> VideoPlayer? {
        // A flag's own value (an export path, say) is not a clip: skip each
        // flag and the argument that follows it.
        let arguments = Array(CommandLine.arguments.dropFirst())
        var isDirectory: ObjCBool = false
        for (i, argument) in arguments.enumerated() where !argument.hasPrefix("-") {
            if i > 0, arguments[i - 1].hasPrefix("-") { continue }
            if FileManager.default.fileExists(atPath: argument, isDirectory: &isDirectory),
               !isDirectory.boolValue {
                return try? VideoPlayer(path: argument)
            }
        }
        return try? VideoPlayer(resource: "voladores", withExtension: "mp4", in: .module)
    }

    override func draw() {
        background(Color(white: 0.06))
        guard let player else { return }

        drawFrame(player)

        // Playback progress along the bottom edge.
        if let duration = player.duration, duration > 0 {
            let progress = min(1, player.currentTime / duration)
            fill(Color(white: 0.92))
            drawRect(0, height - 5 * scale, width * progress, 5 * scale)
        }

        drawCaption("Voladores de Papantla · José Millán (CC BY-SA)", edge: .top)
    }
}

↑↓ move ↩ open