View Source Vtc.Timecode (vtc v0.8.0)

Represents a particular frame in a video clip.

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>>}]"

arithmatic-autocasting

Arithmatic Autocasting

For operators that take two timecode values, likt add/3 or compare/2, 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.

If parsing the value fails during casting, the function raises a Vtc.Timecode.ParseError.

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.

t()

Timecode type.

Parse

Returns a new Timecode with a frames/2 return value equal to the frames arg.

As Timecode.with_frames/3, but raises on error.

Returns a new Timecode with a :seconds field value equal to the seconds arg.

Manipulate

Rebases timecode to a new framerate.

As rebase/2, but raises on error.

Compare

Comapare the values of a and b.

Returns true if a is eqaul to b.

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.

Arithmatic

Returns the absolute value of tc.

Add two timecodes.

Divides dividend by divisor.

Divides the total frame count of dividend by divisor and returns both a quotient and a remainder.

Evalutes timecode mathematical expressions in a do block.

As the kernel -/1 function.

Scales a by b.

Devides the total frame count of dividend by devisor, and returns the remainder.

Subtract b from a.

Convert

Returns the number of physical film feet and frames timecode represents if shot on film.

Returns the number of frames that would have elapsed between 00:00:00:00 and timecode.

Returns the number of elapsed ticks timecode represents in Adobe Premiere Pro.

Runtime Returns the true, real-world runtime of timecode in HH:MM:SS.FFFFFFFFF format.

The individual sections of a timecode string as i64 values.

Returns the the formatted SMPTE timecode

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 Parse

Link to this function

with_frames(frames, rate)

View Source
@spec with_frames(Vtc.Source.Frames.t(), Vtc.Framerate.t()) :: parse_result()

Returns a new Timecode with a frames/2 return value equal to the frames arg.

arguments

Arguments

  • frames: A value which can be represented as a frame number / frame count. Must implement the Frames 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>>}"

By default, feet+frames is interpreted as 35mm, 4perf film. You can use the FeetAndFrames struct to parse other film formats:

iex> alias Vtc.Source.Frames.FeetAndFrames
iex>
iex> {:ok, feet_and_frames} = FeetAndFrames.from_string("5400+00", film_format: :ff16mm)
iex> Timecode.with_frames(feet_and_frames, Rates.f23_98()) |> inspect()
"{:ok, <01:15: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>>}"
Link to this function

with_frames!(frames, rate)

View Source
@spec with_frames!(Vtc.Source.Frames.t(), Vtc.Framerate.t()) :: t()

As Timecode.with_frames/3, but raises on error.

Link to this function

with_seconds(seconds, rate, opts \\ [])

View Source
@spec with_seconds(
  Vtc.Source.Seconds.t(),
  Vtc.Framerate.t(),
  opts :: [{:round, maybe_round()}]
) ::
  parse_result()

Returns a new Timecode with a :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 the Seconds 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 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>>"
Link to this function

with_seconds!(seconds, rate, opts \\ [])

View Source
@spec with_seconds!(
  Vtc.Source.Seconds.t(),
  Vtc.Framerate.t(),
  opts :: [{:round, maybe_round()}]
) :: t()

As with_seconds/3, but raises on error.

Link to this section Manipulate

@spec rebase(t(), Vtc.Framerate.t()) :: parse_result()

Rebases 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>>"
Link to this function

rebase!(timecode, new_rate)

View Source
@spec rebase!(t(), Vtc.Framerate.t()) :: t()

As rebase/2, but raises on error.

Link to this section Compare

@spec compare(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) ::
  :lt | :eq | :gt

Comapare the values of a and b.

Compatible with Enum.sort/2. For more on sorting non-builtin values, see the Elixir ducumentation.

auto-casts Frames values. See eq?/2 for more information on how equality is determined.

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 eq?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) ::
  boolean()

Returns true if a is eqaul to b.

auto-casts Frames values.

examples

Examples

iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> true = Timecode.eq?(a, b)

Timecodes with the same string representation, but different real-world seconds values, are not equal:

iex> a = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> b = Timecode.with_frames!("01:00:00:00", Rates.f24())
iex> false = Timecode.eq?(a, b)

But Timecodes with the different string representation, but the same real-world seconds values, are equal:

iex> a = Timecode.with_frames!("01:00:00:12", Rates.f23_98())
iex> b = Timecode.with_frames!("01:00:00:24", Rates.f47_95())
iex> true = Timecode.eq?(a, b)
@spec gt?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) ::
  boolean()

Returns true if a is greater than b.

auto-casts Frames values. See eq?/2 for more information on how equality is determined.

@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.

auto-casts Frames values. See eq?/2 for more information on how equality is determined.

@spec lt?(a :: t() | Vtc.Source.Frames.t(), b :: t() | Vtc.Source.Frames.t()) ::
  boolean()

Returns true if a is less than b.

auto-casts Frames values. See eq?/2 for more information on how equality is determined.

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.

auto-casts Frames values. See eq?/2 for more information on how equality is determined.

Link to this section Arithmatic

@spec abs(t()) :: t()

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()

Add two timecodes.

Uses the 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.

auto-casts Frames values.

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>>"
Link to this function

div(dividend, divisor, opts \\ [])

View Source
@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 match divmod and the expected meaning of div 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>>"
Link to this function

divrem(dividend, divisor, opts \\ [])

View Source
@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.

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>>}"
Link to this macro

eval(opts \\ [], body)

View Source (macro)
@spec eval(
  [at: Vtc.Framerate.t() | number() | Ratio.t(), ntsc: Vtc.Framerate.ntsc()],
  Macro.input()
) ::
  Macro.t()

Evalutes timecode mathematical expressions 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 a Timecode. This value can be any value accepted by Framerate.new/2.

  • ntsc: The ntsc value to use when creating a new Framerate with at. Not needed if at is a Framerate 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 minus(t()) :: t()

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>>"
Link to this function

rem(dividend, divisor, opts \\ [])

View Source
@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, and returns the remainder.

The quotient is floored before the remainder is calculated.

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. Default: :closest.

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>>"
@spec sub(
  a :: t(),
  b :: t() | Vtc.Source.Frames.t(),
  opts :: [{:round, maybe_round()}]
) :: t()

Subtract b from a.

Uses 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.

auto-casts Frames values.

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>>"

Link to this section Convert

Link to this function

feet_and_frames(timecode, opts \\ [])

View Source
@spec feet_and_frames(t(), opts :: [fiim_format: Vtc.FilmFormat.t(), round: round()]) ::
  Vtc.Source.Frames.FeetAndFrames.t()

Returns the number of physical film feet and frames timecode represents if shot on film.

Ex: '5400+13'.

options

Options

  • round: How to round the internal frame count before conversion. Default: :closest.

  • fiim_format: The film format to use when doing the calculation. For more on film formats, see Vtc.FilmFormat. Default: :ff35mm_4perf, by far the most common format used to shoot Hollywood movies.

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.

For more information on individual film formats, see the Vtc.FilmFormat module.

examples

Examples

Defaults to 35mm, 4perf:

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.feet_and_frames(timecode) |> inspect()
"<5400+00 :ff35mm_4perf>"

Use String.Chars to convert the resulting struct to a traditional F=F string:

iex> alias Vtc.Source.Frames.FeetAndFrames
iex>
iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.feet_and_frames(timecode) |> String.Chars.to_string()
"5400+00"

Outputting as a different film format:

examples-1

Examples

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.feet_and_frames(timecode, film_format: :ff16mm) |> inspect()
"<4320+00 :ff16mm>"
Link to this function

frames(timecode, opts \\ [])

View Source
@spec frames(t(), opts :: [{:round, round()}]) :: integer()

Returns the number of frames that would have elapsed between 00:00:00:00 and 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>

examples

Examples

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.frames(timecode)
86400
Link to this function

premiere_ticks(timecode, opts \\ [])

View Source
@spec premiere_ticks(t(), opts :: [{:round, round()}]) :: integer()

Returns the number of elapsed ticks 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>

examples

Examples

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.premiere_ticks(timecode)
915372057600000
Link to this function

runtime(timecode, opts \\ [])

View Source
@spec runtime(t(), precision: non_neg_integer(), trim_zeros?: boolean()) :: String.t()

Runtime Returns the true, real-world runtime of timecode in HH:MM:SS.FFFFFFFFF format.

Trailing zeroes are trimmed from the end of the return value. If the entire fractal seconds value would be trimmed, '.0' is used.

options

Options

  • precision: The number of places to round to. Extra trailing 0's will still be trimmed. Default: 9.

  • trim_zeros?: Whether to trim trailing zeroes. Default: true.

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'

examples

Examples

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.runtime(timecode)
"01:00:03.6"
Link to this function

sections(timecode, opts \\ [])

View Source
@spec sections(t(), opts :: [{:round, round()}]) :: Vtc.Timecode.Sections.t()

The individual sections of a timecode string as i64 values.

examples

Examples

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> Timecode.sections(timecode) |> inspect()
"%Vtc.Timecode.Sections{negative?: false, hours: 1, minutes: 0, seconds: 0, frames: 0}"
Link to this function

timecode(timecode, opts \\ [])

View Source
@spec timecode(t(), opts :: [{:round, round()}]) :: String.t()

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.

examples

Examples

iex> timecode = Timecode.with_frames!(86400, Rates.f23_98())
iex> Timecode.timecode(timecode)
"01:00:00:00"