rainbow-dragon/Sources/ForgeExport/Timecode.swift

40 lines
1.3 KiB
Swift
Raw Permalink Normal View History

import Foundation
/// Non-drop-frame timecode. Frame count + fps.
public struct Timecode: Sendable, Equatable, CustomStringConvertible {
public var frames: Int
public var fps: Int
public init(frames: Int, fps: Int) {
self.frames = frames
self.fps = fps
}
/// Parse HH:MM:SS:FF.
public static func parse(_ s: String, fps: Int) -> Timecode? {
let parts = s.split(separator: ":")
guard parts.count == 4,
let h = Int(parts[0]), let m = Int(parts[1]),
let sec = Int(parts[2]), let f = Int(parts[3]),
m < 60, sec < 60, f < fps else { return nil }
return Timecode(frames: ((h * 3600 + m * 60 + sec) * fps) + f, fps: fps)
}
public var description: String {
let totalSeconds = frames / fps
let f = frames % fps
let h = totalSeconds / 3600
let m = (totalSeconds % 3600) / 60
let s = totalSeconds % 60
return String(format: "%02d:%02d:%02d:%02d", h, m, s, f)
}
public static func + (l: Timecode, r: Timecode) -> Timecode {
Timecode(frames: l.frames + r.frames, fps: l.fps)
}
public static func - (l: Timecode, r: Timecode) -> Timecode {
Timecode(frames: max(0, l.frames - r.frames), fps: l.fps)
}
}