9个版本
0.1.13 | 2023年7月23日 |
---|---|
0.1.12 | 2023年3月25日 |
0.1.9 | 2021年5月26日 |
#21 in 视频
190 每月下载量
1.5MB
4.5K SLoC
包含 (Cab文件,3MB) Many Basic Edits.aaf
vtc-rs
Rust的SMPTE时间码库
概述
vtc-rs
受到好莱坞剪辑室多年脚本解决方案的启发。它旨在捕捉整个行业中所有时间码的使用方式,以便用户可以将更多时间花在他们的工作流程逻辑上,而不是处理解析和计算时间码的边缘情况。
演示
让我们快速了解一下vtc-rs可以做什么
use vtc::{Timecode, Framerate, Ntsc, rates};
use num::Rational64;
// It's easy to make a new 23.98 NTSC timecode. We use the with_frames constructor here since
// timecode is really a human-readable way to represent frame count.
let mut tc = Timecode::with_frames("17:23:13:02", rates::F23_98).unwrap();
// We can get all sorts of ways to represent the timecode.
assert_eq!(tc.timecode(), "17:23:13:02");
assert_eq!(tc.frames(), 1502234i64);
assert_eq!(tc.seconds(), Rational64::new(751868117, 12000));
assert_eq!(tc.runtime(3), "17:24:15.676");
assert_eq!(tc.premiere_ticks(), 15915544300656000i64);
assert_eq!(tc.feet_and_frames(), "93889+10");
// We can inspect the framerate.
assert_eq!(tc.rate().playback(), Rational64::new(24000, 1001));
assert_eq!(tc.rate().timebase(), Rational64::new(24, 1));
assert_eq!(tc.rate().ntsc(), Ntsc::NonDropFrame);
// Parsing is flexible
// Partial timecode:
let parsed = Timecode::with_frames("3:12", rates::F23_98).unwrap();
assert_eq!(parsed.timecode(), "00:00:03:12");
// Frame count:
let parsed = Timecode::with_frames(24, rates::F23_98).unwrap();
assert_eq!(parsed.timecode(), "00:00:01:00");
// Seconds:
let parsed = Timecode::with_seconds(1.5, rates::F23_98).unwrap();
assert_eq!(parsed.timecode(), "00:00:01:12");
// Premiere Ticks:
let parsed = Timecode::with_premiere_ticks(254016000000i64, rates::F23_98).unwrap();
assert_eq!(parsed.timecode(), "00:00:01:00");
// Feet + Frames:
let parsed = Timecode::with_frames("1+08", rates::F23_98).unwrap();
assert_eq!(parsed.timecode(), "00:00:01:00");
// We can add two timecodes
tc += Timecode::with_frames("01:00:00:00", rates::F23_98).unwrap();
assert_eq!(tc.timecode(), "18:23:13:02");
// We can subtract too.
tc -= Timecode::with_frames("01:00:00:00", rates::F23_98).unwrap();
assert_eq!(tc.timecode(), "17:23:13:02");
// It's easy to compare two timecodes:
assert!(tc > Timecode::with_frames("02:00:00:00", rates::F23_98).unwrap());
// And sort them:
let mut sorted = vec![tc, Timecode::with_frames("02:00:00:00", rates::F23_98).unwrap()];
sorted.sort();
assert_eq!(sorted[0].timecode(), "02:00:00:00");
assert_eq!(sorted[1].timecode(), "17:23:13:02");
// We can multiply:
tc *= 2;
assert_eq!(tc.timecode(), "34:46:26:04");
// ...divide... :
tc /= 2;
assert_eq!(tc.timecode(), "17:23:13:02");
// ... and even get the remainder of division!
let dividend = tc / 1.5;
let remainder = tc % 1.5;
assert_eq!(dividend.timecode(), "11:35:28:17");
assert_eq!(remainder.timecode(), "00:00:00:01");
// We can make a timecode negative:
tc = -tc;
assert_eq!(tc.timecode(), "-17:23:13:02");
// Or get it's absolute value.
tc = tc.abs();
assert_eq!(tc.timecode(), "17:23:13:02");
// We can make dropframe timecode for 29.97 or 59.94 using one of the pre-set framerates.
// We can use an int to parse 15000 frames.
let drop_frame = Timecode::with_frames(15000, rates::F29_97_DF).unwrap();
assert_eq!(drop_frame.timecode(), "00:08:20;18");
assert_eq!(drop_frame.rate().ntsc(), Ntsc::DropFrame);
// We can make new timecodes with arbitrary framerates if we want:
let arbitrary = Timecode::with_frames(
"01:00:00:00",
Framerate::with_playback(48, Ntsc::None).unwrap(),
).unwrap();
assert_eq!(arbitrary.frames(), 172800);
// We can make NTSC values for timebases and playback speeds that do not ship with this
// crate:
let mut ntsc = Timecode::with_frames(
"01:00:00:00",
Framerate::with_timebase(120, Ntsc::NonDropFrame).unwrap(),
).unwrap();
assert_eq!(ntsc.rate().playback(), Rational64::new(120000, 1001));
assert_eq!(ntsc.rate().timebase(), Rational64::new(120, 1));
assert_eq!(ntsc.rate().ntsc(), Ntsc::NonDropFrame);
// We can also rebase them using another framerate:
ntsc = ntsc.rebase(rates::F59_94_NDF);
assert_eq!(ntsc.timecode(), "02:00:00:00");
功能
- SMPTE约定
- NTSC
- Drop-Frame
- 交错时间码
- 时间码表示
- 时间码 | '01:00:00:00'
- 帧 | 86400
- 秒 | 3600.0
- 运行时间 | '01:00:00.0'
- 有理数 | 18018/5
- 英尺+帧 | '5400+00'
- 35mm, 4-perf
- 35mm, 3-perf
- 35mm, 2-perf
- 16mm
- 首演时间戳 | 15240960000000
- 操作
- 比较运算符(==, <, <=, >, >=)
- 加法
- 减法
- 缩放(乘法和除法)
- 除余
- 取模
- 负数
- 绝对值
- 重新计算帧计数(以新的帧率)
- 灵活解析
- 部分时间码 | '1:12'
- 部分运行时间 | '1.5'
- 负字符串值 | '-1:12', '-3+00'
- 格式不正确的tc | '1:13:4'
- 内置常量用于常见帧率
目标
- 解析和获取所有时间码表示
- 干净、简洁的API
- 支持所有对时间码有意义的应用程序
非目标
- 实时时间码生成器
致谢
Drop-Frame计算借鉴自 David Heidelberger的博客。
Logo由 Freepik(来自 www.flaticon.com)制作
作者
- Billy Peake:初始工作
- Jamie Hardt:35mm, 3perf & 16mm格式支持
依赖
~2.5–3.5MB
~62K SLoC