Get tags from mb

This commit is contained in:
Dan Jones 2023-11-11 17:01:01 -06:00
commit 5881f3d538
5 changed files with 190 additions and 32 deletions

View file

@ -2,17 +2,19 @@ package app
import (
"fmt"
"strconv"
"codeberg.org/danjones000/strip-beats/input/boolean"
"codeberg.org/danjones000/strip-beats/input/list"
"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
num int
r rune
score float64
}
func (o recOpt) Title() string {
@ -21,7 +23,8 @@ func (o recOpt) Title() string {
func (o recOpt) Text() string {
return fmt.Sprintf(
"By %s - First Released %s - %s %s",
"(Score %.2f) By %s - First Released %s - %s %s",
100*o.score,
o.rec.FirstArtist().Name,
o.rec.FirstReleaseDate,
o.rec.FirstGenre().Name,
@ -29,11 +32,7 @@ func (o recOpt) Text() string {
}
func (o recOpt) Rune() rune {
s := strconv.Itoa(o.num)
for _, c := range s {
return c
}
return 0
return o.r
}
func (o recOpt) Selected() func() {
@ -57,27 +56,123 @@ func print() {
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
fmt.Printf("%+v\n", tags)
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 {
var recs []list.Option
var rec brainz.Recording
var err error
i := 1
i := 'a'
for _, res := range ids.Results {
for _, rec = range res.Recordings {
err = brainz.FillRecording(&rec)
if err != nil {
panic(err)
}
recs = append(recs, recOpt{rec, i})
i = (i + 1) % 10
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 = slice.Filter(recs, func(opt list.Option) bool {
return opt.Title() != ""
})
return list.List("Which recording is the correct one?", recs, nil).(recOpt).rec
}
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
}

View file

@ -52,14 +52,16 @@ 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/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")
print()
quit()
}
func Run(step AppStep) {
testPrint()
for step < Quit {
switch step {
case Pick:

View file

@ -12,6 +12,7 @@ import (
type Recording struct {
Id uuid.UUID
AcousticId uuid.UUID
Isrcs []string
FirstReleaseDate string `json:"first-release-date"`
Length int
@ -67,20 +68,56 @@ 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"`
// 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
}
type Artist struct {
@ -95,6 +132,7 @@ 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"`
@ -109,6 +147,25 @@ 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}

View file

@ -12,6 +12,7 @@ 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 {
@ -45,7 +46,7 @@ type IdResults struct {
}
type IdResult struct {
Id string
Id uuid.UUID
Score float64
Recordings []brainz.Recording
}

View file

@ -5,13 +5,11 @@ import (
)
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
Synopsis string
@ -21,12 +19,17 @@ type Tags struct {
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
ReleaseType string
Composer string
Genre string
Disc string
Track string
Disc int `json:"-"`
DiscCount int
Track int `json:"-"`
TrackCount int
TrackStr string `json:"track"`
DiscStr string `json:"disc"`
}