Vtc.Timecode (vtc v0.3.4) View Source

Represents the frame at a particular time in a video.

New Timecode values are created with the with_seconds/2 and with_frames/2, and other function prefaced by with_*.

Link to this section Summary

Types

t()

Timecode type.

Functions

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.

Divides dividend by divisor. The result will inherit the framerate of dividend and be floored to the nearest frame.

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

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.

Scales a by b. 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 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.

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/2, but raises on error.

Returns a new Timecode with a premiere_ticks/1 return value equal to the ticks arg.

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

As with_seconds/2, but raises on error.

Link to this section Types

Specs

parse_result() :: {:ok, t()} | {:error, Vtc.Timecode.ParseError.t()}

Type returned by with_seconds/2 and with_frames/2.

Specs

t() :: %Vtc.Timecode{rate: Vtc.Framerate.t(), seconds: Vtc.Utils.Rational.t()}

Timecode type.

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.

Link to this section Functions

Specs

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

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 a. This is mostly to support quick scripting. This function will raise if there is an error parsing b.

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

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

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

Specs

compare(a :: 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.

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 a. This is mostly to support quick scripting. This function will raise if there is an error parsing b.

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

Specs

div(dividend :: t(), divisor :: Ratio.t() | number()) :: t()

Divides dividend by divisor. The result will inherit the framerate of dividend and be floored to the nearest frame.

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

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

divmod(dividend, divisor)

View Source

Specs

divmod(dividend :: t(), divisor :: Ratio.t() | number()) :: {t(), t()}

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

If division would result in a non-whole-frame quotient, that value is floored before the remainder is calculated.

If the remainder would result in a non-whole-frame value, it is rounded.

Examples

iex> dividend = Timecode.with_frames!("01:00:00:01", Rates.f23_98())
iex> Timecode.divmod(dividend, 4) |> inspect()
"{<00:15:00:00 @ <23.98 NTSC NDF>>, <00:00:00:01 @ <23.98 NTSC NDF>>}"
Link to this function

feet_and_frames(timecode)

View Source

Specs

feet_and_frames(t()) :: String.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'.

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

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.

Specs

frames(t()) :: integer()

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

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

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

Specs

mult(a :: t(), b :: Ratio.t() | number()) :: 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 at that rate.

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

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

premiere_ticks(timecode)

View Source

Specs

premiere_ticks(t()) :: integer()

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

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

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

Specs

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

iex> timecode = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> {:ok, rebased} = Timecode.rebase(timecode, Rates.f47_95())
iex> Timecode.to_string(rebased)
"<00:30:00:00 @ <47.95 NTSC NDF>>"
Link to this function

rebase!(timecode, new_rate)

View Source

Specs

rebase!(t(), Vtc.Framerate.t()) :: t()

As rebase/2, but raises on error.

Link to this function

runtime(timecode, precision)

View Source

Specs

runtime(t(), integer()) :: String.t()

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

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

• 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

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 NDF>> has a true runtime of '01:00:03.6'

Specs

sections(t()) :: Vtc.Timecode.Sections.t()

The individual sections of a timecode string as i64 values.

Specs

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

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 a. This is mostly to support quick scripting. This function will raise if there is an error parsing b.

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

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

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

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

Specs

timecode(t()) :: 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.

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

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.

Specs

to_string(t()) :: String.t()
Link to this function

with_frames(frames, rate)

View Source

Specs

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

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.

Link to this function

with_frames!(frames, rate)

View Source

Specs

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

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

Link to this function

with_premiere_ticks(ticks, rate)

View Source

Specs

Returns a new Timecode with a premiere_ticks/1 return value equal to the ticks arg.

Arguments

  • ticks: Any value that can represent the number of ticks for a given timecode. Must implement the PremiereTicks protocol.

  • rate: Frame-per-second playback value of the timecode.

Link to this function

with_premiere_ticks!(ticks, rate)

View Source

Specs

with_premiere_ticks!(Vtc.Source.Frames.t(), Vtc.Framerate.t()) :: t()

As with_premiere_ticks/2, but raises on error.

Link to this function

with_seconds(seconds, rate)

View Source

Specs

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

Arguments

  • seconds: A value which can be represented as a number of seconds. Must implement the Seconds protocol.

  • rate: Frame-per-second playback value of the timecode.

Link to this function

with_seconds!(seconds, rate)

View Source

Specs

with_seconds!(Vtc.Source.Seconds.t(), Vtc.Framerate.t()) :: t()

As with_seconds/2, but raises on error.