tomgjson

package module
v0.4.9 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2023 License: MIT Imports: 10 Imported by: 0

README

tomgjson

Converts time based data sources to Adobe's mgJSON format (Motion Graphics JSON).

A live version of this app can be found here: To mgJSON

The first iterations will be very limited in terms of customization and supported formats, but the provided parser funcs can potentially be adapted to any source that associates time with values.

For instructions on how to use mgJSON files in After Effects, see Work with Data-driven animation

Supported input formats

See the sample_sources directory for compatible samples.

CSV

The simplest CSV file supported is a column with numbers. When a frame rate is specified, every value will be assigned a time based on the frame rate. Optionally, a header can be included in order to label the data. If the desired times do not correspond to the frame rate, a left-aligned "milliseconds" column can be used to specify the times relative to the beginning of the video. Additional columns with different labels can be appended to the right-hand side of the document to create new streams.

GPX

GPS tracks with time fields can be parsed. For now, only the first track of a file will be read. Based on the parsed data, additional data streams can be computed (speed, acceleration, course direction, distance...).

Usage

src, _ := ioutil.ReadFile("./sample_sources/multiple-data.csv")
converted := FromCSV(src, 0)
doc := tomgjson.ToMgjson(converted, "Author Name")
f, _ := os.Create("./out.mgjson")
f.Write(doc)
f.Close()

See all_test.go for implementation examples.

Sample project templates

You can find sample After Effects projects that use mgJSON files on the GoPro Telemetry Extractor page. Look for the Lite/Trial templates.

Videos made with mgJSON

If you create something with mgJSON, let me know and I'll add it to the list.

Software that supports mgJSON

These apps can output mgJSON files:

Contribution

Please make your changes to the dev branch, so that automated tests can be run before merging to master. Also, if possible, provide tests for new functionality.

To-Do

  • Import from json and other formats
  • Enable creating static fields? Non interpolable fields? Multidimensional fields?

Documentation

Overview

Package tomgjson converts time based data sources to Adobe's mgJSON format for After Effects.

Initially, this supports appropriately formatted CSV files and simple GPX files (see sample_sources).

A live version of this app can be found here: https://goprotelemetryextractor.com/csv-gpx-to-mgjson/.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ToMgjson

func ToMgjson(sd FormattedData, creator string) ([]byte, error)

ToMgjson receives a formatted source data (FormattedData) and a creator or author name and returns formatted mgjson ready to write to a file compatible with Adobe After Effects data-driven animations (or an error)

Example
stream1 := Stream{
	Label:  "Prime numbers",
	Values: []float64{2, 3, 5, 7},
}

stream2 := Stream{
	Label:  "Non primes",
	Values: []float64{4, 6, 8, 9},
}

stream3 := Stream{
	Label: "Colors",
	Strings: []string{
		"Green",
		"Yellow",
		"Red",
		"Blue",
	},
}

utc, _ := time.LoadLocation("UTC")
now := time.Unix(0, 0).In(utc)
plus10, _ := time.ParseDuration("10s")
plus20, _ := time.ParseDuration("20s")
plus30, _ := time.ParseDuration("30s")
timing := []time.Time{
	now,
	now.Add(plus10),
	now.Add(plus20),
	now.Add(plus30),
}

data := FormattedData{
	Timing:  timing,
	Streams: []Stream{stream1, stream2, stream3},
}

doc, _ := ToMgjson(data, "Juan Irache")

fmt.Println(string(doc))
Output:

{"version":"MGJSON2.0.0","creator":"Juan Irache","dynamicSamplesPresentB":true,"dynamicDataInfo":{"useTimecodeB":false,"utcInfo":{"precisionLength":3,"isGMT":true}},"dataOutline":[{"objectType":"dataDynamic","displayName":"Prime numbers","sampleSetID":"Stream0","dataType":{"type":"numberString","numberStringProperties":{"pattern":{"digitsInteger":1,"digitsDecimal":1,"isSigned":true},"range":{"occuring":{"min":2,"max":7},"legal":{"min":2,"max":7}}},"paddedStringProperties":{"maxLen":0,"maxDigitsInStrLength":0,"eventMarkerB":false}},"interpolation":"linear","hasExpectedFrequecyB":false,"sampleCount":4,"matchName":"Stream0"},{"objectType":"dataDynamic","displayName":"Non primes","sampleSetID":"Stream1","dataType":{"type":"numberString","numberStringProperties":{"pattern":{"digitsInteger":1,"digitsDecimal":1,"isSigned":true},"range":{"occuring":{"min":4,"max":9},"legal":{"min":4,"max":9}}},"paddedStringProperties":{"maxLen":0,"maxDigitsInStrLength":0,"eventMarkerB":false}},"interpolation":"linear","hasExpectedFrequecyB":false,"sampleCount":4,"matchName":"Stream1"},{"objectType":"dataDynamic","displayName":"Colors","sampleSetID":"Stream2","dataType":{"type":"paddedString","numberStringProperties":{"pattern":{"digitsInteger":0,"digitsDecimal":0,"isSigned":false},"range":{"occuring":{"min":0,"max":0},"legal":{"min":0,"max":0}}},"paddedStringProperties":{"maxLen":6,"maxDigitsInStrLength":1,"eventMarkerB":false}},"interpolation":"hold","hasExpectedFrequecyB":false,"sampleCount":4,"matchName":"Stream2"}],"dataDynamicSamples":[{"sampleSetID":"Stream0","samples":[{"time":"1970-01-01T00:00:00.000Z","value":"+2.0"},{"time":"1970-01-01T00:00:10.000Z","value":"+3.0"},{"time":"1970-01-01T00:00:20.000Z","value":"+5.0"},{"time":"1970-01-01T00:00:30.000Z","value":"+7.0"}]},{"sampleSetID":"Stream1","samples":[{"time":"1970-01-01T00:00:00.000Z","value":"+4.0"},{"time":"1970-01-01T00:00:10.000Z","value":"+6.0"},{"time":"1970-01-01T00:00:20.000Z","value":"+8.0"},{"time":"1970-01-01T00:00:30.000Z","value":"+9.0"}]},{"sampleSetID":"Stream2","samples":[{"time":"1970-01-01T00:00:00.000Z","value":{"length":"5","str":"Green "}},{"time":"1970-01-01T00:00:10.000Z","value":{"length":"6","str":"Yellow"}},{"time":"1970-01-01T00:00:20.000Z","value":{"length":"3","str":"Red   "}},{"time":"1970-01-01T00:00:30.000Z","value":{"length":"4","str":"Blue  "}}]}]}

Types

type FormattedData

type FormattedData struct {
	Timing  []time.Time
	Streams []Stream
}

FormattedData is the struct accepted by ToMgjson. It consists of a slice of timestamps and a slice with all the streams of labelled values (floats for now)

func FromCSV

func FromCSV(src []byte, fr float64) (FormattedData, error)

FromCSV formats a compatible CSV as a FormattedData struct ready for mgJSON and returns it. Or returns an error The optional frame rate (fr) is used if timing data is not present

Example
src, _ := ioutil.ReadFile("./sample_sources/multiple-data.csv")
converted, _ := FromCSV(src, 0)
sample := 5
fmt.Printf(
	`The second stream is labelled as %q and its %q at %f seconds is %v`,
	converted.Streams[1].Label,
	converted.Streams[2].Strings[sample],
	converted.Timing[sample].Sub(time.Unix(0, 0)).Seconds(),
	converted.Streams[1].Values[sample],
)
Output:

The second stream is labelled as "Signed 1k Perlin" and its "sample 6" at 0.500000 seconds is 74.1837892462852

func FromGPX

func FromGPX(src []byte, extra bool) (FormattedData, error)

FromGPX formats a compatible GPX file as a struct ready for mgJSON and returns it. Or returns an error The optional extra bool will compute additional streams based on the existing data

Example
src, _ := ioutil.ReadFile("./sample_sources/gps-path.gpx")
converted, _ := FromGPX(src, true)
sample := 10
fmt.Printf(
	`At %v the position was %v: %f, %v: %f and the %v was %f `,
	converted.Timing[sample].Format("15:04:05"),
	converted.Streams[0].Label,
	converted.Streams[0].Values[sample],
	converted.Streams[1].Label,
	converted.Streams[1].Values[sample],
	converted.Streams[8].Label,
	converted.Streams[8].Values[sample],
)
Output:

At 11:45:55 the position was lat (°): 41.389212, lon (°): 2.147359 and the speed2d (m/s) was 3.057694

type Stream

type Stream struct {
	Label   string
	Values  []float64
	Strings []string
}

Stream contains a slice of values or strings and their label The slices must be of the same length as the timing slice in their parent's FormattedData Only one of the slices must be present, not both

Jump to

Keyboard shortcuts

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