timecode

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2021 License: Apache-2.0 Imports: 7 Imported by: 1

Documentation

Overview

Package timecode provides types and primitives to work with SMPTE ST 12-1 timecodes at standard and user-defined edit rates. Currently only the DF flag is supported and timecodes cannot be negative.

The package supports functions to convert between timecode, frame number and realtime durations as well as functions for timecode calculations. Drop-frame and non-drop-frame timecodes are correctly handled and all standard film, video and Television edit rates are supported. You may also use arbitrary user-defined edit rates down to 1ns precision with a timecode runtime of ~9 years.

Timecode and edit rate are stored as a single 64bit integer for efficient timecode handling and comparisons.

Index

Constants

View Source
const (
	R_23976      // 24000,1001 (Note: this is NOT a drop-frame edit rate)
	R_24         // 24,1
	R_25         // 25,1
	R_30         // 30,1
	R_48         // 48,1
	R_50         // 50,1
	R_60         // 60,1
	R_96         // 96,1
	R_100        // 100,1
	R_120        // 120,1
	R_MAX   = 15 // special case: requires rateNum and rateDen to be set
)

Standard edit rates for non-drop-frame timecodes.

View Source
const (
	R_30DF // 30000,1001

	R_60DF // 60000,1001
)

Standard edit rates for drop-frame timecodes.

View Source
const (
	Invalid Timecode = math.MaxUint64
	Zero    Timecode = 0
	Origin  string   = "00:00:00:00"

	Mask = time_mask
)

Variables

This section is empty.

Functions

func ConvertTimecode

func ConvertTimecode(value string) reflect.Value

ConvertTimecode implements schema.Converter function defined by the Gorilla schema package. To use this converter you need to register it via

dec := schema.NewDecoder()
dec.RegisterConverter(timecode.Timecode(0), timecode.ConvertTimecode)

This will eventually becomes unnecessary once https://github.com/gorilla/schema/issues/57 is fixed.

Types

type Rate

type Rate struct {
	// contains filtered or unexported fields
}
var (
	InvalidRate    Rate = Rate{R_MAX, 0, 0, 0, 0, 0}
	OneFpsRate     Rate = Rate{0, 1, 1, 1, 0, 1 * 600}                             // == 1fps
	IdentityRate   Rate = Rate{0, 1000000000, 1000000000, 1, 0, 1000000000 * 600}  // == 1ns
	IdentityRateDF Rate = Rate{df, 1000000000, 1000000000, 1, 0, 1000000000 * 600} // == 1ns
	Rate23976      Rate = Rate{R_23976, 24, 24000, 1001, 0, 24 * 600}
	Rate24         Rate = Rate{R_24, 24, 24, 1, 0, 24 * 600}
	Rate25         Rate = Rate{R_25, 25, 25, 1, 0, 25 * 600}
	Rate30         Rate = Rate{R_30, 30, 30, 1, 0, 30 * 600}
	Rate30DF       Rate = Rate{R_30DF, 30, 30000, 1001, 2, 17982}
	Rate48         Rate = Rate{R_48, 48, 48, 1, 0, 48 * 600}
	Rate50         Rate = Rate{R_50, 50, 50, 1, 0, 50 * 600}
	Rate60         Rate = Rate{R_60, 60, 60, 1, 0, 60 * 600}
	Rate60DF       Rate = Rate{R_60DF, 60, 60000, 1001, 4, 35964}
	Rate96         Rate = Rate{R_96, 96, 96, 1, 0, 96 * 600}
	Rate100        Rate = Rate{R_100, 100, 100, 1, 0, 100 * 600}
	Rate120        Rate = Rate{R_120, 120, 120, 1, 0, 120 * 600}
)

Common edit rate configurations you should use in your code when calling New()

func MaxRate

func MaxRate(a, b Rate) Rate

MaxRate returns the rate with larger frame duration.

func MinRate

func MinRate(a, b Rate) Rate

MinRate returns the rate with smaller frame duration.

func NewFloatRate

func NewFloatRate(f float32) Rate

NewFloatRate converts the float32 f to a rate. If the rate is approximately close to a pre-defined standard rate, the standard rate's configuration including the appropriate enum id will be used.

func NewRate

func NewRate(n, d int) Rate

NewRate creates a user-defined rate from rate numerator n and denominator d. If the rate is approximately close to a pre-defined standard rate, the standard rate's configuration including the appropriate enum id will be used.

func ParseRate

func ParseRate(s string) (Rate, error)

ParseRate converts the string s to a rate. The string is treated as a rate enumeration index when its value is an integer, as floating point rate when s parses as float32 or as rational rate otherwise.

If the pased float or rational rate is approximately close to a pre-defined standard rate, the standard rate's configuration including the appropriate enum id will be used.

func (Rate) Duration

func (r Rate) Duration(f int64) time.Duration

Duration returns the duration of f frames at the edit rate.

func (Rate) Float

func (r Rate) Float() float32

Float returns the rate as floating point number.

func (Rate) FloatString

func (r Rate) FloatString() string

FloatString returns the rate as floating point string with maximum precision of 3 digits.

func (Rate) Fraction

func (r Rate) Fraction() (int, int)

Fraction returns the rate's numerator and denominator.

func (Rate) FrameDuration

func (r Rate) FrameDuration() time.Duration

FrameDuration returns the duration of a single frame at the edit rate.

func (Rate) Frames

func (r Rate) Frames(d time.Duration) int64

Frames returns the number of frames matching duration d at the edit rate.

func (Rate) IndexString

func (r Rate) IndexString() string

IndexString returns the enumeration for a standard timecode as string.

func (Rate) IsDrop

func (r Rate) IsDrop() bool

IsDrop indicates if the rate refers to a drop-frame timecode.

func (Rate) IsEqual

func (r Rate) IsEqual(b Rate) bool

IsEqual returns true when rate r and b have equal frame duration.

func (Rate) IsSmaller

func (r Rate) IsSmaller(b Rate) bool

IsSmaller returns true if rate b has a larger frame duration than rate r.

func (Rate) IsValid

func (r Rate) IsValid() bool

IsValid indicates if a rate may be used in calculations. Rates with a denominator of zero would lead to division by zero panics, rates with a numerator of zero are undefined.

func (Rate) IsZero

func (r Rate) IsZero() bool

IsZero indicates if the rate equals IdentityRate. This may be used to check if a timecode has no associated rate using Timecode.Rate().IsZero().

func (Rate) MarshalText

func (r Rate) MarshalText() ([]byte, error)

func (Rate) RationalString

func (r Rate) RationalString() string

RationalString returns the rate as rational string of form 'numerator/denominator'.

func (Rate) Truncate

func (r Rate) Truncate(d time.Duration, precision int) time.Duration

Truncate clips duration d to the edit rate's interval length, while internally rounding to precision digits.

func (Rate) TruncateFloat

func (r Rate) TruncateFloat(d float64, precision int) time.Duration

func (*Rate) UnmarshalText

func (r *Rate) UnmarshalText(data []byte) error

type Timecode

type Timecode uint64

Timecode represents a duration at nanosecond precision similar to Golang's time.Duration. Unlike time.Duration Timecode cannot be negative.

The 6 most significant bits are used to store an edit rate identifier required for offset calculations. The timecode's duration value occupies the 59 least significant bits which allows for expressing ~9 years of runtime.

func FromSMPTE

func FromSMPTE(tc uint32, bits uint32) Timecode

FromSMPTE unpacks the SMPTE timecode from tc and also considers the drop-frame bit. User bits are ignored right now.

func FromSMPTEwithRate

func FromSMPTEwithRate(tc, bits uint32, rate float32) Timecode

FromSMPTEwithRate unpacks the SMPTE timecode from tc, considering the drop-frame bit and uses rate as initial timecode rate.

func New

func New(d time.Duration, r Rate) Timecode

New creates a new timecode from a time.Duration and an edit rate. The duration is truncated to the edit rate's interval length before storage.

func Parse

func Parse(s string) (Timecode, error)

Parse converts the string s to a timecode with optional rate. Without rate, the frame number is stored as raw nanosecond value. To reflect its actual duration you must call SetRate before calling any calculation functions. It's legal to parse and print timecodes without a rate.

Well-formed timecodes must contain exactly four numeric segements of format 'hh:mm:ss:ff' where 'hh' denotes hours, 'mm' minutes, 'ss' seconds and 'ff' frames. Drop-frame timecodes use a semicolon ';' as the last separator between seconds and frame number.

If s contains a '@' character, Parse treats the following substring as rate expression and uses ParseRate() to read it.

func (Timecode) Add

func (t Timecode) Add(d time.Duration) Timecode

Add returns a new timecode with current rate and duration d added to the current duration. Any negative result will be clipped to zero.

func (Timecode) AddFrames

func (t Timecode) AddFrames(f int64) Timecode

AddFrames returns a new timecode adjusted by f frames relative to the edit rate. If f is positive, the new timecode is larger than the current one, if negative it will be smaller. Any negative result after adding will be clipped to zero.

func (Timecode) Duration

func (t Timecode) Duration() time.Duration

Duration returns the duration part of the timecode.

func (Timecode) Frame

func (t Timecode) Frame() int64

Frame returns the frame sequence counter value corresponding to the timecode's duration at the timecode's edit rate. Note that this value will be wrong when the edit rate is unknown or unset, as is the case after parsing a timecode from string without setting the rate.

func (Timecode) FrameAtRate

func (t Timecode) FrameAtRate(r Rate) int64

FrameAtRate returns the frame sequence counter value corresponding to the timecode's duration at edit rate r.

func (Timecode) IsValid

func (t Timecode) IsValid() bool

IsValid indicates if a timecode is valid. Invalid timecodes have all bits set to 1.

func (Timecode) IsZero

func (t Timecode) IsZero() bool

IsZero indicates of the duration part of the timecode is zero. Rate bits are not considered in this check.

func (Timecode) MarshalText

func (t Timecode) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface for converting a timecode value to string. This implementation preserves the rate

func (Timecode) Millisecond

func (t Timecode) Millisecond() int64

Second returns the number of milliseconds covered by the timecode.

func (Timecode) Rate

func (t Timecode) Rate() Rate

func (Timecode) SMPTE

func (t Timecode) SMPTE() (uint32, uint32)

SMPTE returns a packed SMPTE timecode and user bits from the current timecode value.

func (*Timecode) Scan

func (t *Timecode) Scan(value interface{}) error

Scan implements sql.Scanner interface for converting database values to timecode so you can use type timecode.Timecode directly with ORMs or the sql package.

func (Timecode) Second

func (t Timecode) Second() int64

Second returns a properly rounded number of seconds covered by the timecode.

func (*Timecode) SetFrame

func (t *Timecode) SetFrame(f int64) Timecode

SetFrame sets the timecode to a new frame number f and keeps the timecode's current rate.

func (*Timecode) SetRate

func (t *Timecode) SetRate(r Rate) Timecode

SetRate sets a new edit rate r for the timecode and keeps the timecode's frame counter. Use this function to change the current edit rate or set set an initial edit rate after parsing a timecode with Parse() when the string did not contain a valid rate.

func (Timecode) String

func (t Timecode) String() string

String returns a string representation of the timecode as `hh:mm:ss:ff`. If the timecode uses a drop-frame edit rate, the last separator in the string is a semicolon `;`.

func (Timecode) StringWithRate

func (t Timecode) StringWithRate() string

StringWithRate returns the timecode as string appended with the current rate after a separating `@` character.

func (Timecode) Sub

func (t Timecode) Sub(t2 Timecode) time.Duration

Sub returns the difference between timecodes t and t2 in nanoseconds as time.Duration.

func (Timecode) Uint64

func (t Timecode) Uint64() uint64

Uint64 returns the raw timecode value as unsigned 64bit integer.

func (*Timecode) UnmarshalText

func (t *Timecode) UnmarshalText(data []byte) error

UnmarshalText implements the encoding.TextMarshaler interface for reading a timecode values.

func (Timecode) Value

func (t Timecode) Value() (driver.Value, error)

Value implements sql driver.Valuer interface for converting timecodes to a database driver compatible type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL