-
Howdy, and thanks to @orchetect for this library 👍. I'm starting this discussion because I think I must lack some knowledge of timecodes and how they relate to wall-clock time, and I'm hopeful somebody here can set me straight. Consider the following snippet. import Foundation
import TimecodeKit
var max = TimecodeFrameRate.allCases.map({ $0.rawValue.count }).max()
guard let max else { exit(1) }
for fps in TimecodeFrameRate.allCases {
let tc = try Timecode(.realTime(seconds: 1), at: fps)
let pad = String(repeating: " ", count: max - fps.rawValue.count)
let fpsString = fps.rawValue
let tcString = tc.stringValue(format: .showSubFrames)
print("\(pad)\(fpsString):\t\(tcString)")
} And its output.
You'll notice that with one second of If this is is too rudimentary or if there's a better place to ask this, please let me know. Thanks again. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Thanks for the post - it's a good question. It's explained in the documentation but due to the nuanced nature of timecode it can be a head-scratcher even for the experienced in the field. Timecode is not time. Timecode seconds are not wall-clock seconds. That is why a conversion is necessary between the two completely different domains.
In a nutshell, for fractional rates and drop-frame rates, the time values themselves will not align because 1 Timecode second will be slightly shorter than 1 actual second of wall time if you were to overlay the two domains. So your code (and log output) is correct. There are long and very technical reasons for this, and if you want some very dry bedtime reading you can read about SMPTE Timecode and why fractional rates and drop-frame exists. At certain rates it may appear that hours, minutes, and seconds in both domains correspond. However this is not necessarily true as in many cases there is actual very slight drift between the two domains even if it's seemingly inconsequential. So some are led to use timecode (say, at 30 fps) in place of real time or see them as interchangeable, but it is generally bad practise. The purpose of this library is to try and make working with timecode and conversions simple (and correct). And also, if it is not totally clear: Timecode(.realTime(seconds: 1), at: fps) // converts 1 second of real time to timecode
Timecode(.components(h: 0, m: 0, s: 1, f: 0), at: fps) // 1 explicit second of timecode |
Beta Was this translation helpful? Give feedback.
Thanks for the post - it's a good question. It's explained in the documentation but due to the nuanced nature of timecode it can be a head-scratcher even for the experienced in the field.
Timecode is not time. Timecode seconds are not wall-clock seconds. That is why a conversion is necessary between the two completely different domains.
TimecodeFrameRate
is essentially: fps == frames per Timecode second.VideoFrameRate
is essentially: fps == frames per wall-time second.In a nutshell, for fractional rates and drop-frame rates, the time values themselves will not align because 1 Timecode second will be slightly shorter than 1 actual second of wall time if you were to overlay the two domain…