Skip to content

Instantly share code, notes, and snippets.

@derekkwok
Last active December 17, 2015 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derekkwok/5590529 to your computer and use it in GitHub Desktop.
Save derekkwok/5590529 to your computer and use it in GitHub Desktop.
This is the Go version of encode.py written for Windows 7
// This is a go script that encodes all files with mkv extension in the current
// working directory.
//
// NOTE: To use this script on Windows, you must download the fontconfig file
// which can be found at:
// http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=10&t=318&start=10
//
//
// Sources:
// http://ffmpeg.org/trac/ffmpeg/wiki/x264EncodingGuide
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"os/signal"
"strings"
)
const (
CRF_VALUE = "21"
PROFILE = "high"
PRESET = "fast"
FFMPEG_PATH = "C:\\ffmpeg\\bin\\ffmpeg.exe"
FONT_DIR = "C:\\ffmpeg\\bin\\fonts"
FC_CONFIG_DIR = "C:\\ffmpeg\\bin\\fonts"
FC_CONFIG_FILE = "C:\\ffmpeg\\bin\\fonts\\fonts.conf"
EXTENSION = "mkv"
ATTACHMENTS = "fonts"
ASS = "temp.ass"
)
// Remove the following:
// - symbolic links for fonts
// - ATTACHMENTS directory
// - extracted subtitles
func cleanup() {
os.Chdir(ATTACHMENTS)
fileInfoList, _ := ioutil.ReadDir(".")
for _, fileInfo := range fileInfoList {
link := fmt.Sprintf("%s\\%s", FONT_DIR, fileInfo.Name())
if err := exec.Command("cmd", "/c", "DEL", link).Run(); err != nil {
fmt.Println(err)
}
}
os.Chdir("..")
os.RemoveAll(ATTACHMENTS)
os.Remove(ASS)
}
// 1. Create ATTACHMENTS directory
// 2. Dump mkv attachments into ATTACHMENTS directory
// 3. Create symlinks to FC_CONFIG_DIR
func installFonts(name string) {
os.Mkdir(ATTACHMENTS, os.ModeDir)
os.Chdir(ATTACHMENTS)
exec.Command(FFMPEG_PATH, "-dump_attachment:t", "", "-i", fmt.Sprintf("../%s", name)).Run()
fileInfoList, _ := ioutil.ReadDir(".")
for _, fileInfo := range fileInfoList {
link := fmt.Sprintf("%s\\%s", FONT_DIR, fileInfo.Name())
target := fileInfo.Name()
if err := exec.Command("cmd", "/c", "MKLINK", "/H", link, target).Run(); err != nil {
fmt.Println(err)
}
}
os.Chdir("..")
}
func encode(fileInfo os.FileInfo) {
defer cleanup()
name := fileInfo.Name()
loc := strings.LastIndex(name, ".")
if name[loc+1:] != EXTENSION {
return
}
outputName := fmt.Sprintf("%s.mp4", name[:loc])
installFonts(name)
// Extract ASS subtitles
exec.Command(FFMPEG_PATH, "-i", name, ASS).Run()
// Encode Video
cmd := exec.Command(FFMPEG_PATH, "-i", name,
"-tune", "animation", "-preset", PRESET, "-profile:v", PROFILE, "-crf", CRF_VALUE,
"-vf", fmt.Sprintf("ass=%s", ASS),
"-c:v", "libx264",
"-c:a", "copy",
"-threads", "2",
outputName)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}
func handleInterrupt() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
log.Printf("captured %v, stopping and exiting..", sig)
cleanup()
os.Exit(1)
}
}()
}
func main() {
handleInterrupt()
os.Setenv("FC_CONFIG_DIR", FC_CONFIG_DIR)
os.Setenv("FC_CONFIG_FILE", FC_CONFIG_FILE)
dir, err := os.Getwd()
if err != nil {
fmt.Println(err)
return
}
fileInfoList, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Println(err)
return
}
for _, fileInfo := range fileInfoList {
encode(fileInfo)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment