Skip to content

Commit 16873c1

Browse files
committed
fix: update and replace dependencies
1 parent 6610662 commit 16873c1

8 files changed

Lines changed: 238 additions & 170 deletions

File tree

cmd/mkc/internal/cli/cli.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,18 @@ package cli
22

33
import (
44
"errors"
5-
"flag"
5+
flag "github.com/spf13/pflag"
66
"os"
77
)
88

9-
var SpinnerCharSet = []string{"[ ]", "[= ]", "[== ]", "[=== ]", "[==== ]", "[ ==== ]", "[ ==== ]", "[ ====]", "[ ===]", "[ ==]", "[ =]"}
10-
119
type Command struct {
1210
Flags *flag.FlagSet
1311
Run func(flags *flag.FlagSet)
1412
}
1513

1614
// ValidatorFile only allows file paths
17-
func ValidatorFile(val interface{}) error {
18-
p, ok := val.(string)
19-
if !ok {
20-
panic("cli: validator only applies to string values")
21-
}
22-
s, err := os.Stat(p)
15+
func ValidatorFile(val string) error {
16+
s, err := os.Stat(val)
2317
if os.IsNotExist(err) {
2418
return errors.New("Path has to represent an existing file")
2519
}
@@ -30,12 +24,8 @@ func ValidatorFile(val interface{}) error {
3024
}
3125

3226
// ValidatorDir only allows directory paths
33-
func ValidatorDir(val interface{}) error {
34-
p, ok := val.(string)
35-
if !ok {
36-
panic("cli: validator only applies to string values")
37-
}
38-
s, err := os.Stat(p)
27+
func ValidatorDir(val string) error {
28+
s, err := os.Stat(val)
3929
if os.IsNotExist(err) {
4030
return errors.New("Path has to represent an existing dir")
4131
}

cmd/mkc/internal/extract/extract.go

Lines changed: 100 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package extract
22

33
import (
4-
"flag"
4+
"errors"
55
"fmt"
6-
"github.com/AlecAivazis/survey/v2"
7-
"github.com/AlecAivazis/survey/v2/terminal"
8-
"github.com/briandowns/spinner"
6+
"github.com/charmbracelet/huh"
7+
"github.com/charmbracelet/huh/spinner"
98
"github.com/coding-socks/matroska"
109
"github.com/coding-socks/matroska/cmd/mkc/internal/cli"
10+
flag "github.com/spf13/pflag"
1111
"log"
1212
"os"
1313
"path/filepath"
1414
"strings"
15-
"time"
1615
)
1716

1817
var Cmd = &cli.Command{
@@ -23,89 +22,126 @@ func init() {
2322
Cmd.Run = run
2423
}
2524

26-
var flagOutput = Cmd.Flags.String("output", "", "Path to the output folder.")
25+
var flagOutput = Cmd.Flags.StringP("output", "o", "", "Path to the output folder.")
26+
var flagTracks = Cmd.Flags.UintSliceP("tracks", "t", []uint{}, "Id of track to extract")
2727

2828
type arguments struct {
2929
Input string
3030
Output string
31+
Tracks []uint
3132
}
3233

3334
func run(flags *flag.FlagSet) {
3435
args := arguments{
3536
Input: flags.Arg(0),
3637
Output: *flagOutput,
38+
Tracks: *flagTracks,
3739
}
38-
var questions []*survey.Question
3940
if args.Input == "" {
40-
questions = append(questions, &survey.Question{
41-
Name: "input",
42-
Prompt: &survey.Input{Message: "Source matroska file:"},
43-
Validate: survey.ComposeValidators(survey.Required, cli.ValidatorFile),
44-
})
41+
err := huh.NewInput().
42+
Title("Source matroska file:").
43+
Prompt("?").
44+
Validate(cli.ValidatorFile).
45+
Value(&args.Input).
46+
Run()
47+
if errors.Is(err, huh.ErrUserAborted) {
48+
return
49+
} else if err != nil {
50+
log.Fatal(err)
51+
}
4552
}
4653
if args.Output == "" {
47-
questions = append(questions, &survey.Question{
48-
Name: "output",
49-
Prompt: &survey.Input{Message: "Output folder:"},
50-
Validate: survey.ComposeValidators(survey.Required, cli.ValidatorDir),
51-
})
52-
}
53-
if err := survey.Ask(questions, &args); err == terminal.InterruptErr {
54-
return
55-
} else if err != nil {
56-
log.Fatal(err)
54+
err := huh.NewInput().
55+
Title("Output folder:").
56+
Prompt("?").
57+
Validate(cli.ValidatorDir).
58+
Value(&args.Output).
59+
Run()
60+
if errors.Is(err, huh.ErrUserAborted) {
61+
return
62+
} else if err != nil {
63+
log.Fatal(err)
64+
}
5765
}
5866

5967
f, err := os.Open(args.Input)
6068
if err != nil {
6169
log.Fatalf("Could not open input file: %s", args.Input)
6270
}
6371
defer f.Close()
64-
spin := spinner.New(cli.SpinnerCharSet, 200*time.Millisecond)
65-
spin.Prefix = "Loading file into memory "
66-
spin.Start()
67-
s, err := matroska.NewScanner(f)
68-
spin.Stop()
69-
if err != nil {
70-
log.Fatal(err)
71-
}
72-
tracks := s.Tracks()
73-
options := make([]string, len(tracks.TrackEntry))
74-
for i, e := range tracks.TrackEntry {
75-
options[i] = fmt.Sprintf("Track %02d [%s]", e.TrackNumber, e.CodecID)
76-
}
77-
var trackIndex int
78-
err = survey.AskOne(&survey.Select{
79-
Message: "Select track",
80-
Options: options,
81-
}, &trackIndex)
82-
if err == terminal.InterruptErr {
72+
73+
var (
74+
s *matroska.Scanner
75+
actionErr error
76+
)
77+
err = spinner.New().
78+
Title("Loading file into memory").
79+
Action(func() {
80+
s, actionErr = matroska.NewScanner(f)
81+
}).
82+
Run()
83+
if errors.Is(err, huh.ErrUserAborted) {
8384
return
8485
} else if err != nil {
8586
log.Fatal(err)
8687
}
87-
te := tracks.TrackEntry[trackIndex]
8888

89-
spin.Start()
90-
fname := filepath.Base(args.Input)
91-
fname = strings.TrimSuffix(fname, filepath.Ext(fname))
92-
fname = fmt.Sprintf("%s_Track_%02d", fname, te.TrackNumber)
93-
suffix := ""
94-
ext := GuessExt(te.CodecID)
95-
for i := 1; ; i++ {
96-
_, err := os.Stat(filepath.Join(args.Output, fname+suffix+ext))
97-
if os.IsNotExist(err) {
98-
break
99-
}
100-
suffix = fmt.Sprintf("_%d", i)
89+
if err = actionErr; err != nil {
90+
log.Fatal(err)
10191
}
102-
f, err = os.Create(filepath.Join(args.Output, fname+suffix+ext))
103-
if err != nil {
104-
log.Fatalf("Could not create ouput file: %s", err)
92+
tracks := s.Tracks()
93+
if len(args.Tracks) == 0 {
94+
options := make([]huh.Option[uint], len(tracks.TrackEntry))
95+
for i, e := range tracks.TrackEntry {
96+
options[i] = huh.NewOption(fmt.Sprintf("Track %02d [%s]", e.TrackNumber, e.CodecID), e.TrackNumber)
97+
}
98+
err = huh.NewMultiSelect[uint]().
99+
Title("Track:").
100+
Options(options...).
101+
Value(&args.Tracks).
102+
Run()
103+
if errors.Is(err, huh.ErrUserAborted) {
104+
return
105+
} else if err != nil {
106+
log.Fatal(err)
107+
}
105108
}
106-
if err := matroska.ExtractTract(f, s, te); err != nil {
107-
os.Remove(filepath.Join(args.Output, fname))
108-
log.Fatalf("Could not extract track: %s", err)
109+
110+
for _, trackIndex := range args.Tracks {
111+
te := tracks.TrackEntry[trackIndex-1]
112+
113+
err = spinner.New().
114+
Action(func() {
115+
fname := filepath.Base(args.Input)
116+
fname = strings.TrimSuffix(fname, filepath.Ext(fname))
117+
fname = fmt.Sprintf("%s_Track_%02d", fname, te.TrackNumber)
118+
suffix := ""
119+
ext := GuessExt(te.CodecID)
120+
for i := 1; ; i++ {
121+
_, err := os.Stat(filepath.Join(args.Output, fname+suffix+ext))
122+
if os.IsNotExist(err) {
123+
break
124+
}
125+
suffix = fmt.Sprintf("_%d", i)
126+
}
127+
f, err := os.Create(filepath.Join(args.Output, fname+suffix+ext))
128+
if err != nil {
129+
actionErr = fmt.Errorf("could not create ouput file: %s", err)
130+
return
131+
}
132+
if err := matroska.ExtractTract(f, s, te); err != nil {
133+
os.Remove(filepath.Join(args.Output, fname))
134+
log.Fatalf("Could not extract track: %s", err)
135+
}
136+
}).
137+
Run()
138+
if errors.Is(err, huh.ErrUserAborted) {
139+
return
140+
} else if err != nil {
141+
log.Fatal(err)
142+
} else if err = actionErr; err != nil {
143+
log.Fatal(err)
144+
}
109145
}
110146
}
111147

@@ -116,8 +152,12 @@ func GuessExt(codecID string) string {
116152
return ".aac"
117153
case matroska.AudioCodecAC3:
118154
return ".ac3"
155+
case matroska.AudioCodecMP2:
156+
return ".mp2"
119157
case matroska.AudioCodecMP3:
120158
return ".mp3"
159+
case matroska.AudioCodecVORBIS:
160+
return ".ogg"
121161
// Video
122162
case matroska.VideoCodecMSCOMP:
123163
return ".avi"

cmd/mkc/internal/list/list.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ package list
22

33
import (
44
"errors"
5-
"flag"
65
"fmt"
7-
"github.com/AlecAivazis/survey/v2"
8-
"github.com/AlecAivazis/survey/v2/terminal"
6+
"github.com/charmbracelet/huh"
97
"github.com/coding-socks/ebml"
108
"github.com/coding-socks/ebml/ebmltext"
119
"github.com/coding-socks/matroska"
1210
"github.com/coding-socks/matroska/cmd/mkc/internal/cli"
11+
flag "github.com/spf13/pflag"
1312
"io"
1413
"log"
1514
"os"
@@ -33,18 +32,18 @@ func run(flags *flag.FlagSet) {
3332
args := arguments{
3433
Input: flags.Arg(0),
3534
}
36-
var questions []*survey.Question
3735
if args.Input == "" {
38-
questions = append(questions, &survey.Question{
39-
Name: "input",
40-
Prompt: &survey.Input{Message: "Source matroska file:"},
41-
Validate: survey.ComposeValidators(survey.Required, cli.ValidatorFile),
42-
})
43-
}
44-
if err := survey.Ask(questions, &args); errors.Is(err, terminal.InterruptErr) {
45-
return
46-
} else if err != nil {
47-
log.Fatal(err)
36+
err := huh.NewInput().
37+
Title("Source matroska file:").
38+
Prompt("?").
39+
Validate(cli.ValidatorFile).
40+
Value(&args.Input).
41+
Run()
42+
if errors.Is(err, huh.ErrUserAborted) {
43+
return
44+
} else if err != nil {
45+
log.Fatal(err)
46+
}
4847
}
4948

5049
f, err := os.Open(args.Input)

cmd/mkc/main.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package main
22

33
import (
4+
"errors"
45
"flag"
56
"fmt"
6-
"github.com/AlecAivazis/survey/v2"
7-
"github.com/AlecAivazis/survey/v2/terminal"
7+
"github.com/charmbracelet/huh"
88
"github.com/coding-socks/matroska/cmd/mkc/internal/cli"
99
"github.com/coding-socks/matroska/cmd/mkc/internal/extract"
1010
"github.com/coding-socks/matroska/cmd/mkc/internal/list"
@@ -23,18 +23,19 @@ func main() {
2323
mode := flag.Arg(0)
2424

2525
if mode == "" {
26-
options := make([]string, len(commands))
26+
options := make([]huh.Option[string], len(commands))
2727
for i := range commands {
28-
options[i] = commands[i].Flags.Name()
28+
options[i] = huh.NewOption(commands[i].Flags.Name(), commands[i].Flags.Name())
2929
}
30-
modeSelector := &survey.Select{
31-
Message: "Choose a mode:",
32-
Options: options,
30+
err := huh.NewSelect[string]().
31+
Title("Choose a mode:").
32+
Options(options...).
33+
Value(&mode).
34+
Run()
35+
if errors.Is(err, huh.ErrUserAborted) {
36+
return
3337
}
34-
if err := survey.AskOne(modeSelector, &mode); err != nil {
35-
if err == terminal.InterruptErr {
36-
return
37-
}
38+
if err != nil {
3839
log.Fatal(err)
3940
}
4041
}

extract_audio.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ func extractTrackAudio(w io.Writer, s *Scanner, t TrackEntry) error {
1414
}
1515

1616
func extractTrackMPEG(w io.Writer, s *Scanner, t TrackEntry) error {
17-
var blocks []block
1817
for s.Next() {
1918
c := s.Cluster()
2019
m := len(c.SimpleBlock) + len(c.BlockGroup)
@@ -27,7 +26,9 @@ func extractTrackMPEG(w io.Writer, s *Scanner, t TrackEntry) error {
2726
return fmt.Errorf("matroska: could not create block struct: %w", err)
2827
}
2928
if block.TrackNumber() == t.TrackNumber {
30-
blocks = append(blocks, block)
29+
if _, err := io.Copy(w, block.Data()); err != nil {
30+
return err
31+
}
3132
}
3233
}
3334
for i := range c.BlockGroup {
@@ -36,14 +37,11 @@ func extractTrackMPEG(w io.Writer, s *Scanner, t TrackEntry) error {
3637
return fmt.Errorf("matroska: could not create block struct: %w", err)
3738
}
3839
if block.TrackNumber() == t.TrackNumber {
39-
blocks = append(blocks, block)
40+
if _, err := io.Copy(w, block.Data()); err != nil {
41+
return err
42+
}
4043
}
4144
}
4245
}
43-
for _, block := range blocks {
44-
if _, err := io.Copy(w, block.Data()); err != nil {
45-
return err
46-
}
47-
}
4846
return nil
4947
}

0 commit comments

Comments
 (0)