Skip to content

Commit

Permalink
Use github.com/dhowden/tag as backup tag parser
Browse files Browse the repository at this point in the history
Taglib appears to be unable to parse Vorbis tags in OGG files. And there
are places where it will be useful, even in my own collection.
Unfortunately github.com/dhowden/tag does not support getting media
duration and bitrate.
  • Loading branch information
ironsmile committed Oct 27, 2024
1 parent f7453f8 commit 3c4f4bb
Show file tree
Hide file tree
Showing 23 changed files with 3,202 additions and 11 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/ironsmile/euterpe
go 1.21

require (
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8
github.com/gbrlsnchs/jwt/v3 v3.0.1
github.com/gorilla/mux v1.6.2
github.com/howeyc/fsnotify v0.9.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8 h1:OtSeLS5y0Uy01jaKK4mA/WVIYtpzVm63vLVAPzJXigg=
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8/go.mod h1:apkPC/CR3s48O2D7Y++n1XWEpgPNNCjXYga3PPbJe2E=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gbrlsnchs/jwt/v3 v3.0.1 h1:lbUmgAKpxnClrKloyIwpxm4OuWeDl5wLk52G91ODPw4=
github.com/gbrlsnchs/jwt/v3 v3.0.1/go.mod h1:AncDcjXz18xetI3A6STfXq2w+LuTx8pQ8bGEwRN8zVM=
Expand Down
13 changes: 8 additions & 5 deletions src/library/local_library.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"time"

"github.com/howeyc/fsnotify"
taglib "github.com/wtolson/go-taglib"

// Blind import is the way a SQL driver is imported. This is the proposed way
// from the golang documentation.
Expand Down Expand Up @@ -867,11 +866,10 @@ func (lib *LocalLibrary) AddMedia(filename string) error {
return err
}

file, err := taglib.Read(filename)
file, err := parseFileTags(filename)
if err != nil {
return fmt.Errorf("Taglib error for %s: %s", filename, err.Error())
return fmt.Errorf("parsing tags error for %s: %s", filename, err.Error())
}
defer file.Close()

fi := fileInfo{
FilePath: filename,
Expand Down Expand Up @@ -1348,13 +1346,18 @@ func (lib *LocalLibrary) setTrackID(
yearArg = sql.Named("year", nil)
}

durationArg := sql.Named("duration", duration)
if duration == 0 {
durationArg = sql.Named("duration", nil)
}

res, err := stmt.Exec(
sql.Named("title", title),
sql.Named("albumID", albumID),
sql.Named("artistID", artistID),
sql.Named("fsPath", fsPath),
sql.Named("trackNumber", trackNumber),
sql.Named("duration", duration),
durationArg,
yearArg,
sql.Named("size", size),
bitrateArg,
Expand Down
7 changes: 2 additions & 5 deletions src/library/local_library_scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"os"
"path/filepath"
"time"

taglib "github.com/wtolson/go-taglib"
)

// Scan scans all of the folders in paths for media files. New files will be added to the
Expand Down Expand Up @@ -135,9 +133,9 @@ func (lib *LocalLibrary) Rescan(ctx context.Context) error {
continue
}

file, err := taglib.Read(fileName)
file, err := parseFileTags(fileName)
if err != nil {
log.Printf("Taglib error for %s: %s\n", fileName, err)
log.Printf("Parsing tags error for %s: %s\n", fileName, err)
continue
}

Expand All @@ -149,7 +147,6 @@ func (lib *LocalLibrary) Rescan(ctx context.Context) error {
if err := lib.insertMediaIntoDatabase(file, fi); err != nil {
log.Printf("failed updating file %s: %s\n", fileName, err)
}
file.Close()
}
}

Expand Down
83 changes: 82 additions & 1 deletion src/library/media_file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package library

import "time"
import (
"fmt"
"os"
"time"

"github.com/dhowden/tag"
taglib "github.com/wtolson/go-taglib"
)

// MediaFile is an interface which a media object should satisfy in order to be inserted
// in the library database.
Expand All @@ -27,3 +34,77 @@ type MediaFile interface {
// Returns the bitrate of the file in kb/s.
Bitrate() int
}

// parseFileTags reads a file and returns its metadata tags as a MediaFile object.
func parseFileTags(fileName string) (MediaFile, error) {
file, tglErr := taglib.Read(fileName)
if tglErr == nil {
defer file.Close()
return medaFileFromTaglib(file), nil
}

mf, tagErr := mediaFileFromTag(fileName)
if tagErr != nil {
return nil, fmt.Errorf(
"failed to parse file with both tagging libs: (tag: %s, taglib: %w)",
tagErr, tglErr,
)
}

return mf, nil
}

type mediaFile struct {
artist string
album string
title string
track int
length time.Duration
year int
bitrate int
}

func (f *mediaFile) Artist() string { return f.artist }
func (f *mediaFile) Album() string { return f.album }
func (f *mediaFile) Title() string { return f.title }
func (f *mediaFile) Track() int { return f.track }
func (f *mediaFile) Length() time.Duration { return f.length }
func (f *mediaFile) Year() int { return f.year }
func (f *mediaFile) Bitrate() int { return f.bitrate }

// medaFileFromTaglib returns a MediaFile from a taglib parsed file.
func medaFileFromTaglib(file *taglib.File) MediaFile {
return &mediaFile{
artist: file.Artist(),
album: file.Album(),
title: file.Title(),
track: file.Track(),
length: file.Length(),
year: file.Year(),
bitrate: file.Bitrate(),
}
}

func mediaFileFromTag(fileName string) (MediaFile, error) {
fh, err := os.Open(fileName)
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}
defer fh.Close()

md, err := tag.ReadFrom(fh)
if err != nil {
return nil, fmt.Errorf("parsing tags: %w", err)
}

track, _ := md.Track()
file := &mediaFile{
artist: md.Artist(),
album: md.Album(),
title: md.Title(),
track: track,
year: md.Year(),
}

return file, nil
}
19 changes: 19 additions & 0 deletions vendor/github.com/dhowden/tag/.editorconfig

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vendor/github.com/dhowden/tag/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions vendor/github.com/dhowden/tag/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 71 additions & 0 deletions vendor/github.com/dhowden/tag/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3c4f4bb

Please # to comment.