Unified · Split
| @@ -2,8 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | A command line tool for frame accurate FLAC image + cue sheet splitting. |
| 4 | 4 | |
| 5 | −WIP. | |
| 6 | − | |
| 7 | 5 | This project is started mostly out of frustration over supporting |
| 8 | 6 | [split2flac](https://github.com/ftrvxmtrx/split2flac) with all the |
| 9 | 7 | external dependencies and their quirks. |
| @@ -17,7 +15,7 @@ Yeah, that's it. · 7 unmodified lines | ||
| 17 | 15 | |
| 18 | 16 | ## TODO |
| 19 | 17 | |
| 20 | − * parallel extraction | |
| 18 | + * get the artist/performer/composer right (and support multiple) | |
| 21 | 19 | * an option to format the output path in a specific way |
| 22 | 20 | * detect cue sheet encoding and convert to utf8 |
| 23 | 21 | * copying cue, log, images over to the destination |
| @@ -29,6 +27,7 @@ Yeah, that's it. · 5 unmodified lines | ||
| 29 | 27 | * basic splitting |
| 30 | 28 | * tagging |
| 31 | 29 | * split to other formats (ogg/vorbis, mp3) |
| 30 | + * parallel extraction | |
| 32 | 31 | |
| 33 | 32 | ## NOTES |
| 34 | 33 | |
| @@ -2,4 +2,7 @@ module github.com/ftrvxmtrx/unflac · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | go 1.12 |
| 4 | 4 | |
| 5 | −require github.com/vchimishuk/chub v0.0.0-20190501162134-36f1f5f7c9ef | |
| 5 | +require ( | |
| 6 | + github.com/gammazero/workerpool v0.0.0-20190608213748-0ed5e40ec55e | |
| 7 | + github.com/vchimishuk/chub v0.0.0-20190501162134-36f1f5f7c9ef | |
| 8 | +) | |
| @@ -1,2 +1,6 @@ | ||
| 1 | +github.com/gammazero/deque v0.0.0-20190521012701-46e4ffb7a622 h1:lxbhOGZ9pU3Kf8P6lFluUcE82yVZn2EqEf4+mWRNPV0= | |
| 2 | +github.com/gammazero/deque v0.0.0-20190521012701-46e4ffb7a622/go.mod h1:D90+MBHVc9Sk1lJAbEVgws0eYEurY4mv2TDso3Nxh3w= | |
| 3 | +github.com/gammazero/workerpool v0.0.0-20190608213748-0ed5e40ec55e h1:fqgNEGLc7p2Rz4xlDHp9WNw/pqqR3c2cLdIC4zASBzU= | |
| 4 | +github.com/gammazero/workerpool v0.0.0-20190608213748-0ed5e40ec55e/go.mod h1:avlwxCMavNtjwf7NrfnzdIGU3OZYI5D1NFQ2Rn3nHKg= | |
| 1 | 5 | github.com/vchimishuk/chub v0.0.0-20190501162134-36f1f5f7c9ef h1:Aew4jNB16cG2gnlY1dGOW6Od/x0r3puwfpbwX7aO6r0= |
| 2 | 6 | github.com/vchimishuk/chub v0.0.0-20190501162134-36f1f5f7c9ef/go.mod h1:28Qi8YBLQu3Fb3xKnGR9ou2d/PfFz3ptpbZdtsCM++4= |
| @@ -7,6 +7,7 @@ import ( · 6 unmodified lines | ||
| 7 | 7 | "path/filepath" |
| 8 | 8 | "strings" |
| 9 | 9 | |
| 10 | + "github.com/gammazero/workerpool" | |
| 10 | 11 | "github.com/vchimishuk/chub/cue" |
| 11 | 12 | ) |
| 12 | 13 | |
| @@ -145,17 +146,23 @@ func (in *Input) Dump() { · 132 unmodified lines | ||
| 145 | 146 | } |
| 146 | 147 | } |
| 147 | 148 | |
| 148 | −func (in *Input) Split() (err error) { | |
| 149 | +func (in *Input) Split(pool *workerpool.WorkerPool, firstErr chan<- error) (err error) { | |
| 149 | 150 | dirPath := filepath.Join(*outputDir, in.OutputPath()) |
| 150 | 151 | if err = os.MkdirAll(dirPath, 0755); err != nil { |
| 151 | 152 | return |
| 152 | 153 | } |
| 153 | 154 | |
| 154 | 155 | for _, t := range in.Tracks { |
| 155 | − trackPath := filepath.Join(dirPath, in.TrackFilename(t)) | |
| 156 | − if err = in.Audio.Extract(t, trackPath); err != nil { | |
| 157 | − return | |
| 158 | − } | |
| 156 | + pool.Submit(func(t *Track) func() { | |
| 157 | + return func() { | |
| 158 | + trackPath := filepath.Join(dirPath, in.TrackFilename(t)) | |
| 159 | + if err = in.Audio.Extract(t, trackPath); err != nil { | |
| 160 | + firstErr <- fmt.Errorf("%s: %s", trackPath, err) | |
| 161 | + } else if !*quiet { | |
| 162 | + fmt.Printf("%s\n", trackPath) | |
| 163 | + } | |
| 164 | + } | |
| 165 | + }(t)) | |
| 159 | 166 | } |
| 160 | 167 | |
| 161 | 168 | return |
| @@ -3,11 +3,13 @@ package main · 2 unmodified lines | ||
| 3 | 3 | import ( |
| 4 | 4 | "encoding/json" |
| 5 | 5 | "flag" |
| 6 | − "fmt" | |
| 7 | 6 | "log" |
| 8 | 7 | "os" |
| 9 | 8 | "path/filepath" |
| 9 | + "runtime" | |
| 10 | 10 | "strings" |
| 11 | + | |
| 12 | + "github.com/gammazero/workerpool" | |
| 11 | 13 | ) |
| 12 | 14 | |
| 13 | 15 | var ( |
| @@ -80,15 +82,22 @@ func main() { · 66 unmodified lines | ||
| 80 | 82 | if len(inputs) == 0 { |
| 81 | 83 | log.Fatal("no input found") |
| 82 | 84 | } |
| 85 | + | |
| 86 | + wp := workerpool.New(runtime.NumCPU()) | |
| 87 | + firstErr := make(chan error) | |
| 88 | + go func() { | |
| 89 | + log.Fatalf("%s", <-firstErr) | |
| 90 | + }() | |
| 91 | + | |
| 83 | 92 | for _, in := range inputs { |
| 84 | − if !*quiet { | |
| 85 | − in.Dump() | |
| 86 | − fmt.Printf("\n") | |
| 87 | − } | |
| 88 | 93 | if !*dryRun { |
| 89 | − in.Split() | |
| 94 | + if err := in.Split(wp, firstErr); err != nil { | |
| 95 | + log.Fatalf("%s: %s", in.Audio.Path, err) | |
| 96 | + } | |
| 90 | 97 | } |
| 91 | 98 | } |
| 99 | + wp.StopWait() | |
| 100 | + | |
| 92 | 101 | if *jsonDump { |
| 93 | 102 | json.NewEncoder(os.Stdout).Encode(inputs) |
| 94 | 103 | } |