Compare commits

..

No commits in common. "6493b2c5fc46bf21e82372cc30a327c5245b10d0" and "b2ef27761f12adcb1af877f4595c42d960055b11" have entirely different histories.

5 changed files with 46 additions and 92 deletions

View File

@ -1,7 +1,6 @@
package ncm package ncm
import ( import (
"go.uber.org/zap"
"strings" "strings"
"unlock-music.dev/cli/algo/common" "unlock-music.dev/cli/algo/common"
@ -18,11 +17,9 @@ type ncmMeta interface {
} }
type ncmMetaMusic struct { type ncmMetaMusic struct {
logger *zap.Logger
Format string `json:"format"` Format string `json:"format"`
MusicName string `json:"musicName"` MusicName string `json:"musicName"`
Artist interface{} `json:"artist"` Artist [][]interface{} `json:"artist"`
Album string `json:"album"` Album string `json:"album"`
AlbumPicDocID interface{} `json:"albumPicDocId"` AlbumPicDocID interface{} `json:"albumPicDocId"`
AlbumPic string `json:"albumPic"` AlbumPic string `json:"albumPic"`
@ -33,34 +30,20 @@ type ncmMetaMusic struct {
TransNames []interface{} `json:"transNames"` TransNames []interface{} `json:"transNames"`
} }
func newNcmMetaMusic(logger *zap.Logger) *ncmMetaMusic {
ncm := new(ncmMetaMusic)
ncm.logger = logger.With(zap.String("module", "ncmMetaMusic"))
return ncm
}
func (m *ncmMetaMusic) GetAlbumImageURL() string { func (m *ncmMetaMusic) GetAlbumImageURL() string {
return m.AlbumPic return m.AlbumPic
} }
func (m *ncmMetaMusic) GetArtists() []string { func (m *ncmMetaMusic) GetArtists() (artists []string) {
m.logger.Debug("ncm artists", zap.Any("artists", m.Artist)) for _, artist := range m.Artist {
for _, item := range artist {
var artists []string = nil name, ok := item.(string)
if jsonArtists, ok := m.Artist.([][]string); ok { if ok {
for _, artist := range jsonArtists {
for _, name := range artist {
artists = append(artists, name) artists = append(artists, name)
} }
} }
} else if artist, ok := m.Artist.(string); ok {
// #78: artist is a string type.
// https://git.unlock-music.dev/um/cli/issues/78
artists = []string{artist}
} else {
m.logger.Warn("unexpected artist type", zap.Any("artists", m.Artist))
} }
return artists return
} }
func (m *ncmMetaMusic) GetTitle() string { func (m *ncmMetaMusic) GetTitle() string {

View File

@ -8,7 +8,6 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"go.uber.org/zap"
"io" "io"
"net/http" "net/http"
"strings" "strings"
@ -31,11 +30,10 @@ var (
) )
func NewDecoder(p *common.DecoderParams) common.Decoder { func NewDecoder(p *common.DecoderParams) common.Decoder {
return &Decoder{rd: p.Reader, logger: p.Logger.With(zap.String("module", "ncm"))} return &Decoder{rd: p.Reader}
} }
type Decoder struct { type Decoder struct {
logger *zap.Logger
rd io.ReadSeeker // rd is the original file reader rd io.ReadSeeker // rd is the original file reader
offset int offset int
@ -76,7 +74,7 @@ func (d *Decoder) Validate() error {
} }
if err := d.parseMeta(); err != nil { if err := d.parseMeta(); err != nil {
return fmt.Errorf("parse meta failed: %w (raw json=%s)", err, string(d.metaRaw)) return fmt.Errorf("parse meta failed: %w", err)
} }
d.cipher = newNcmCipher(keyData) d.cipher = newNcmCipher(keyData)
@ -183,7 +181,7 @@ func (d *Decoder) readCoverData() error {
func (d *Decoder) parseMeta() error { func (d *Decoder) parseMeta() error {
switch d.metaType { switch d.metaType {
case "music": case "music":
d.meta = newNcmMetaMusic(d.logger) d.meta = new(ncmMetaMusic)
return json.Unmarshal(d.metaRaw, d.meta) return json.Unmarshal(d.metaRaw, d.meta)
case "dj": case "dj":
d.meta = new(ncmMetaDJ) d.meta = new(ncmMetaDJ)

View File

@ -5,10 +5,6 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/fsnotify/fsnotify"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"io" "io"
"os" "os"
"os/signal" "os/signal"
@ -19,6 +15,11 @@ import (
"sort" "sort"
"strings" "strings"
"time" "time"
"github.com/fsnotify/fsnotify"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"unlock-music.dev/cli/algo/common" "unlock-music.dev/cli/algo/common"
_ "unlock-music.dev/cli/algo/kgm" _ "unlock-music.dev/cli/algo/kgm"
_ "unlock-music.dev/cli/algo/kwm" _ "unlock-music.dev/cli/algo/kwm"
@ -28,13 +29,14 @@ import (
_ "unlock-music.dev/cli/algo/xiami" _ "unlock-music.dev/cli/algo/xiami"
_ "unlock-music.dev/cli/algo/ximalaya" _ "unlock-music.dev/cli/algo/ximalaya"
"unlock-music.dev/cli/internal/ffmpeg" "unlock-music.dev/cli/internal/ffmpeg"
"unlock-music.dev/cli/internal/logging"
"unlock-music.dev/cli/internal/sniff" "unlock-music.dev/cli/internal/sniff"
"unlock-music.dev/cli/internal/utils" "unlock-music.dev/cli/internal/utils"
) )
var AppVersion = "v0.2.8" var AppVersion = "v0.2.8"
var logger = setupLogger(false) // TODO: inject logger to application, instead of using global logger var logger, _ = logging.NewZapLogger() // TODO: inject logger to application, instead of using global logger
func main() { func main() {
module, ok := debug.ReadBuildInfo() module, ok := debug.ReadBuildInfo()
@ -53,7 +55,6 @@ func main() {
&cli.StringFlag{Name: "qmc-mmkv-key", Aliases: []string{"key"}, Usage: "mmkv password (16 ascii chars)", Required: false}, &cli.StringFlag{Name: "qmc-mmkv-key", Aliases: []string{"key"}, Usage: "mmkv password (16 ascii chars)", Required: false},
&cli.BoolFlag{Name: "remove-source", Aliases: []string{"rs"}, Usage: "remove source file", Required: false, Value: false}, &cli.BoolFlag{Name: "remove-source", Aliases: []string{"rs"}, Usage: "remove source file", Required: false, Value: false},
&cli.BoolFlag{Name: "skip-noop", Aliases: []string{"n"}, Usage: "skip noop decoder", Required: false, Value: true}, &cli.BoolFlag{Name: "skip-noop", Aliases: []string{"n"}, Usage: "skip noop decoder", Required: false, Value: true},
&cli.BoolFlag{Name: "verbose", Aliases: []string{"V"}, Usage: "verbose logging", Required: false, Value: false},
&cli.BoolFlag{Name: "update-metadata", Usage: "update metadata & album art from network", Required: false, Value: false}, &cli.BoolFlag{Name: "update-metadata", Usage: "update metadata & album art from network", Required: false, Value: false},
&cli.BoolFlag{Name: "overwrite", Usage: "overwrite output file without asking", Required: false, Value: false}, &cli.BoolFlag{Name: "overwrite", Usage: "overwrite output file without asking", Required: false, Value: false},
&cli.BoolFlag{Name: "watch", Usage: "watch the input dir and process new files", Required: false, Value: false}, &cli.BoolFlag{Name: "watch", Usage: "watch the input dir and process new files", Required: false, Value: false},
@ -66,7 +67,6 @@ func main() {
HideHelpCommand: true, HideHelpCommand: true,
UsageText: "um [-o /path/to/output/dir] [--extra-flags] [-i] /path/to/input", UsageText: "um [-o /path/to/output/dir] [--extra-flags] [-i] /path/to/input",
} }
err := app.Run(os.Args) err := app.Run(os.Args)
if err != nil { if err != nil {
logger.Fatal("run app failed", zap.Error(err)) logger.Fatal("run app failed", zap.Error(err))
@ -93,27 +93,7 @@ func printSupportedExtensions() {
} }
} }
func setupLogger(verbose bool) *zap.Logger {
logConfig := zap.NewProductionEncoderConfig()
logConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
logConfig.EncodeTime = zapcore.RFC3339TimeEncoder
enabler := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
if verbose {
return true
}
return level >= zapcore.InfoLevel
})
return zap.New(zapcore.NewCore(
zapcore.NewConsoleEncoder(logConfig),
os.Stdout,
enabler,
))
}
func appMain(c *cli.Context) (err error) { func appMain(c *cli.Context) (err error) {
logger = setupLogger(c.Bool("verbose"))
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err != nil { if err != nil {
return err return err
@ -175,7 +155,6 @@ func appMain(c *cli.Context) (err error) {
} }
proc := &processor{ proc := &processor{
logger: logger,
inputDir: inputDir, inputDir: inputDir,
outputDir: output, outputDir: output,
skipNoopDecoder: c.Bool("skip-noop"), skipNoopDecoder: c.Bool("skip-noop"),
@ -198,7 +177,6 @@ func appMain(c *cli.Context) (err error) {
} }
type processor struct { type processor struct {
logger *zap.Logger
inputDir string inputDir string
outputDir string outputDir string
@ -428,7 +406,7 @@ func (p *processor) process(inputFile string, allDec []common.DecoderFactory) er
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel() defer cancel()
if err := ffmpeg.UpdateMeta(ctx, outPath, params, logger); err != nil { if err := ffmpeg.UpdateMeta(ctx, outPath, params); err != nil {
return err return err
} }
} }

View File

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"go.uber.org/zap"
"io" "io"
"os" "os"
"os/exec" "os/exec"
@ -44,9 +43,9 @@ type UpdateMetadataParams struct {
AlbumArtExt string // required if AlbumArt is not nil AlbumArtExt string // required if AlbumArt is not nil
} }
func UpdateMeta(ctx context.Context, outPath string, params *UpdateMetadataParams, logger *zap.Logger) error { func UpdateMeta(ctx context.Context, outPath string, params *UpdateMetadataParams) error {
if params.AudioExt == ".flac" { if params.AudioExt == ".flac" {
return updateMetaFlac(ctx, outPath, params, logger.With(zap.String("module", "updateMetaFlac"))) return updateMetaFlac(ctx, outPath, params)
} else { } else {
return updateMetaFFmpeg(ctx, outPath, params) return updateMetaFFmpeg(ctx, outPath, params)
} }

View File

@ -2,7 +2,6 @@ package ffmpeg
import ( import (
"context" "context"
"go.uber.org/zap"
"mime" "mime"
"strings" "strings"
@ -12,7 +11,7 @@ import (
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
func updateMetaFlac(_ context.Context, outPath string, m *UpdateMetadataParams, logger *zap.Logger) error { func updateMetaFlac(_ context.Context, outPath string, m *UpdateMetadataParams) error {
f, err := flac.ParseFile(m.Audio) f, err := flac.ParseFile(m.Audio)
if err != nil { if err != nil {
return err return err
@ -63,18 +62,16 @@ func updateMetaFlac(_ context.Context, outPath string, m *UpdateMetadataParams,
} }
if m.AlbumArt != nil { if m.AlbumArt != nil {
coverMime := mime.TypeByExtension(m.AlbumArtExt)
logger.Debug("cover image mime detect", zap.String("mime", coverMime))
cover, err := flacpicture.NewFromImageData( cover, err := flacpicture.NewFromImageData(
flacpicture.PictureTypeFrontCover, flacpicture.PictureTypeFrontCover,
"Front cover", "Front cover",
m.AlbumArt, m.AlbumArt,
coverMime, mime.TypeByExtension(m.AlbumArtExt),
) )
if err != nil { if err != nil {
logger.Warn("failed to create flac cover", zap.Error(err)) return err
} else { }
coverBlock := cover.Marshal() coverBlock := cover.Marshal()
f.Meta = append(f.Meta, &coverBlock) f.Meta = append(f.Meta, &coverBlock)
@ -88,7 +85,6 @@ func updateMetaFlac(_ context.Context, outPath string, m *UpdateMetadataParams,
f.Meta[coverIdx] = &coverBlock f.Meta[coverIdx] = &coverBlock
} }
} }
}
return f.Save(outPath) return f.Save(outPath)
} }