diff --git a/LICENSE b/LICENSE index c2984bc..e69de29 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +0,0 @@ -© 2023 Dan Jones - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index fc4e3a9..0000000 --- a/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# strip-beats - -Imagine you have a folder full of music videos. You want to go through those videos, turn it into an audio file, tag them, and add it to your music collection. - -This app aims to streamline that. - -## Pre-requisites - -- ffmpeg -- fpcalc (for fingerprinting audio so that we can identify it and automatically pull tags) -- mpv (for watching the video to ensure you're stipping out non-music elements, like an intro or outro) -- An account on acousticid.org (for querying the fingerprint to get data) - -## Install - -- Pull the repo -- `go install .` - -Hopefully, I'll have binaries downloadable soon. - -## Disclaimer - -This does not work yet! Some features are implemented, but most are not yet. Have a look around at the code, but don't actually use this at all. diff --git a/app/choose.go b/app/choose.go index da98672..4d07959 100644 --- a/app/choose.go +++ b/app/choose.go @@ -5,7 +5,7 @@ import ( "os" "codeberg.org/danjones000/strip-beats/files" - "codeberg.org/danjones000/strip-beats/io/boolean" + "codeberg.org/danjones000/strip-beats/input/boolean" "codeberg.org/danjones000/strip-beats/media" "codeberg.org/danjones000/strip-beats/utils" "github.com/rkoesters/xdg/trash" @@ -20,10 +20,8 @@ func PickNewFile() media.Probe { } func SetFile(path string) media.Probe { - resetTags() f := media.ProbeFile(path) file = &f - copyTagsFromFile() return f } @@ -72,7 +70,6 @@ func PickAgain() { } file = nil tmpfile = nil - resetTags() } func Finish() { diff --git a/app/convert.go b/app/convert.go deleted file mode 100644 index e6d708d..0000000 --- a/app/convert.go +++ /dev/null @@ -1,16 +0,0 @@ -package app - -import ( - "fmt" - - "codeberg.org/danjones000/strip-beats/media" - "codeberg.org/danjones000/strip-beats/utils" -) - -func convert() { - in := utils.Tern(tmpfile == nil, file, tmpfile) - out, _ := media.ConvertAndTag(*in, tags) - fmt.Println(out) - - quit() -} diff --git a/app/fade.go b/app/fade.go index 64882d3..290e0f4 100644 --- a/app/fade.go +++ b/app/fade.go @@ -2,8 +2,6 @@ package app import ( "os" - p "path/filepath" - s "strings" "codeberg.org/danjones000/strip-beats/media" "codeberg.org/danjones000/strip-beats/utils" @@ -33,10 +31,7 @@ func validateNumber(input string, lastChar rune) bool { } func fadeFile() error { - base := p.Base(file.Format.Path) - ext := p.Ext(base) - base = s.TrimSuffix(base, ext) - tmp, err := os.CreateTemp("", base+".*.mka") + tmp, err := os.CreateTemp("", "audio.*.mka") if err != nil { return err } diff --git a/app/menu.go b/app/menu.go index 96b3ac0..2e5cdd1 100644 --- a/app/menu.go +++ b/app/menu.go @@ -3,14 +3,14 @@ package app import ( "fmt" - "codeberg.org/danjones000/strip-beats/io/list" + "codeberg.org/danjones000/strip-beats/input/list" ) func (st AppStep) Title() string { mustpick := "You need to pick a file" switch st { case Pick: - return "Pick a new file" + return "Pick a new show" case Watch: if file == nil { return mustpick @@ -26,11 +26,6 @@ func (st AppStep) Title() string { return mustpick } return fmt.Sprintf("Should we try to identify %s", file.ShortPath()) - case Convert: - if file == nil { - return mustpick - } - return fmt.Sprintf("Convert %s?", file.ShortPath()) case Restart: return "Forget current selection" case Quit: @@ -59,8 +54,6 @@ func (st AppStep) Rune() rune { return 'r' case Print: return 'a' - case Convert: - return 'c' case Quit: return 'q' default: @@ -77,7 +70,7 @@ func mainMenu() AppStep { if file == nil { steps = []list.Option{Pick, Quit} } else { - steps = []list.Option{Pick, Watch, Fade, Print, Convert, Quit} + steps = []list.Option{Pick, Watch, Fade, Print, Quit} } step := list.List("What would you like to do next?", steps, nil) diff --git a/app/print.go b/app/print.go index 1a87c68..7ce26dc 100644 --- a/app/print.go +++ b/app/print.go @@ -3,48 +3,15 @@ package app import ( "fmt" - "codeberg.org/danjones000/strip-beats/io/boolean" - "codeberg.org/danjones000/strip-beats/io/list" - m "codeberg.org/danjones000/strip-beats/io/message" "codeberg.org/danjones000/strip-beats/media" "codeberg.org/danjones000/strip-beats/media/brainz" - "codeberg.org/danjones000/strip-beats/utils" - "github.com/akrennmair/slice" ) -type recOpt struct { - rec brainz.Recording - r rune - score float64 -} - -func (o recOpt) Title() string { - return o.rec.Title -} - -func (o recOpt) Text() string { - return fmt.Sprintf( - "(Score %.2f) By %s - First Released %s - %s %s", - 100*o.score, - o.rec.FirstArtist().Name, - o.rec.FirstReleaseDate, - o.rec.FirstGenre().Name, - utils.Tern(o.rec.Video, "(Video)", "")) -} - -func (o recOpt) Rune() rune { - return o.r -} - -func (o recOpt) Selected() func() { - return nil -} - func print() { if file == nil { PickFileWithConf() } - fp, err := media.Fingerprint(file.Format.Path) + fp, err := media.Fingerprint("/home/drj/MyFiles/Videos/WebShows/YouTube/Dolly_Parton_-_Topic/Just_Because_I_m_a_Woman.Dolly_Parton_-_Topic.Fmv-XQerVkM.webm") if err != nil { panic(err) } @@ -52,136 +19,17 @@ func print() { if err != nil { panic(err) } - rec, ok := chooseRec(ids) - if !ok { - m.Message("Couldn't find a marching recording") - return - } - - fmt.Println(rec.Title) - - tags.Title = rec.Title - - tags.MusicbrainzRecordingId = rec.Id - tags.Date = rec.FirstReleaseDate - tags.Genre = rec.FirstGenre().Name - tags.Artist = rec.FirstArtist().Name - tags.ArtistSort = rec.FirstArtist().SortName - tags.AcoustidId = rec.AcousticId - - rel := findFirstRelease(rec) - if !boolean.Choose(fmt.Sprintf("Is %s album (%s %s) correct?", rel.Title, rel.Country, rel.Date)) { - rel = chooseRel(rec) - } - media := rel.Media[0] - track := media.Tracks[0] - full, err := brainz.GetReleaseWithMedia(rel.Id) - if err != nil { - panic(err) - } - albumArtist := full.ArtistCredit[0] - - tags.MusicbrainzReleaseGroupId = full.ReleaseGroup.Id - tags.MusicbrainzAlbumId = rel.Id - tags.MusicbrainzAlbumArtistId = albumArtist.Artist.Id - tags.AlbumArtist = albumArtist.Name - tags.Album = rel.Title - if rel.Date != "" { - tags.Date = rel.Date - } - tags.AlbumArtistSort = albumArtist.Artist.SortName - tags.ReleaseCountry = rel.Country - if len(full.LabelInfo) > 0 { - tags.Label = full.LabelInfo[0].Label.Name - tags.MusicBrainzLabelId = full.LabelInfo[0].Label.Id - } - if len(rel.Genres) > 0 && rel.Genres[0].Name != "" { - tags.Genre = rel.Genres[0].Name - } - tags.Disc = media.Position - tags.DiscCount = len(full.Media) - tags.Track = track.Position - tags.TrackCount = media.TrackCount -} - -func chooseRec(ids media.IdResults) (brainz.Recording, bool) { - var recs []list.Option - var rec brainz.Recording - var err error - i := 'a' + var recs []brainz.Recording for _, res := range ids.Results { - for _, rec = range res.Recordings { + for _, rec := range res.Recordings { err = brainz.FillRecording(&rec) if err != nil { panic(err) } - rec.AcousticId = res.Id - recs = append(recs, recOpt{rec, i, res.Score}) - if rec.Title != "" { - // Empty titles will be filtered out, so we don't need to increment them - i = i + 1 - } + recs = append(recs, rec) + } } - recs = slice.Filter(recs, func(opt list.Option) bool { - return opt.Title() != "" - }) - if len(recs) < 1 { - return rec, false - } - - return list.List("Which recording is the correct one?", recs, nil).(recOpt).rec, true -} - -func findFirstRelease(rec brainz.Recording) brainz.Release { - var rel brainz.Release - for _, rel = range rec.Releases { - if rel.Date == rec.FirstReleaseDate { - return rel - } - } - if len(rec.Releases) > 0 { - return rec.Releases[0] - } - return brainz.Release{} -} - -func chooseRel(rec brainz.Recording) brainz.Release { - var rels []list.Option - var rel brainz.Release - i := 'a' - for _, rel = range rec.Releases { - rels = append(rels, relOpt{rel, i}) - if rel.Title != "" { - // Empty titles will be filtered out, so we don't need to increment them - i = i + 1 - } - } - rels = slice.Filter(rels, func(opt list.Option) bool { - return opt.Title() != "" - }) - - return list.List("Which releases is the correct one?", rels, nil).(relOpt).rel -} - -type relOpt struct { - rel brainz.Release - r rune -} - -func (o relOpt) Title() string { - return o.rel.Title -} - -func (o relOpt) Text() string { - return fmt.Sprintf("%s %s", o.rel.Country, o.rel.Date) -} - -func (o relOpt) Rune() rune { - return o.r -} - -func (o relOpt) Selected() func() { - return nil + fmt.Printf("%+v\n", recs) } diff --git a/app/run.go b/app/run.go index cf01523..a42b1ab 100644 --- a/app/run.go +++ b/app/run.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "codeberg.org/danjones000/strip-beats/io/boolean" + "codeberg.org/danjones000/strip-beats/input/boolean" "codeberg.org/danjones000/strip-beats/media" "codeberg.org/danjones000/strip-beats/media/brainz" ) @@ -16,7 +16,6 @@ const ( Watch Fade Print - Convert Restart Quit ) @@ -52,17 +51,14 @@ func testMb() { } func testPrint() { - // SetFile("/home/drj/MyFiles/Videos/WebShows/YouTube/Dolly_Parton_-_Topic/Just_Because_I_m_a_Woman.Dolly_Parton_-_Topic.Fmv-XQerVkM.webm") - // SetFile("/home/drj/MyFiles/Videos/WebShows/YouTube/Whitney_Houston/I_Will_Always_Love_You_Ultimate_Collection_Edit.Whitney_Houston.rB7z_l8mBxw.mp4") - SetFile("/home/drj/MyFiles/Music/Original_Broadway_Cast_of_Hamilton/Hamilton/d02t12-We_Know.m4a") - // SetFile("/home/drj/MyFiles/Videos/WebShows/YouTube/KaceyMusgravesVEVO/Kacey_Musgraves_-_Biscuits-nGIUtLO_x8g.mp4") - // SetFile("/home/drj/MyFiles/Videos/WebShows/YouTube/Willie_Nelson_-_Topic/Too_Sick_To_Pray.Willie_Nelson_-_Topic.8QgBXo41j2E.webm") + SetFile("/home/drj/MyFiles/Videos/WebShows/YouTube/Dolly_Parton_-_Topic/Just_Because_I_m_a_Woman.Dolly_Parton_-_Topic.Fmv-XQerVkM.webm") print() quit() } func Run(step AppStep) { + testPrint() for step < Quit { switch step { case Pick: @@ -95,9 +91,6 @@ func Run(step AppStep) { case Print: print() step = mainMenu() - case Convert: - convert() - step = mainMenu() case Quit: quit() default: diff --git a/app/tags.go b/app/tags.go deleted file mode 100644 index cd25b4d..0000000 --- a/app/tags.go +++ /dev/null @@ -1,21 +0,0 @@ -package app - -import ( - "errors" - - t "codeberg.org/danjones000/strip-beats/media/tags" -) - -var tags t.Tags - -func resetTags() { - tags = t.Tags{} -} - -func copyTagsFromFile() { - if file == nil { - panic(errors.New("Missing file")) - } - - tags = file.FullTags() -} diff --git a/cmd/root.go b/cmd/root.go index a04a3ce..13aaf4b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,5 +1,5 @@ /* -Copyright © 2023 Dan Jones +Copyright © 2023 NAME HERE */ package cmd diff --git a/config/config.go b/config/config.go index fbd3af9..7c4d5fa 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,7 @@ import ( const ( AppName string = "strip-beats" - Version string = "0.1.1" + Version string = "0.1.0" Url string = "https://codeberg.org/danjones000/strip-beats" Email string = "danjones@goodevilgenius.org" UserAgent string = AppName + "/" + Version + " (" + Url + "; " + Email + ")" diff --git a/go.mod b/go.mod index ab3c23e..093ef9b 100644 --- a/go.mod +++ b/go.mod @@ -13,25 +13,21 @@ require ( github.com/rivo/tview v0.0.0-20230826224341-9754ab44dc1c github.com/rkoesters/xdg v0.0.1 github.com/spf13/cobra v1.7.0 - github.com/stretchr/testify v1.7.0 github.com/u2takey/ffmpeg-go v0.5.0 golang.org/x/term v0.11.0 ) require ( github.com/aws/aws-sdk-go v1.38.20 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect github.com/gdamore/encoding v1.0.0 // indirect github.com/gdamore/tcell/v2 v2.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/u2takey/go-utils v0.3.1 // indirect golang.org/x/sys v0.11.0 // indirect golang.org/x/text v0.7.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a93a960..6e6d58e 100644 --- a/go.sum +++ b/go.sum @@ -117,7 +117,6 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/io/boolean/boolean.go b/input/boolean/boolean.go similarity index 100% rename from io/boolean/boolean.go rename to input/boolean/boolean.go diff --git a/io/list/list.go b/input/list/list.go similarity index 100% rename from io/list/list.go rename to input/list/list.go diff --git a/io/message/message.go b/io/message/message.go deleted file mode 100644 index c73ffcd..0000000 --- a/io/message/message.go +++ /dev/null @@ -1,20 +0,0 @@ -package message - -import "github.com/rivo/tview" - -func Message(text string) { - app := tview.NewApplication() - modal := tview.NewModal() - if text != "" { - modal.SetText(text) - } - - modal.AddButtons([]string{"Ok"}). - SetDoneFunc(func(buttonIndex int, buttonLabel string) { - app.Stop() - }) - - if err := app.SetRoot(modal, false).EnableMouse(true).Run(); err != nil { - panic(err) - } -} diff --git a/main.go b/main.go index a2c4aef..e7b5f1c 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,6 @@ /* -Copyright © 2023 Dan Jones +Copyright © 2023 NAME HERE + */ package main diff --git a/media/brainz/brainz.go b/media/brainz/brainz.go index 47bd4c9..da9d999 100644 --- a/media/brainz/brainz.go +++ b/media/brainz/brainz.go @@ -12,7 +12,6 @@ import ( type Recording struct { Id uuid.UUID - AcousticId uuid.UUID Isrcs []string FirstReleaseDate string `json:"first-release-date"` Length int @@ -20,45 +19,6 @@ type Recording struct { Video bool Releases []Release Genres []Genre - ArtistCredit []ArtistCredit `json:"artist-credit"` -} - -func (r Recording) FirstArtist() Artist { - var a Artist - for _, ac := range r.ArtistCredit { - if ac.Artist.Name != "" { - return ac.Artist - } - } - for _, rel := range r.Releases { - for _, ac := range rel.ArtistCredit { - if ac.Artist.Name != "" { - return ac.Artist - } - } - } - - if a.Name == "" { - a.Name = "Unknown Artist" - } - return a -} - -func (r Recording) FirstGenre() Genre { - var g Genre - for _, g = range r.Genres { - if g.Name != "" { - return g - } - } - for _, rel := range r.Releases { - for _, g = range rel.Genres { - if g.Name != "" { - return g - } - } - } - return g } type Genre struct { @@ -67,57 +27,21 @@ type Genre struct { } type Release struct { - Id uuid.UUID - Asin string - Barcode string - Country string - Date string - Disambiguation string - Media []Media - Packaging string - PackagingId uuid.UUID `json:"packaging-id"` - Quality string - Status string - StatusId uuid.UUID `json:"status-id"` - ArtistCredit []ArtistCredit `json:"artist-credit"` - Title string - Genres []Genre - ReleaseGroup ReleaseGroup `json:"release-group"` - LabelInfo []LabelInfo `json:"label-info"` + Id uuid.UUID + Country string + Date string + Media []Media + Status string + StatusId uuid.UUID `json:"status-id"` + ArtistCredit []ArtistCredit `json:"artist-credit"` + Title string + Genres []Genre // ReleaseEvents []ReleaseEvent `json:"release-events"` } -type LabelInfo struct { - CatalogNumber string `json:"catalog-number"` - Label Label -} - -type Label struct { - Id uuid.UUID - Name string - SortName string `json:"sort-name"` - Disambiguation string - TypeId string `json:"type-id"` - Type string - LabelCode int `json:"label-code"` -} - -type ReleaseGroup struct { - Id uuid.UUID - Title string - ArtistCredit []ArtistCredit `json:"artist-credit"` - Disambiguation string - FirstReleaseDate string `json:"first-release-date"` - PrimaryType string `json:"primary-type"` - PrimaryTypeId uuid.UUID `json:"primary-type-id"` - SecondaryTypes []string `json:"secondary-types"` - SecondaryTypeIds []uuid.UUID `json:"secondary-type-ids"` -} - type ArtistCredit struct { - Name string - Artist Artist - JoinPhrase string + Name string + Artist Artist } type Artist struct { @@ -132,7 +56,6 @@ type Artist struct { type Media struct { FormatId uuid.UUID `json:"format-id"` Position int - Title string TrackOffset int `json:"track-offset"` Format string TrackCount int `json:"track-count"` @@ -147,25 +70,6 @@ type Track struct { Length int } -func GetReleaseWithMedia(id uuid.UUID) (Release, error) { - rel := Release{Id: id} - url := fmt.Sprintf("https://musicbrainz.org/ws/2/release/%s", id) - resp, err := h.GetWithQuery(url, u.Values{ - "fmt": []string{"json"}, - "inc": []string{"artist-credits+discids+labels+release-groups"}}) - if err != nil { - return rel, err - } - defer resp.Body.Close() - body, err := io.ReadAll(resp.Body) - if err != nil { - return rel, err - } - err = json.Unmarshal(body, &rel) - - return rel, err -} - func GetRecording(id string) (Recording, error) { u, err := uuid.Parse(id) rec := Recording{Id: u} diff --git a/media/ffmpeg.go b/media/ffmpeg.go index 5ff6c3e..9dfa4c2 100644 --- a/media/ffmpeg.go +++ b/media/ffmpeg.go @@ -3,142 +3,12 @@ package media import ( "errors" "fmt" - p "path/filepath" "strconv" - s "strings" "codeberg.org/danjones000/strip-beats/config" - t "codeberg.org/danjones000/strip-beats/media/tags" - "codeberg.org/danjones000/strip-beats/utils" - "github.com/google/uuid" ffmpeg "github.com/u2takey/ffmpeg-go" ) -func ConvertAndTag(in Probe, tags t.Tags) (string, error) { - st := in.GetFirstAcceptableAudio() - if st == nil { - st = in.GetFirstAudio() - } - if st == nil { - return "", errors.New("Can't find an audio stream") - } - - conf := config.GetConfig() - codec := utils.Tern(st.isAcceptableCodec(), "copy", conf.FfEncoder) - target := utils.Tern(st.isAcceptableCodec(), st.CodecName, conf.Codec) - - base := p.Base(in.Format.Path) - ext := p.Ext(base) - base = s.TrimSuffix(base, ext) - ext = conf.CodecExt[target] - - out := p.Join(conf.SavePath, base+"."+ext) - - input := ffmpeg.Input(in.Format.Path).Get(strconv.Itoa(st.Index)) - args := ffmpeg.KwArgs{"c:a": codec} - output := input.Output(out, args, getMetadataArgs(ext, tags)).GlobalArgs("-y") - - return out, output.Run() -} - -func getMetadataArgs(ext string, tags t.Tags) ffmpeg.KwArgs { - var meta []string - args := ffmpeg.KwArgs{} - switch ext { - case "opus": - fallthrough - case "flac": - fallthrough - case "ogg": - meta = append(meta, mapMetaKeys(getOggMeta(tags))...) - case "m4a": - fallthrough - case "mp4": - meta = append(meta, mapMetaKeys(getMp4Meta(tags))...) - case "mp3": - // @todo meta = append(meta, mapMetaKeys(getMp3Meta(tags))...) - } - - meta = append(meta, "comment=Processed by "+config.UserAgent) - args["metadata"] = meta - return args -} - -func mapMetaKeys(meta map[string]string) []string { - out := []string{} - for k, v := range meta { - if v != "" { - out = append(out, fmt.Sprintf("%s=%s", k, v)) - } - } - return out -} - -func getOggMeta(tags t.Tags) map[string]string { - meta := map[string]string{} - meta["TITLE"] = tags.Title - meta["ARTIST"] = tags.Artist - meta["ALBUM_ARTIST"] = tags.AlbumArtist - meta["ALBUMARTIST"] = tags.AlbumArtist - meta["ALBUM"] = tags.Album - meta["DATE"] = tags.Date - year, _, _ := s.Cut(tags.Date, "-") - meta["YEAR"] = year - meta["URL"] = tags.Url - meta["PURL"] = tags.Url - meta["URI"] = tags.Url - meta["ARTISTSORT"] = tags.ArtistSort - meta["ALBUMARTISTSORT"] = tags.AlbumArtistSort - meta["RELEASECOUNTRY"] = tags.ReleaseCountry - meta["LABEL"] = tags.Label - meta["GENRE"] = tags.Genre - meta["DISC"] = utils.Tern(tags.Disc > 0, strconv.Itoa(tags.Disc), "") - meta["DISCTOTAL"] = utils.Tern(tags.DiscCount > 0, strconv.Itoa(tags.DiscCount), "") - meta["TRACK"] = utils.Tern(tags.Track > 0, strconv.Itoa(tags.Track), "") - meta["TRACKTOTAL"] = utils.Tern(tags.TrackCount > 0, strconv.Itoa(tags.TrackCount), "") - if tags.AcoustidId != uuid.Nil { - meta["ACOUSTID_ID"] = tags.AcoustidId.String() - } - if tags.MusicbrainzReleaseGroupId != uuid.Nil { - meta["MUSICBRAINZ_RELEASEGROUPID"] = tags.MusicbrainzReleaseGroupId.String() - } - if tags.MusicbrainzAlbumId != uuid.Nil { - meta["MUSICBRAINZ_ALBUMID"] = tags.MusicbrainzAlbumId.String() - } - if tags.MusicbrainzAlbumArtistId != uuid.Nil { - meta["MUSICBRAINZ_ALBUMARTISTID"] = tags.MusicbrainzAlbumArtistId.String() - } - if tags.MusicbrainzRecordingId != uuid.Nil { - meta["MUSICBRAINZ_RECORDINGID"] = tags.MusicbrainzRecordingId.String() - } - if tags.MusicBrainzLabelId != uuid.Nil { - meta["MUSICBRAINZ_LABELID"] = tags.MusicBrainzLabelId.String() - } - - return meta -} - -func getMp4Meta(tags t.Tags) map[string]string { - meta := map[string]string{} - meta["title"] = tags.Title - meta["artist"] = tags.Artist - meta["album_artist"] = tags.AlbumArtist - meta["album"] = tags.Album - year, _, _ := s.Cut(tags.Date, "-") - meta["year"] = year - meta["description"] = tags.Url - meta["genre"] = tags.Genre - meta["network"] = tags.Label - if tags.Disc > 0 { - meta["disc"] = fmt.Sprintf("%d", tags.Disc) + utils.Tern(tags.DiscCount > 0, fmt.Sprintf("/%d", tags.DiscCount), "") - } - if tags.Track > 0 { - meta["track"] = fmt.Sprintf("%d", tags.Track) + utils.Tern(tags.TrackCount > 0, fmt.Sprintf("/%d", tags.TrackCount), "") - } - - return meta -} - func TrimWithFade(in Probe, out string, start, stop, up, down float64) error { // -ss (start) -t (end) -af afade=t=in:st=(start):d=(up),afade=t=out:st=(downstart):d=(down) st := in.GetFirstAcceptableAudio() diff --git a/media/fingerprint.go b/media/fingerprint.go index 5952bad..2b4d1ad 100644 --- a/media/fingerprint.go +++ b/media/fingerprint.go @@ -12,7 +12,6 @@ import ( "codeberg.org/danjones000/strip-beats/config" "codeberg.org/danjones000/strip-beats/media/brainz" h "codeberg.org/danjones000/strip-beats/utils/http" - "github.com/google/uuid" ) type FPrint struct { @@ -46,7 +45,7 @@ type IdResults struct { } type IdResult struct { - Id uuid.UUID + Id string Score float64 Recordings []brainz.Recording } diff --git a/media/probe.go b/media/probe.go index b3b4f29..6419b93 100644 --- a/media/probe.go +++ b/media/probe.go @@ -4,7 +4,6 @@ import ( "encoding/json" "codeberg.org/danjones000/strip-beats/config" - "codeberg.org/danjones000/strip-beats/media/tags" "codeberg.org/danjones000/strip-beats/utils" "dario.cat/mergo" "github.com/akrennmair/slice" @@ -100,7 +99,7 @@ type Stream struct { StartTime float64 `json:"start_time,string"` Duration float64 `json:",string"` DurationTs int `json:"duration_ts"` - Tags tags.Tags + Tags Tags } func (st Stream) isWantedCodec() bool { @@ -125,10 +124,26 @@ type Format struct { Size int `json:",string"` BitRate int `json:"bit_rate,string"` Score int `json:"probe_score"` - Tags tags.Tags + Tags Tags } -func (pr Probe) FullTags() tags.Tags { +type Tags struct { + MajorBrand string `json:"major_brand"` + Title string + Artist string + AlbumArtist string `json:"album_artist"` + Album string + Date string + Encoder string + Comment string + Description string + Composer string + Genre string + Disc string + Track string +} + +func (pr Probe) FullTags() Tags { t := pr.Format.Tags s := pr.WantedAudioStream() if s != nil { diff --git a/media/tags/tags.go b/media/tags/tags.go deleted file mode 100644 index eeb13fd..0000000 --- a/media/tags/tags.go +++ /dev/null @@ -1,35 +0,0 @@ -package tags - -import ( - "github.com/google/uuid" -) - -type Tags struct { - Title string - Artist string - AlbumArtist string `json:"album_artist"` - Album string - Date string - Comment string - Description string - Synopsis string - Url string `json:"purl"` - AcoustidId uuid.UUID `json:"ACOUSTID_ID"` - MusicbrainzReleaseGroupId uuid.UUID `json:"MUSICBRAINZ_RELEASEGROUPID"` - MusicbrainzAlbumId uuid.UUID `json:"MUSICBRAINZ_ALBUMID"` - MusicbrainzAlbumArtistId uuid.UUID `json:"MUSICBRAINZ_ALBUMARTISTID"` - MusicbrainzRecordingId uuid.UUID - MusicBrainzLabelId uuid.UUID - ArtistSort string - AlbumArtistSort string - ReleaseCountry string - Label string - Composer string - Genre string - Disc int `json:"-"` - DiscCount int - Track int `json:"-"` - TrackCount int - TrackStr string `json:"track"` - DiscStr string `json:"disc"` -} diff --git a/utils/utils.go b/utils/utils.go index 17d76d5..1f40e98 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -29,17 +29,3 @@ func HourMinSecToSeconds(time string) (float64, error) { dur, _ := t.ParseDuration(f) return dur.Seconds(), nil } - -func Tern[V any](choice bool, one, two V) V { - if choice { - return one - } - return two -} - -func TernCall[V any](choice bool, one, two func() V) V { - if choice { - return one() - } - return two() -} diff --git a/utils/utils_tern_test.go b/utils/utils_tern_test.go deleted file mode 100644 index 5a9280c..0000000 --- a/utils/utils_tern_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package utils - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestTern(t *testing.T) { - assert.Equal(t, Tern(true, 5, 2), 5) - assert.Equal(t, Tern(false, 5, 2), 2) -} - -func TestTernCall(t *testing.T) { - five := func() int { - return 5 - } - two := func() int { - return 2 - } - assert.Equal(t, TernCall(true, five, two), 5) - assert.Equal(t, TernCall(false, five, two), 2) -}