View Source Vtc.Range (vtc v0.9.0)

Holds a timecode range.

struct-fields

Struct Fields

  • in: Start TC. Must be less than or equal to out.
  • out: End TC. Must be greater than or equal to in.
  • inclusive: See below for more information. Default: false

inclusive-vs-exclusive-ranges

Inclusive vs. Exclusive Ranges

Inclusive ranges treat the out timecode as the last visible frame of a piece of footage. This style of tc range is most often associated with AVID.

Exclusive timecode ranges treat the out timecode as the boundary where the range ends. This style of tc range is most often associated with Final Cut and Premiere.

In mathematical notation, inclusive ranges are [in, out], while exclusive ranges are [in, out).

Link to this section Summary

Types

Whether the end point should be treated as the Range's boundary (:exclusive), or its last element (:inclusive).

t()

Range struct type.

Parse

As new/3, but raises on error.

Returns a range with an :in value of tc_in and a duration of duration.

As with_duration/3, but raises on error.

Manipulate

Adjusts range to have an exclusive out timecode.

Adjusts range to have an inclusive out timecode.

Inspect

Returns the duration in Timecode of range.

Compare

Returns true if range contains timecode. timecode may be any value that implements Frames.

Returns the the range where a and b overlap/intersect.

As intersection, but returns a Range from 00:00:00:00 - 00:00:00:00 when there is no overlap.

Returns true if there is overlap between a and b.

Returns the range between two, non-overlapping ranges.

As separation, but returns a Range from 00:00:00:00 - 00:00:00:00 when there is overlap.

Link to this section Types

@type out_type() :: :inclusive | :exclusive

Whether the end point should be treated as the Range's boundary (:exclusive), or its last element (:inclusive).

@type t() :: %Vtc.Range{
  in: Vtc.Timecode.t(),
  out: Vtc.Timecode.t(),
  out_type: out_type()
}

Range struct type.

Link to this section Parse

Link to this function

new(tc_in, tc_out, opts \\ [])

View Source
@spec new(
  in_tc :: Vtc.Timecode.t(),
  out_tc :: Vtc.Timecode.t() | Vtc.Source.Frames.t(),
  opts :: [{:out_type, out_type()}]
) :: {:ok, t()} | {:error, Exception.t() | Vtc.Timecode.ParseError.t()}

Creates a new Range.

out_tc may be a Timecode value for any value that implements the Frames protocol.

Returns an error if the resulting range would not have a duration greater or eual to 0, or if tc_in and tc_out do not have the same rate.

examples

Examples

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> tc_out = Timecode.with_frames!("02:00:00:00", Rates.f23_98())
iex> 
iex> result = Range.new(tc_in, tc_out)
iex> inspect(result)
"{:ok, <01:00:00:00 - 02:00:00:00 :exclusive <23.98 NTSC>>}"

Using a timecode string as b:

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> 
iex> result = Range.new(tc_in, "02:00:00:00")
iex> inspect(result)
"{:ok, <01:00:00:00 - 02:00:00:00 :exclusive <23.98 NTSC>>}"

Making a range with an inclusive out:

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> 
iex> result = Range.new(tc_in, "02:00:00:00", out_type: :inclusive)
iex> inspect(result)
"{:ok, <01:00:00:00 - 02:00:00:00 :inclusive <23.98 NTSC>>}"
Link to this function

new!(tc_in, tc_out, opts \\ [])

View Source
@spec new!(Vtc.Timecode.t(), Vtc.Timecode.t(), opts :: [{:out_type, out_type()}]) ::
  t()

As new/3, but raises on error.

Link to this function

with_duration(tc_in, duration, opts \\ [])

View Source
@spec with_duration(
  tc_in :: Vtc.Timecode.t(),
  duration :: Vtc.Timecode.t() | Vtc.Source.Frames.t(),
  opts :: [{:out_type, out_type()}]
) :: {:ok, t()} | {:error, Exception.t() | Vtc.Timecode.ParseError.t()}

Returns a range with an :in value of tc_in and a duration of duration.

duration may be a Timecode value for any value that implements the Frames protocol. Returns an error if duration is less than 0 seconds or if tc_in and tc_out do not have the same rate.

examples

Examples

iex> start_tc = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> duration = Timecode.with_frames!("00:30:00:00", Rates.f23_98())
iex> 
iex> result = Range.with_duration(start_tc, duration)
iex> inspect(result)
"{:ok, <01:00:00:00 - 01:30:00:00 :exclusive <23.98 NTSC>>}"

Using a timecode string as b:

iex> start_tc = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> 
iex> result = Range.with_duration(start_tc, "00:30:00:00")
iex> inspect(result)
"{:ok, <01:00:00:00 - 01:30:00:00 :exclusive <23.98 NTSC>>}"

Making a range with an inclusive out:

iex> start_tc = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> 
iex> result = Range.with_duration(start_tc, "00:30:00:00", out_type: :inclusive)
iex> inspect(result)
"{:ok, <01:00:00:00 - 01:29:59:23 :inclusive <23.98 NTSC>>}"
Link to this function

with_duration!(tc_in, duration, opts \\ [])

View Source
@spec with_duration!(
  Vtc.Timecode.t(),
  Vtc.Timecode.t(),
  opts :: [{:out_type, out_type()}]
) :: t()

As with_duration/3, but raises on error.

Link to this section Manipulate

Link to this function

with_exclusive_out(range)

View Source
@spec with_exclusive_out(t()) :: t()

Adjusts range to have an exclusive out timecode.

examples

Examples

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> range = Range.new!(tc_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> result = Range.with_exclusive_out(range)
iex> inspect(result)
"<01:00:00:00 - 02:00:00:01 :exclusive <23.98 NTSC>>"
Link to this function

with_inclusive_out(range)

View Source
@spec with_inclusive_out(t()) :: t()

Adjusts range to have an inclusive out timecode.

examples

Examples

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> range = Range.new!(tc_in, "02:00:00:00")
iex> 
iex> result = Range.with_inclusive_out(range)
iex> inspect(result)
"<01:00:00:00 - 01:59:59:23 :inclusive <23.98 NTSC>>"

Link to this section Inspect

@spec duration(t()) :: Vtc.Timecode.t()

Returns the duration in Timecode of range.

examples

Examples

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> range = Range.new!(tc_in, "01:30:00:00")
iex> 
iex> result = Range.duration(range)
iex> inspect(result)
"<00:30:00:00 <23.98 NTSC>>"

Link to this section Compare

Link to this function

contains?(range, timecode)

View Source
@spec contains?(t(), Vtc.Timecode.t() | Vtc.Source.Frames.t()) :: boolean()

Returns true if range contains timecode. timecode may be any value that implements Frames.

examples

Examples

iex> tc_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> range = Range.new!(tc_in, "01:30:00:00")
iex> 
iex> Range.contains?(range, "01:10:00:00")
true
iex> Range.contains?(range, "01:40:00:00")
false
@spec intersection(t(), t()) :: {:ok, t()} | {:error, :none}

Returns the the range where a and b overlap/intersect.

Returns nil if the two ranges do not intersect.

a and b do not have to have matching :out_type settings, but the result will inherit a's setting.

examples

Examples

iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("01:50:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "02:30:00:00", out_type: :inclusive)
iex> 
iex> result = Range.intersection(a, b)
iex> inspect(result)
"{:ok, <01:50:00:00 - 02:00:00:00 :inclusive <23.98 NTSC>>}"
iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("02:10:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "03:30:00:00", out_type: :inclusive)
iex> Range.intersection(a, b)
{:error, :none}
@spec intersection!(t(), t()) :: t()

As intersection, but returns a Range from 00:00:00:00 - 00:00:00:00 when there is no overlap.

This returned range inherets the framerate and out_type from a.

examples

Examples

iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("02:10:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "03:30:00:00", out_type: :inclusive)
iex> 
iex> result = Range.intersection!(a, b)
iex> inspect(result)
"<00:00:00:00 - -00:00:00:01 :inclusive <23.98 NTSC>>"
@spec overlaps?(t(), t()) :: boolean()

Returns true if there is overlap between a and b.

examples

Examples

iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("01:50:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "02:30:00:00", out_type: :inclusive)
iex> Range.overlaps?(a, b)
true
iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("02:10:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "03:30:00:00", out_type: :inclusive)
iex> Range.overlaps?(a, b)
false
@spec separation(t(), t()) :: {:ok, t()} | {:error, :none}

Returns the range between two, non-overlapping ranges.

Returns nil if the two ranges are not separated.

a and b do not have to have matching :out_type settings, but the result will inherit a's setting.

examples

Examples

iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("02:10:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "03:30:00:00", out_type: :inclusive)
iex> 
iex> result = Range.separation(a, b)
iex> inspect(result)
"{:ok, <02:00:00:01 - 02:09:59:23 :inclusive <23.98 NTSC>>}"
iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("01:50:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "02:30:00:00", out_type: :inclusive)
iex> Range.separation(a, b)
{:error, :none}
@spec separation!(t(), t()) :: t()

As separation, but returns a Range from 00:00:00:00 - 00:00:00:00 when there is overlap.

This returned range inherets the framerate and out_type from a.

examples

Examples

iex> a_in = Timecode.with_frames!("01:00:00:00", Rates.f23_98())
iex> a = Range.new!(a_in, "02:00:00:00", out_type: :inclusive)
iex> 
iex> b_in = Timecode.with_frames!("01:50:00:00", Rates.f23_98())
iex> b = Range.new!(b_in, "02:30:00:00", out_type: :inclusive)
iex> 
iex> result = Range.separation!(a, b)
iex> inspect(result)
"<00:00:00:00 - -00:00:00:01 :inclusive <23.98 NTSC>>"