Skip to content
Permalink
Browse files

First working version

  • Loading branch information...
HenrySlawniak committed Sep 5, 2018
0 parents commit 5944d04ca04903e4a60816d805644bd69ed7e042
Showing with 9,093 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +49 −0 Gopkg.lock
  3. +38 −0 Gopkg.toml
  4. BIN IBMPlexMono-Regular.ttf
  5. +57 −0 binaries.go
  6. +19 −0 compile-all-platforms.sh
  7. +181 −0 contactsheet.go
  8. +115 −0 main.go
  9. +49 −0 metadata.go
  10. +55 −0 thumbs.go
  11. +27 −0 vendor/github.com/go-playground/ansi/.gitignore
  12. +21 −0 vendor/github.com/go-playground/ansi/LICENSE
  13. +88 −0 vendor/github.com/go-playground/ansi/README.md
  14. +50 −0 vendor/github.com/go-playground/ansi/ansi.go
  15. +15 −0 vendor/github.com/go-playground/errors/.gitignore
  16. +21 −0 vendor/github.com/go-playground/errors/LICENSE
  17. +19 −0 vendor/github.com/go-playground/errors/Makefile
  18. +111 −0 vendor/github.com/go-playground/errors/README.md
  19. +118 −0 vendor/github.com/go-playground/errors/chain.go
  20. +104 −0 vendor/github.com/go-playground/errors/errors.go
  21. +6 −0 vendor/github.com/go-playground/errors/helpers.go
  22. +158 −0 vendor/github.com/go-playground/errors/stack.go
  23. +26 −0 vendor/github.com/go-playground/log/.gitignore
  24. +21 −0 vendor/github.com/go-playground/log/LICENSE
  25. +210 −0 vendor/github.com/go-playground/log/README.md
  26. +174 −0 vendor/github.com/go-playground/log/entry.go
  27. +49 −0 vendor/github.com/go-playground/log/errors.go
  28. +218 −0 vendor/github.com/go-playground/log/handlers/console/console.go
  29. +54 −0 vendor/github.com/go-playground/log/handlers/console/doc.go
  30. +87 −0 vendor/github.com/go-playground/log/level.go
  31. +222 −0 vendor/github.com/go-playground/log/log.go
  32. +20 −0 vendor/github.com/golang/freetype/AUTHORS
  33. +38 −0 vendor/github.com/golang/freetype/CONTRIBUTORS
  34. +12 −0 vendor/github.com/golang/freetype/LICENSE
  35. +21 −0 vendor/github.com/golang/freetype/README
  36. +341 −0 vendor/github.com/golang/freetype/freetype.go
  37. +245 −0 vendor/github.com/golang/freetype/raster/geom.go
  38. +287 −0 vendor/github.com/golang/freetype/raster/paint.go
  39. +601 −0 vendor/github.com/golang/freetype/raster/raster.go
  40. +483 −0 vendor/github.com/golang/freetype/raster/stroke.go
  41. +42 −0 vendor/github.com/golang/freetype/testdata/COPYING
  42. +507 −0 vendor/github.com/golang/freetype/truetype/face.go
  43. +522 −0 vendor/github.com/golang/freetype/truetype/glyph.go
  44. +1,770 −0 vendor/github.com/golang/freetype/truetype/hint.go
  45. +289 −0 vendor/github.com/golang/freetype/truetype/opcodes.go
  46. +653 −0 vendor/github.com/golang/freetype/truetype/truetype.go
  47. +3 −0 vendor/golang.org/x/image/AUTHORS
  48. +3 −0 vendor/golang.org/x/image/CONTRIBUTORS
  49. +27 −0 vendor/golang.org/x/image/LICENSE
  50. +22 −0 vendor/golang.org/x/image/PATENTS
  51. +359 −0 vendor/golang.org/x/image/font/font.go
  52. +410 −0 vendor/golang.org/x/image/math/fixed/fixed.go
  53. +72 −0 video.go
@@ -0,0 +1,4 @@
*.exe
config.json
.bin/*
.logs/*

Some generated files are not rendered by default. Learn more.

@@ -0,0 +1,38 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true


[[constraint]]
name = "github.com/go-playground/log"
version = "6.3.0"

[[constraint]]
branch = "master"
name = "github.com/golang/freetype"

[prune]
go-tests = true
unused-packages = true
Binary file not shown.
@@ -0,0 +1,57 @@
// Copyright (c) 2018 Henry Slawniak <https://datacenterscumbags.com/>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
"runtime"
)

// GetFFMpegBinary returns the location of the correct ffmpeg binary for the runtime OS
func GetFFMpegBinary() string {
var location string
if runtime.GOOS == "linux" {
location = "./bin/ffmpeg"
} else if runtime.GOOS == "windows" {
location = "./bin/ffmpeg.exe"
}

if !FileExists(location) {
return "ffmpeg"
}

return location
}

// GetFFProbeBinary returns the location of the correct ffprobe binary for the runtime OS
func GetFFProbeBinary() string {
var location string
if runtime.GOOS == "linux" {
location = "./bin/ffprobe"
} else if runtime.GOOS == "windows" {
location = "./bin/ffprobe.exe"
}

if !FileExists(location) {
return "ffprobe"
}

return location
}
@@ -0,0 +1,19 @@
#!/bin/bash

mkdir -p .bin/

go get

for os in windows linux darwin; do
for arch in amd64 386 arm arm64; do
target="$os:$arch"
echo "Compiling $target"
export GOOS=$(echo $target | cut -d: -f1) GOARCH=$(echo $target | cut -d: -f2)
OUT=.bin/$(basename $(echo $PWD))_${GOOS}_${GOARCH}
if [ $GOOS == "windows" ]
then
OUT="$OUT.exe"
fi
bash -c "go build -ldflags '-w -X main.buildTime=$(date +'%b-%d-%Y-%H:%M:%S') -X main.commit=$(git describe --always)' -v -o $OUT ."
done
done
@@ -0,0 +1,181 @@
// Copyright (c) 2018 Henry Slawniak <https://datacenterscumbags.com/>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
"bufio"
"fmt"
"github.com/go-playground/log"
"github.com/golang/freetype"
"image"
"image/color"
"image/draw"
"image/png"
"os"
)

const (
GutterSize = 20
FramesPerRow = 3

FontSize = 40
FontSpacing = 0.9
FontDPI = 72
HeaderSize = 200
)

var (
text = image.Black
bg = image.NewUniform(color.RGBA{0xE0, 0xEB, 0xF5, 0xff})
)

func generateContactSheet(vid *Video, numFrames int) {
var FrameWidth int
var FrameHeight int
frames := map[int]image.Image{}
for i := 0; i < numFrames; i++ {
frameLoc := fmt.Sprintf("tmp/%s-%d.png", vid.SHA1.Hex(), i)
if !FileExists(frameLoc) {
log.Errorf("Frame missing from disk `%s`\n", frameLoc)
return
}
f, err := os.Open(frameLoc)
if err != nil {
log.Error(err)
return
}

img, _, err := image.Decode(f)
if err != nil {
log.Error(err)
return
}
f.Close()
os.Remove(f.Name())

if i == 0 {
FrameWidth = img.Bounds().Dx()
FrameHeight = img.Bounds().Dy()
}

frames[i] = img
}

log.Infof("Loaded %d frames for %s", len(frames), vid.Filename)

rowCount := numFrames / FramesPerRow

sheetWidth := (FramesPerRow * FrameWidth) + ((FramesPerRow + 1) * GutterSize)
sheetHeight := (HeaderSize) + (rowCount * FrameHeight) + ((rowCount + 1) * GutterSize)
log.Infof("Sheet Dimmensions: %dx%d\n", sheetWidth, sheetHeight)

sheet := image.NewRGBA(image.Rect(0, 0, sheetWidth, sheetHeight))

font, err := freetype.ParseFont(fontBytes)
if err != nil {
log.Error(err)
return
}

draw.Draw(sheet, sheet.Bounds(), bg, image.ZP, draw.Src)
c := freetype.NewContext()
c.SetDPI(FontDPI)
c.SetFont(font)
c.SetFontSize(FontSize)
c.SetClip(sheet.Bounds())
c.SetDst(sheet)
c.SetSrc(text)

pt := freetype.Pt(10, 10+int(c.PointToFixed(FontSize)>>6))
for _, s := range vid.Filename {
_, err = c.DrawString(string(s), pt)
if err != nil {
log.Error(err)
return
}
pt.X += c.PointToFixed(FontSize * FontSpacing)
}

pt = freetype.Pt(10, 20+FontSize+int(c.PointToFixed((FontSize))>>6))
for _, s := range "SHA1: " + vid.SHA1.Hex() {
_, err = c.DrawString(string(s), pt)
if err != nil {
log.Error(err)
return
}
pt.X += c.PointToFixed((FontSize * .7) * FontSpacing)
}

pt = freetype.Pt(10, 60+FontSize+int(c.PointToFixed((FontSize))>>6))
for _, s := range fmt.Sprintf("Duration: %s, Dimmensions: %dx%d", stampToString(vid.Duration), vid.Width, vid.Height) {
_, err = c.DrawString(string(s), pt)
if err != nil {
log.Error(err)
return
}
pt.X += c.PointToFixed((FontSize * .7) * FontSpacing)
}

for i := 0; i < len(frames); i++ {
frame := frames[i]
row := i / FramesPerRow
yOff := (row * FrameHeight) + GutterSize + HeaderSize + (GutterSize * row)
col := i % FramesPerRow
xOff := col*FrameWidth + GutterSize + (GutterSize * col)
// frameTime := stampToString(((float64(vid.Duration)) / float64(numFrames)) * float64(i))
rect := image.Rect(xOff, yOff, xOff+FrameWidth, yOff+FrameHeight)
draw.Draw(sheet, rect, frame, frame.Bounds().Min, draw.Src)
}

outFile, err := os.Create(vid.Filename + ".png")
if err != nil {
log.Error(err)
return
}
defer outFile.Close()

b := bufio.NewWriter(outFile)
err = png.Encode(b, sheet)
if err != nil {
log.Error(err)
return
}

err = b.Flush()
if err != nil {
log.Error(err)
return
}

}

func stampToString(stamp float64) string {
ts := int(stamp) % (24 * 3600)
h := ts / 3600

ts = ts % 3600
m := ts / 60

ts = ts % 60
s := ts

return fmt.Sprintf("%02d:%02d:%02d", h, m, s)
}

0 comments on commit 5944d04

Please sign in to comment.
You can’t perform that action at this time.