View Source Vtc.Timecode (vtc v0.7.0)
Represents the frame at a particular time in a video.
New Timecode values are created with the with_seconds/3
and with_frames/2
, and
other function prefaced by with_*
.
struct-fields
Struct Fields
seconds
: The real-world seconds elapsed since 01:00:00:00 as a rational value. (Note: The Ratio module automatically will coerce itself to an integer whenever possible, so this value may be an integer when exactly a whole-second value).rate
: the Framerate of the timecode.
sorting-support
Sorting Support
Timecode
implements compare/2
, and as such, can be used wherever the standard
library calls for a Sorter
module. Let's see it in action:
iex> tc_01 = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> tc_02 = Timecode.with_frames!("02:00:00:00", Rates.f23_98())
iex>
iex>
iex> Enum.sort([tc_02, tc_01], Timecode) |> inspect()
"[<01:00:00:00 <23.98 NTSC>>, <02:00:00:00 <23.98 NTSC>>]"
iex>
iex>
iex> Enum.sort([tc_01, tc_02], {:desc, Timecode}) |> inspect()
"[<02:00:00:00 <23.98 NTSC>>, <01:00:00:00 <23.98 NTSC>>]"
iex>
iex>
iex> Enum.max([tc_02, tc_01], Timecode) |> inspect()
"<02:00:00:00 <23.98 NTSC>>"
iex>
iex>
iex> Enum.min([tc_02, tc_01], Timecode) |> inspect()
"<01:00:00:00 <23.98 NTSC>>"
iex>
iex>
iex> data_01 = %{id: 2, tc: tc_01}
iex> data_02 = %{id: 1, tc: tc_02}
iex> Enum.sort_by([data_02, data_01], &(&1.tc), Timecode) |> inspect()
"[%{id: 2, tc: <01:00:00:00 <23.98 NTSC>>}, %{id: 1, tc: <02:00:00:00 <23.98 NTSC>>}]"
Link to this section Summary
Types
As round/0
, but includes :off
option to disable rounding entirely. Not all
functions exposed by this module make logical sense without some form of rouding, so
:off
will not be accepted by all functions.
Type returned by with_seconds/3
and with_frames/3
.
Valid values for rounding options.
Timecode
type.
Functions
Returns the absolute value of tc
.
Adds two timecodoes together using their real-world seconds representation. When the
rates of a
and b
are not equal, the result will inheret the framerat of a
and
be rounded to the seconds representation of the nearest whole-frame at that rate.
Returns whether a
is greater than, equal to, or less than b
in terms of real-world
seconds. Compatible with Enum.sort/2
.
Divides dividend
by divisor
. The result will inherit the framerate of dividend
and rounded to the nearest whole-frame based on the :round
option.
Divides the total frame count of dividend
by divisor
and returns both a quotient
and a remainder as Timecode values.
Returns true
if a
is eqaul to b
.
Evalute timecode mathematical expression in a do
block. Any code captured within
this macro can use Kernel operators to work with timecode values instead of module
functions like add/2
.
Returns the number of feet and frames this timecode represents if it were shot on 35mm 4-perf film (16 frames per foot). ex: '5400+13'.
Returns the number of frames that would have elapsed between 00:00:00:00 and this timecode.
Returns true
if a
is greater than b
.
Returns true
if a
is greater than or eqaul to b
.
Returns true
if a
is less than b
.
Returns true
if a
is less than or equal to b
.
Scales a
by b
. The result will inheret the framerat of a
and be rounded to the
seconds representation of the nearest whole-frame based on the :round
option.
Returns the number of elapsed ticks this timecode represents in Adobe Premiere Pro.
Rebases the timecode to a new framerate.
As rebase/2
, but raises on error.
Devides the total frame count of dividend
by devisor
, rounds the quotient down,
and returns the remainder rounded to the nearest frame.
Runtime Returns the true, real-world runtime of the timecode in HH:MM:SS.FFFFFFFFF format.
The individual sections of a timecode string as i64 values.
Subtracts two timecodoes together using their real-world seconds representation. When
the rates of a
and b
are not equal, the result will inheret the framerat of a
and be rounded to the seconds representation of the nearest whole-frame at that rate.
Returns the the formatted SMPTE timecode: (ex: 01:00:00:00). Drop frame timecode will be rendered with a ';' sperator before the frames field.
Returns a new Timecode
with a frames/1
return value equal to the frames
arg.
As Timecode.with_frames/3
, but raises on error.
Returns a new Timecode
with a Timecode.seconds
field value equal to the
seconds
arg.
As with_seconds/3
, but raises on error.
Link to this section Types
@type maybe_round() :: round() | :off
As round/0
, but includes :off
option to disable rounding entirely. Not all
functions exposed by this module make logical sense without some form of rouding, so
:off
will not be accepted by all functions.
@type parse_result() :: {:ok, t()} | {:error, Vtc.Timecode.ParseError.t() | %ArgumentError{__exception__: true, message: term()}}
Type returned by with_seconds/3
and with_frames/3
.
@type round() :: :closest | :floor | :ceil
Valid values for rounding options.
:closest
: Round the to the closet whole frame.:floor
: Always round down to the closest whole-frame.:ciel
: Always round up to the closest whole-frame.
@type t() :: %Vtc.Timecode{rate: Vtc.Framerate.t(), seconds: Ratio.t()}
Timecode
type.
Link to this section Functions
Returns the absolute value of tc
.
examples
Examples
iex> tc = Timecode.with_frames!("-01:00:00:00", Rates.f23_98())
iex> Timecode.abs(tc) |> inspect()
"<01:00:00:00 <23.98 NTSC>>"
iex> tc = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.abs(tc) |> inspect()
"<01:00:00:00 <23.98 NTSC>>"
@spec add( a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t(), opts :: [{:round, maybe_round()}] ) :: t()
Adds two timecodoes together using their real-world seconds representation. When the
rates of a
and b
are not equal, the result will inheret the framerat of a
and
be rounded to the seconds representation of the nearest whole-frame at that rate.
As long as one argument is a Timecode
value, a
or b
May be any value that
implements the Frames
protocol, such as a timecode string, and will be assumed to be
the same framerate as the other. This is mostly to support quick scripting. Will raise
if there is an error parsing a Frames
value.
options
Options
round
: How to round the result with respect to whole-frames when mixing framerates. Default::closest
.
examples
Examples
Two timecodes running at the same rate:
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("01:30:21:17", Rates.f23_98())
iex> Timecode.add(a, b) |> inspect()
"<02:30:21:17 <23.98 NTSC>>"
Two timecodes running at different rates:
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("00:00:00:02", Rates.f47_95())
iex> Timecode.add(a, b) |> inspect()
"<01:00:00:01 <23.98 NTSC>>"
Using a timcode and a bare string:
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.add(a, "01:30:21:17") |> inspect()
"<02:30:21:17 <23.98 NTSC>>"
@spec compare(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) :: :lt | :eq | :gt
Returns whether a
is greater than, equal to, or less than b
in terms of real-world
seconds. Compatible with Enum.sort/2
.
Argument Autocasting
As long as one argument is a
Timecode
value,a
orb
May be any value that implements theFrames
protocol, such as a timecode string, and will be assumed to be the same framerate as the other. This is mostly to support quick scripting. Will
Raises
Raises if there is an error parsing a
Frames
value from either argument.
Sorting with Timecodes
This function can be used anyware the standard library expexts a
sorter
. See top-levelTimecode
docs for more information.
examples
Examples
Using two timecodes, 01:00:00:00
NTSC is greater than 01:00:00:00
true because it
represents more real-world time.
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("01:00:00:00", Rates.f24())
iex> :gt = Timecode.compare(a, b)
Using a timcode and a bare string:
iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> :eq = Timecode.compare(timecode, "01:00:00:00")
@spec div( dividend :: t(), divisor :: Ratio.t() | number(), opts :: [{:round, maybe_round()}] ) :: t()
Divides dividend
by divisor
. The result will inherit the framerate of dividend
and rounded to the nearest whole-frame based on the :round
option.
options
Options
round
: How to round the result with respect to whole-frame values. Defaults to:floor
to matchdivmod
and the expected meaning ofdiv
to mean integer division in elixir.
examples
Examples
iex> dividend = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.div(dividend, 2) |> inspect()
"<00:30:00:00 <23.98 NTSC>>"
iex> dividend = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.div(dividend, 0.5) |> inspect()
"<02:00:00:00 <23.98 NTSC>>"
@spec divrem( dividend :: t(), divisor :: Ratio.t() | number(), opts :: [round_frames: round(), round_remainder: round()] ) :: {t(), t()}
Divides the total frame count of dividend
by divisor
and returns both a quotient
and a remainder as Timecode values.
The quotient returned is equivalent to Timecode.div/3
with the :round
option set
to :floor
.
options
Options
round_frames
: How to round the frame count before doing the divrem operation. Default::closest
.round_remainder
: How to round the remainder frames when a non-whole frame would be the result. Default::closest
.
examples
Examples
iex> dividend = Timecode.with_frames!("01:00:00:01", Rates.f23_98())
iex> Timecode.divrem(dividend, 4) |> inspect()
"{<00:15:00:00 <23.98 NTSC>>, <00:00:00:01 <23.98 NTSC>>}"
@spec eq?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) :: boolean()
Returns true
if a
is eqaul to b
.
Argument Autocasting
As long as one argument is a
Timecode
value,a
orb
May be any value that implements theFrames
protocol, such as a timecode string, and will be assumed to be the same framerate as the other. This is mostly to support quick scripting. Will
Raises
Raises if there is an error parsing a
Frames
value from either argument.
@spec eval( [at: Vtc.Framerate.t() | number() | Ratio.t(), ntsc: Vtc.Framerate.ntsc()], Macro.input() ) :: Macro.t()
Evalute timecode mathematical expression in a do
block. Any code captured within
this macro can use Kernel operators to work with timecode values instead of module
functions like add/2
.
options
Options
at
: The Framerate to cast non-timecode values to. If this value is not set, then at least one value in each operation must be aTimecode
. This value can be any value accepted byFramerate.new/2
.ntsc
: Thentsc
value to use when creating a new Framerate withat
. Not needed ifat
is aFramerate
value.
examples
Examples
Use eval to do some quick math. The block captures variables from the outer scope,
but contains the expression within its own scope, just like an if
or with
statement.
iex> require Timecode
iex>
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("00:30:00:00", Rates.f23_98())
iex> c = Timecode.with_frames!("00:15:00:00", Rates.f23_98())
iex>
iex> result = Timecode.eval do
iex> a + b * 2 - c
iex> end
iex>
iex> inspect(result)
"<01:45:00:00 <23.98 NTSC>>"
Or if you want to do it in one line:
iex> require Timecode
iex>
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("00:30:00:00", Rates.f23_98())
iex> c = Timecode.with_frames!("00:15:00:00", Rates.f23_98())
iex>
iex> result = Timecode.eval(a + b * 2 - c)
iex>
iex> inspect(result)
"<01:45:00:00 <23.98 NTSC>>"
Just like the regular Timecode
functions, only one value in an arithmatic expression
needs to be a Timecode
value. In the case above, since multiplication happens first,
that's b
:
iex> b = Timecode.with_frames!("00:30:00:00", Rates.f23_98())
iex>
iex> result = Timecode.eval do
iex> "01:00:00:00" + b * 2 - "00:15:00:00"
iex> end
iex>
iex> inspect(result)
"<01:45:00:00 <23.98 NTSC>>"
You can supply a default framerate if you just want to do some quick calculations.
This framerate is inherited by every value that implements the Frames
protocol in
the block, including integers:
iex> result = Timecode.eval at: Rates.f23_98() do
iex> "01:00:00:00" + "00:30:00:00" * 2 - "00:15:00:00"
iex> end
iex>
iex> inspect(result)
"<01:45:00:00 <23.98 NTSC>>"
You can use any value that can be parsed by Framerate.new/2
.
iex> result = Timecode.eval at: 23.98 do
iex> "01:00:00:00" + "00:30:00:00" * 2 - "00:15:00:00"
iex> end
iex>
iex> inspect(result)
"<01:45:00:00 <23.98 NTSC>>"
ntsc: :non_drop
is assumed by default, but you can set a different value with the
:ntsc
option:
iex> result = Timecode.eval at: 24, ntsc: nil do
iex> "01:00:00:00" + "00:30:00:00" * 2 - "00:15:00:00"
iex> end
iex>
iex> inspect(result)
"<01:45:00:00 <24.0 fps>>"
@spec feet_and_frames(t(), opts :: [format: Vtc.FilmFormat.t(), round: round()]) :: Vtc.Source.Frames.FeetAndFrames.t()
Returns the number of feet and frames this timecode represents if it were shot on 35mm 4-perf film (16 frames per foot). ex: '5400+13'.
options
Options
round
: How to round the internal frame count before conversion.
what-it-is
What it is
On physical film, each foot contains a certain number of frames. For 35mm, 4-perf film (the most common type on Hollywood movies), this number is 16 frames per foot. Feet-And-Frames was often used in place of Keycode to quickly reference a frame in the edit.
where-you-see-it
Where you see it
For the most part, feet + frames has died out as a reference, because digital media is not measured in feet. The most common place it is still used is Studio Sound Departments. Many Sound Mixers and Designers intuitively think in feet + frames, and it is often burned into the reference picture for them.
Telecine.
Sound turnover reference picture.
Sound turnover change lists.
Returns the number of frames that would have elapsed between 00:00:00:00 and this timecode.
options
Options
round
: How to round the resulting frame number.
what-it-is
What it is
Frame number / frames count is the number of a frame if the timecode started at 00:00:00:00 and had been running until the current value. A timecode of '00:00:00:10' has a frame number of 10. A timecode of '01:00:00:00' has a frame number of 86400.
where-you-see-it
Where you see it
Frame-sequence files: 'my_vfx_shot.0086400.exr'
FCP7XML cut lists:
<timecode> <rate> <timebase>24</timebase> <ntsc>TRUE</ntsc> </rate> <string>01:00:00:00</string> <frame>86400</frame> <!-- <====THIS LINE--> <displayformat>NDF</displayformat> </timecode>
@spec gt?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) :: boolean()
Returns true
if a
is greater than b
.
Argument Autocasting
As long as one argument is a
Timecode
value,a
orb
May be any value that implements theFrames
protocol, such as a timecode string, and will be assumed to be the same framerate as the other. This is mostly to support quick scripting. Will
Raises
Raises if there is an error parsing a
Frames
value from either argument.
@spec gte?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) :: boolean()
Returns true
if a
is greater than or eqaul to b
.
Argument Autocasting
As long as one argument is a
Timecode
value,a
orb
May be any value that implements theFrames
protocol, such as a timecode string, and will be assumed to be the same framerate as the other. This is mostly to support quick scripting. Will
Raises
Raises if there is an error parsing a
Frames
value from either argument.
@spec lt?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) :: boolean()
Returns true
if a
is less than b
.
Argument Autocasting
As long as one argument is a
Timecode
value,a
orb
May be any value that implements theFrames
protocol, such as a timecode string, and will be assumed to be the same framerate as the other. This is mostly to support quick scripting. Will
Raises
Raises if there is an error parsing a
Frames
value from either argument.
examples
Examples
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("02:00:00:00", Rates.f23_98())
iex> true = Timecode.lt?(a, b)
iex> false = Timecode.lt?(b, a)
@spec lte?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) :: boolean()
Returns true
if a
is less than or equal to b
.
Argument Autocasting
As long as one argument is a
Timecode
value,a
orb
May be any value that implements theFrames
protocol, such as a timecode string, and will be assumed to be the same framerate as the other. This is mostly to support quick scripting. Will
Raises
Raises if there is an error parsing a
Frames
value from either argument.
As the kernel -/1
function.
- Makes a positive
tc
value negative. - Makes a negative
tc
value positive.
examples
Examples
iex> tc = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.minus(tc) |> inspect()
"<-01:00:00:00 <23.98 NTSC>>"
iex> tc = Timecode.with_frames!("-01:00:00:00", Rates.f23_98())
iex> Timecode.minus(tc) |> inspect()
"<01:00:00:00 <23.98 NTSC>>"
@spec mult(a :: t(), b :: Ratio.t() | number(), opts :: [{:round, maybe_round()}]) :: t()
Scales a
by b
. The result will inheret the framerat of a
and be rounded to the
seconds representation of the nearest whole-frame based on the :round
option.
options
Options
round
: How to round the result with respect to whole-frame values. Defaults to:closest
.
examples
Examples
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.mult(a, 2) |> inspect()
"<02:00:00:00 <23.98 NTSC>>"
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.mult(a, 0.5) |> inspect()
"<00:30:00:00 <23.98 NTSC>>"
Returns the number of elapsed ticks this timecode represents in Adobe Premiere Pro.
options
Options
round
: How to round the resulting ticks.
what-it-is
What it is
Internally, Adobe Premiere Pro uses ticks to divide up a second, and keep track of how far into that second we are. There are 254016000000 ticks in a second, regardless of framerate in Premiere.
where-you-see-it
Where you see it
Premiere Pro Panel functions and scripts.
FCP7XML cutlists generated from Premiere:
<clipitem id="clipitem-1"> ... <in>158</in> <out>1102</out> <pproTicksIn>1673944272000</pproTicksIn> <pproTicksOut>11675231568000</pproTicksOut> ... </clipitem>
@spec rebase(t(), Vtc.Framerate.t()) :: parse_result()
Rebases the timecode to a new framerate.
The real-world seconds are recalculated using the same frame count as if they were
being played back at new_rate
instead of timecode.rate
.
examples
Examples
iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> {:ok, rebased} = Timecode.rebase(timecode, Rates.f47_95())
iex> inspect(rebased)
"<00:30:00:00 <47.95 NTSC>>"
@spec rebase!(t(), Vtc.Framerate.t()) :: t()
As rebase/2
, but raises on error.
@spec rem( dividend :: t(), divisor :: Ratio.t() | number(), opts :: [round_frames: round(), round_remainder: round()] ) :: t()
Devides the total frame count of dividend
by devisor
, rounds the quotient down,
and returns the remainder rounded to the nearest frame.
options
Options
round_frames
: How to round the frame count before doing the rem operation. Default::closest
.round_remainder
: How to round the remainder frames when a non-whole frame would be the result.
examples
Examples
iex> dividend = Timecode.with_frames!("01:00:00:01", Rates.f23_98())
iex> Timecode.rem(dividend, 4) |> inspect()
"<00:00:00:01 <23.98 NTSC>>"
Runtime Returns the true, real-world runtime of the timecode in HH:MM:SS.FFFFFFFFF format.
Arguments
precision
: The number of places to round to. Extra trailing 0's will still be trimmed.
what-it-is
What it is
The formatted version of seconds. It looks like timecode, but with a decimal seconds value instead of a frame number place.
where-you-see-it
Where you see it
• Anywhere real-world time is used.
• FFMPEG commands:
ffmpeg -ss 00:00:30.5 -i input.mov -t 00:00:10.25 output.mp4
note
Note
The true runtime will often diverge from the hours, minutes, and seconds value of the timecode representation when dealing with non-whole-frame framerates. Even drop-frame timecode does not continuously adhere 1:1 to the actual runtime. For instance, <01:00:00;00 <29.97 NTSC DF>> has a true runtime of '00:59:59.9964', and <01:00:00:00 <23.98 NTSC>> has a true runtime of '01:00:03.6'
@spec sections(t(), opts :: [{:round, round()}]) :: Vtc.Timecode.Sections.t()
The individual sections of a timecode string as i64 values.
@spec sub( a :: t(), b :: t() | Vtc.Source.Frames.t(), opts :: [{:round, maybe_round()}] ) :: t()
Subtracts two timecodoes together using their real-world seconds representation. When
the rates of a
and b
are not equal, the result will inheret the framerat of a
and be rounded to the seconds representation of the nearest whole-frame at that rate.
As long as one argument is a Timecode
value, a
or b
May be any value that
implements the Frames
protocol, such as a timecode string, and will be assumed to be
the same framerate as the other. This is mostly to support quick scripting. Will raise
if there is an error parsing a Frames
value.
options
Options
round
: How to round the result with respect to whole-frames when mixing framerates. Default::closest
.
examples
Examples
Two timecodes running at the same rate:
iex> a = Timecode.with_frames!("01:30:21:17", Rates.f23_98())
iex> b = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.sub(a, b) |> inspect()
"<00:30:21:17 <23.98 NTSC>>"
When b
is greater than a
, the result is negative:
iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("02:00:00:00", Rates.f23_98())
iex> Timecode.sub(a, b) |> inspect()
"<-01:00:00:00 <23.98 NTSC>>"
Two timecodes running at different rates:
iex> a = Timecode.with_frames!("01:00:00:02", Rates.f23_98())
iex> b = Timecode.with_frames!("00:00:00:02", Rates.f47_95())
iex> Timecode.sub(a, b) |> inspect()
"<01:00:00:01 <23.98 NTSC>>"
Using a timcode and a bare string:
iex> a = Timecode.with_frames!("01:30:21:17", Rates.f23_98())
iex> Timecode.sub(a, "01:00:00:00") |> inspect()
"<00:30:21:17 <23.98 NTSC>>"
Returns the the formatted SMPTE timecode: (ex: 01:00:00:00). Drop frame timecode will be rendered with a ';' sperator before the frames field.
options
Options
round
: How to round the resulting frames field.
what-it-is
What it is
Timecode is used as a human-readable way to represent the id of a given frame. It is formatted to give a rough sense of where to find a frame: {HOURS}:{MINUTES}:{SECONDS}:{FRAME}. For more on timecode, see Frame.io's excellent post on the subject.
where-you-see-it
Where you see it
Timecode is ubiquitous in video editing, a small sample of places you might see timecode:
- Source and Playback monitors in your favorite NLE.
- Burned into the footage for dailies.
- Cut lists like an EDL.
@spec with_frames(Vtc.Source.Frames.t(), Vtc.Framerate.t()) :: parse_result()
Returns a new Timecode
with a frames/1
return value equal to the frames
arg.
arguments
Arguments
frames
: A value which can be represented as a frame number / frame count. Must implement theFrames
protocol.rate
: Frame-per-second playback value of the timecode.
options
Options
round
: How to round the result with regards to whole-frames.
examples
Examples
Accepts timecode strings...
iex> Timecode.with_frames("01:00:00:00", Rates.f23_98) |> inspect()
"{:ok, <01:00:00:00 <23.98 NTSC>>}"
... feet+frames strings...
iex> Timecode.with_frames("5400+00", Rates.f23_98) |> inspect()
"{:ok, <01:00:00:00 <23.98 NTSC>>}"
... integers...
iex> Timecode.with_frames(86400, Rates.f23_98) |> inspect()
"{:ok, <01:00:00:00 <23.98 NTSC>>}"
... and integer strings.
iex> Timecode.with_frames("86400", Rates.f23_98) |> inspect()
"{:ok, <01:00:00:00 <23.98 NTSC>>}"
@spec with_frames!(Vtc.Source.Frames.t(), Vtc.Framerate.t()) :: t()
As Timecode.with_frames/3
, but raises on error.
@spec with_seconds( Vtc.Source.Seconds.t(), Vtc.Framerate.t(), opts :: [{:round, maybe_round()}] ) :: parse_result()
Returns a new Timecode
with a Timecode.seconds
field value equal to the
seconds
arg.
arguments
Arguments
seconds
: A value which can be represented as a number of real-world seconds. Must implement theSeconds
protocol.rate
: Frame-per-second playback value of the timecode.
options
Options
round
: How to round the result with regards to whole-frames.
examples
Examples
Accetps runtime strings...
iex> Timecode.with_seconds("01:00:00.5", Rates.f23_98) |> inspect()
"{:ok, <00:59:56:22 <23.98 NTSC>>}"
... floats...
iex> Timecode.with_seconds(3600.5, Rates.f23_98) |> inspect()
"{:ok, <00:59:56:22 <23.98 NTSC>>}"
... integers...
iex> Timecode.with_seconds(3600, Rates.f23_98) |> inspect()
"{:ok, <00:59:56:10 <23.98 NTSC>>}"
... integer Strings...
iex> Timecode.with_seconds("3600", Rates.f23_98) |> inspect()
"{:ok, <00:59:56:10 <23.98 NTSC>>}"
... and float strings.
iex> Timecode.with_seconds("3600.5", Rates.f23_98) |> inspect()
"{:ok, <00:59:56:22 <23.98 NTSC>>}"
premiere-ticks
Premiere Ticks
The Vtc.Source.Seconds.PremiereTicks
struck implements the Vtc.Source.Seconds
protocol and can be used to parse the format. This struct is not a general-purpose
Module for the unit, and only exists to hint to the parsing function how it should be
processed:
iex> alias Vtc.Source.Seconds.PremiereTicks
iex>
iex> input = %PremiereTicks{in: 254_016_000_000}
iex> Timecode.with_seconds!(input, Rates.f23_98()) |> inspect()
"<00:00:01:00 <23.98 NTSC>>"
@spec with_seconds!( Vtc.Source.Seconds.t(), Vtc.Framerate.t(), opts :: [{:round, maybe_round()}] ) :: t()
As with_seconds/3
, but raises on error.
@spec with_seconds_round_to_frame(Ratio.t(), Vtc.Framerate.t(), maybe_round()) :: Ratio.t()