main
Raw Download raw file
  1package main
  2
  3import (
  4	"encoding/json"
  5	"fmt"
  6	"log"
  7	"os"
  8	"os/exec"
  9	"path/filepath"
 10
 11	"github.com/bryfry/singles/internal/playlist"
 12	"github.com/bryfry/singles/internal/wav"
 13)
 14
 15func main() {
 16
 17	if len(os.Args) < 2 {
 18		err := fmt.Errorf("Usage: go run mixtape.go <path to playlist.json>")
 19		log.Fatal(err)
 20	}
 21	playlistPath := os.Args[1]
 22	playlistDir := filepath.Dir(playlistPath)
 23	f, err := os.Open(playlistPath)
 24	if err != nil {
 25		err = fmt.Errorf("opening playlist: %w", err)
 26		log.Fatal(err)
 27	}
 28
 29	var pl playlist.Playlist
 30	d := json.NewDecoder(f)
 31	err = d.Decode(&pl)
 32	if err != nil {
 33		err = fmt.Errorf("decoding playlist: %w", err)
 34		log.Fatal(err)
 35	}
 36
 37	var combined *wav.WAV
 38	for i, t := range pl.Tracks {
 39		fmt.Printf("processing track %02d %s\n", i, t.Details.Title)
 40
 41		tPath := filepath.Join(playlistDir, t.Filename)
 42		track, err := wav.ReadWAV(tPath)
 43		if err != nil {
 44			panic(err)
 45		}
 46		if combined == nil {
 47			combined = track
 48			continue
 49		}
 50		if t.TrimEnd != 0 {
 51			track.TrimEnd(t.TrimEnd)
 52		}
 53		if t.TrimStart != 0 {
 54			track.TrimStart(t.TrimStart)
 55		}
 56		var transition *wav.WAV
 57		if t.Fade != 0 {
 58			transition, err = combined.Fade(track, t.Fade)
 59			if err != nil {
 60				panic(err)
 61			}
 62		} else {
 63			transition, err = combined.Append(track)
 64			if err != nil {
 65				panic(err)
 66			}
 67		}
 68		transitionFileName := fmt.Sprintf("%02d_transition.wav", i)
 69		transitionPath := filepath.Join(playlistDir, transitionFileName)
 70		err = transition.WriteFile(transitionPath)
 71		if err != nil {
 72			panic(err)
 73		}
 74
 75	}
 76
 77	fmt.Println("compiling mixtape")
 78	mixtapeWav := "mixtape.wav"
 79	mixtapeWavPath := filepath.Join(playlistDir, mixtapeWav)
 80	err = combined.WriteFile(mixtapeWavPath)
 81	if err != nil {
 82		panic(err)
 83	}
 84
 85	ffmpeg := "ffmpeg"
 86	ffmpegPath, err := exec.LookPath(ffmpeg)
 87	if err != nil {
 88		err = fmt.Errorf("%s not found in PATH %w", ffmpeg, err)
 89		log.Fatal(err)
 90	}
 91
 92	mixtapeOgg := "mixtape.ogg"
 93	mixtapeOggPath := filepath.Join(playlistDir, mixtapeOgg)
 94	cmd := exec.Command(
 95		ffmpegPath,
 96		"-y", // overwrite
 97		"-i", mixtapeWavPath,
 98		"-codec:a", "libopus",
 99		"-b:a", "192k",
100		"-vbr", "on",
101		"-application", "audio",
102		mixtapeOggPath,
103	)
104	cmd.Stdout = os.Stdout
105	cmd.Stderr = os.Stderr
106
107	err = cmd.Run()
108	if err != nil {
109		err = fmt.Errorf("running %s: %w", ffmpeg, err)
110		log.Fatal(err)
111	}
112}