Socket
Socket
Sign inDemoInstall

github.com/opencinemac/vtc-go

Package Overview
Dependencies
2
Alerts
File Explorer

Install Socket

Detect and block malicious and high-risk dependencies

Install

    github.com/opencinemac/vtc-go

Package vtc is inspired by years of scripting workflow solutions in a Hollywood cutting room. It aims to capture all the ways in which timecode is used throughout the industry so users can spend more time on their workflow logic, and less time handling the corner-cases of parsing and calculating timecode. To get an overview of what this package can do, see the example at the bottom. But first: what is timecode? If you're already familiar with timecode, it's history, and it's flavors, feel free to skip this section. Back in the days of film, a running strip of numbers ran along the edge of the film stock to uniquely identify each frame, called keycode (https://en.wikipedia.org/wiki/Keykode) Keycode was essential to the film editing process. The raw negative of a film is irreplaceable: you loose quality each time you make a copy. Editing film is necessarily a destructive process (https://nofilmschool.com/2017/06/editing-on-a-flatbed), and often required multiple iterations. It would be just a tad nerve-wracking to take a pair of scissors and some glue to the one-of-a-kind film reels straight out of the camera on set, then running it over and over through a flatbed. To avoid potential disaster, editors made their cut of the film using copies of the raw negative, called a work print (https://en.wikipedia.org/wiki/Workprint), allowing the editor to work without fear of sinking a project from slicing, dicing, and wearing at the film. When the edit was complete, it was necessary to know *exactly* where the edits had been made, so it could be recreated with the raw negative for finishing. A *cut list* would be written out, with the exact reels and keycodes for every cut, and would be used to make an exact duplicate of the editor's work print with the mint condition raw negative. In video and digital filmmaking, the same approach is used. Massive RAW files from a RED, ARRI, Sony, or other cinema camera are rendered down to more manageable files an Editor's machine won't choke on. Once the edit is complete, the raw files are re-assembled using a digital cutlist on a powerful machine for finishing out the film. In film, we referenced *keycode* to know exactly what frame was being displayed on screen at any given time. In digital video, we reference the *timecode* of a given frame. For a technical deep-dive into the many flavors of timecode, check out Frame.io's excellent blogpost on the subject: https://blog.frame.io/2017/07/17/timecode-and-frame-rates. This package is broken into two subpackages: • rate: framerate types and functions • tc: timecode types and functions See the subdirectories below. See a brief overview of this package by expanding the example below:


Version published

Readme

Source

vtc-go

A SMPTE Timecode Library for Go

click to see build pipeline click to see build pipeline click to see build pipeline

click to see report card click here to see report

Repo Go Reference

Overview

vtc-go is inspired by years of scripting workflow solutions in a Hollywood cutting room. It aims to capture all the ways in which timecode is used throughout the industry so users can spend more time on their workflow logic, and less time handling the corner-cases of parsing and calculating timecode.

Demo

Let's take a quick high-level look at what you can do with vtc-rs:

package main

import (
	"fmt"
	"github.com/opencinemac/vtc-go/pkg/rate"
	"github.com/opencinemac/vtc-go/pkg/tc"
	"math/big"
)

func main() {
	// It's easy to make a new 23.98 NTSC Timecode.
	timecode, err := tc.FromTimecode("01:00:00:00", rate.F23_98)
	if err != nil {
		panic(fmt.Errorf("error parsing timecode: %w", err))
	}

	// 01:00:00:00 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// We can get all sorts of ways to represent the timecode.

	// 01:00:00:00
	fmt.Println(timecode.Timecode())

	// 86400
	fmt.Println(timecode.Frames())

	// 18018/5
	fmt.Println(timecode.Seconds())

	// 01:00:03.6
	fmt.Println(timecode.Runtime(9))

	// 915372057600000
	fmt.Println(timecode.PremiereTicks())

	// 5400+00
	fmt.Println(timecode.FeetAndFrames())

	// We can inspect the framerate:

	// 24000/1001
	fmt.Println(timecode.Rate().Playback())

	// 24/1
	fmt.Println(timecode.Rate().Timebase())

	// NTSC NDF
	fmt.Println(timecode.Rate().NTSC())

	// Parsing is flexible:

	// Partial timecodes:
	timecode, _ = tc.FromTimecode("3:12", rate.F23_98)

	// 00:00:03:12 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// Frames:
	timecode = tc.FromFrames(24, rate.F23_98)

	// 00:00:01:00 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// Seconds:
	timecode = tc.FromSeconds(big.NewRat(3, 2), rate.F23_98)

	// 00:00:01:12 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// Premiere Ticks:
	timecode = tc.FromPremiereTicks(254016000000, rate.F23_98)

	// 00:00:01:00 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// Runtime:
	timecode, _ = tc.FromRuntime("01:00:00.5", rate.F23_98)

	// 00:59:56:22 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// Feet + Frames:
	timecode, _ = tc.FromFeetAndFrames("213+07", rate.F23_98)

	// 00:02:22:07 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// We can add two timecodes:
	timecode, _ = tc.FromTimecode("17:23:13:02", rate.F23_98)
	other, _ := tc.FromTimecode("01:00:00:00", rate.F23_98)

	timecode = timecode.Add(other)

	// 18:23:13:02 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// We can subtract too.
	timecode = timecode.Sub(other)

	// 17:23:13:02 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// It's easy to compare two timecodes:

	// GT (1)
	fmt.Println(timecode.Cmp(other))

	// We can multiply:
	timecode = timecode.Mul(big.NewRat(2, 1))

	// 34:46:26:04 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// ... divide...
	timecode = timecode.Div(big.NewRat(2, 1))

	// 17:23:13:02 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// and even get the remainder of division
	dividend, remainder := timecode.DivMod(big.NewRat(3, 2))

	// DIVIDEND: 11:35:28:17 @ 23.98 NTSC NDF
	// REMAINDER: 00:00:00:01 @ 23.98 NTSC NDF
	fmt.Println("DIVIDEND:", dividend)
	fmt.Println("REMAINDER:", remainder)

	// We can make a timecode negative:
	timecode = timecode.Neg()

	// -17:23:13:02 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// Or get it's absolute value:
	timecode = timecode.Abs()

	// 17:23:13:02 @ 23.98 NTSC NDF
	fmt.Println(timecode)

	// We can make dropframe timecode for 29.97 or 59.94 using one of the pre-set
	// framerates.
	dropFrame := tc.FromFrames(15000, rate.F29_97Df)

	// 00:08:20;18 @ 29.97 NTSC DF
	// NTSC DF
	fmt.Println(dropFrame)
	fmt.Println(dropFrame.Rate().NTSC())

	// We can make new timecodes with arbitrary framerates if we want:
	framerate, _ := rate.FromInt(137, rate.NTSCNone)
	timecode, _ = tc.FromTimecode("01:00:00:00", framerate)

	// 493200
	fmt.Println(timecode.Frames())

	// We can make NTSC values for timebases and playback speeds that do not ship with
	// this crate:
	framerate, _ = rate.FromInt(120, rate.NTSCNonDrop)
	timecode, _ = tc.FromTimecode("01:00:00:00", framerate)

	// 01:00:00:00 @ 119.88 NTSC NDF
	fmt.Println(timecode)

	// We can also rebase them using another framerate:
	timecode = timecode.Rebase(rate.F59_94Ndf)

	// 02:00:00:00 @ 59.94 NTSC NDF
	fmt.Println(timecode)
}

Features

  • SMPTE Conventions:
    • NTSC
    • Drop-Frame
    • Interlaced timecode
  • Timecode Representations:
    • Timecode | '01:00:00:00'
    • Frames | 86400
    • Seconds | 3600.0
    • Runtime | '01:00:00.0'
    • Rational | 18018/5
    • Feet+Frames | '5400+00'
      • 35mm, 4-perf
      • 35mm, 3-perf
      • 35mm, 2-perf
      • 16mm
    • Premiere Ticks | 15240960000000
  • Operations:
    • Comparisons (==, <, <=, >, >=)
    • Add
    • Subtract
    • Scale (multiply and divide)
    • Div/Rem
    • Modulo
    • Negative
    • Absolute
    • Rebase (recalculate frame count at new framerate)
  • Flexible Parsing:
    • Partial timecodes | '1:12'
    • Partial runtimes | '1.5'
    • Negative string values | '-1:12', '-3+00'
    • Poorly formatted tc | '1:13:4'
  • Built-in consts for common framerates.

Goals

  • Parse and fetch all Timecode representations.
  • A clean, idiomatic API.
  • Support all operations that make sense for timecode.

Non-Goals

  • Real-time timecode generators.

Attributions

Drop-frame calculations adapted from David Heidelberger's blog.
Logo made by Freepik from www.flaticon.com

FAQs

Last updated on 26 May 2021

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc