previewFrameTimeCodeProblem function
Why value is not a poster-frame timecode, or null when it is.
Shape and ranges only. Whether the frame is inside the video is a question
about a particular file and is asked where both are in hand, in
_loadPreviews.
frameRate bounds the frames field when the caller knows it. Optional
because the shape check has callers that have no file — a consumer
validating a string before writing it — and absent it the frames field is
unbounded, which is the state this shipped in: 00:00:02:99 passed every
offline check on a 30 fps video, because minutes and seconds were range
checked and the field the format is named for was not.
Implementation
String? previewFrameTimeCodeProblem(String value, {double? frameRate}) {
final match = _timeCode.firstMatch(value);
if (match == null) {
return 'is "$value"; Apple wants a HH:MM:SS:FF timecode, e.g. '
'00:00:02:06 for two seconds and six frames in';
}
final minutes = int.parse(match.group(2)!);
final seconds = int.parse(match.group(3)!);
if (minutes > 59 || seconds > 59) {
return 'is "$value"; the minutes and seconds fields go up to 59';
}
final frames = int.parse(match.group(4)!);
// Rounded up, so a 29.97 fps file still accepts frame 29. The bound is the
// count of frames in a second, and the field is zero-based.
final perSecond = frameRate?.ceil();
if (perSecond != null && frames >= perSecond) {
return 'is "$value"; FF is a frame within one second and this video runs '
'at ${frameRate!.toStringAsFixed(2)} fps, so the last frame of a '
'second is ${perSecond - 1}';
}
return null;
}