Explorar o código

feat: function to read vorbis info

Fela Maslen %!s(int64=5) %!d(string=hai) anos
pai
achega
6bd430be5e

+ 5 - 2
music-player/Makefile

@@ -1,8 +1,11 @@
 build:
-	go build -o bin/music-player-scan ./cmd/scan
+	go build -o bin/scan ./cmd/scan
 
 clean:
 	mkdir -p bin && rm -rf ./bin/*
 
-run-scan:
+test.read:
+	go test -v ./pkg/read
+
+run.scan:
 	go run ./cmd/scan

+ 23 - 0
music-player/README.md

@@ -0,0 +1,23 @@
+# music-scanner
+
+This is the backend part of the music player, written in Golang.
+
+## Building
+
+Run `make build` inside this directory. Binaries will be built and output to the `bin` directory (which will be created if it does not exist).
+
+## Testing
+
+Run the following commands to run unit tests:
+
+- `make test.read`: tests the file reader module
+
+## Components
+
+### Music scanner
+
+This is intended to be run as a scheduled job. It will scan a directory and add relevant metadata to a PostgreSQL database.
+
+**Usage**
+
+`bin/scan`

+ 6 - 0
music-player/go.mod

@@ -1,3 +1,9 @@
 module github.com/felamaslen/go-music-player
 
 go 1.15
+
+require (
+	github.com/anyhon/engine v0.1.0
+	github.com/dhowden/tag v0.0.0-20200828214007-46e57f75dbfc
+	github.com/stretchr/testify v1.6.1
+)

+ 15 - 0
music-player/go.sum

@@ -0,0 +1,15 @@
+github.com/anyhon/engine v0.1.0 h1:z8LToJ0A7O3om+Iz+FfFDTqzmBYiIMBhGyFNvySq5NI=
+github.com/anyhon/engine v0.1.0/go.mod h1:1sir2IWytku5IeTl8s92+MJygKx5Y5IQhEq/+PX8RC0=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dhowden/tag v0.0.0-20200828214007-46e57f75dbfc h1:8ndBJ8cTZwp5Qtl5fnG5bM/ekMnm1GFdUSMTGiN09K0=
+github.com/dhowden/tag v0.0.0-20200828214007-46e57f75dbfc/go.mod h1:SniNVYuaD1jmdEEvi+7ywb1QFR7agjeTdGKyFb0p7Rw=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 22 - 0
music-player/pkg/read/duration/vorbis.go

@@ -0,0 +1,22 @@
+package duration
+
+import (
+  "fmt"
+  ov "github.com/anyhon/engine/audio/ov"
+)
+
+func GetSongDurationVorbis(fileName string) (duration int, ok bool) {
+  ovFile, ovErr := ov.Fopen(fileName)
+  if ovErr != nil {
+    fmt.Printf("Error opening file for ogg vorbis duration: %s\n", ovErr)
+    return 0, false
+  }
+
+  result, errTimeTotal := ov.TimeTotal(ovFile, -1)
+  if errTimeTotal != nil {
+    fmt.Printf("Error calling TimeTotal for ogg vorbis file: %s\n", errTimeTotal)
+    return 0, false
+  }
+
+  return int(result), true
+}

+ 1 - 0
music-player/pkg/read/main.go

@@ -0,0 +1 @@
+package read

+ 46 - 0
music-player/pkg/read/read_files.go

@@ -0,0 +1,46 @@
+package read
+
+import (
+  "os"
+
+  tag "github.com/dhowden/tag"
+
+  duration "github.com/felamaslen/go-music-player/pkg/read/duration"
+)
+
+type Song struct {
+  title, artist, album string
+  length int
+}
+
+func getSongDuration(file *os.File, tags tag.Metadata) int {
+  switch tags.Format() {
+  case "VORBIS":
+    result, _ := duration.GetSongDurationVorbis(file.Name())
+    return result
+  default:
+    return 0
+  }
+}
+
+func ReadFile(fileName string) (song *Song, err error) {
+  file, errFile := os.Open(fileName)
+  if errFile != nil {
+    return &Song{}, errFile
+  }
+  defer file.Close()
+
+  tags, errTags := tag.ReadFrom(file)
+  if errTags != nil {
+    return &Song{}, errTags
+  }
+
+  result := Song{
+    title: tags.Title(),
+    artist: tags.Artist(),
+    album: tags.Album(),
+    length: getSongDuration(file, tags),
+  }
+
+  return &result, nil
+}

+ 24 - 0
music-player/pkg/read/read_files_test.go

@@ -0,0 +1,24 @@
+package read
+
+import (
+  "testing"
+  "github.com/stretchr/testify/assert"
+)
+
+const testFile = "testdata/file_example_OOG_1MG.ogg"
+
+const testTitle = "Impact Moderato"
+const testArtist = "Kevin MacLeod"
+const testAlbum = "YouTube Audio Library"
+const testLengthSeconds = 74
+
+func TestReadFile(t *testing.T) {
+  result, err := ReadFile(testFile)
+
+  assert.Nil(t, err)
+
+  assert.Equal(t, result.title, testTitle, "title must be correct")
+  assert.Equal(t, result.artist, testArtist, "artist must be correct")
+  assert.Equal(t, result.album, testAlbum, "album must be correct")
+  assert.Equal(t, result.length, testLengthSeconds, "length must be correct")
+}

BIN=BIN
music-player/pkg/read/testdata/file_example_OOG_1MG.ogg