main
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}