start looking at cover.jpg, handle more errors gracefully, reorganize code

This commit is contained in:
Octopus Octopus 2024-03-18 04:47:00 -05:00
parent 31d2dbebec
commit f8c4cc4591
2 changed files with 162 additions and 31 deletions

BIN
cmus2obs

Binary file not shown.

193
main.go
View File

@ -7,6 +7,7 @@ import (
"image" "image"
"log" "log"
"os" "os"
"path/filepath"
"strings" "strings"
"time" "time"
@ -34,12 +35,12 @@ func main() {
o, _ := c.Output() o, _ := c.Output()
remoteResp := strings.Split(string(o), "\n") remoteResp := strings.Split(string(o), "\n")
filepath, err := getAttribute(remoteResp, "file ") path, err := getAttribute(remoteResp, "file ")
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Fatalln(err.Error())
} }
if filepath != prevFilepath { if path != prevFilepath {
//Album //Album
album, err := getAttribute(remoteResp, "tag album ") album, err := getAttribute(remoteResp, "tag album ")
if err != nil { if err != nil {
@ -58,31 +59,50 @@ func main() {
// Image // Image
img := make([]byte, 0) img := make([]byte, 0)
if strings.HasSuffix(filepath, ".flac") {
img, err = getFlacArt(filepath) switch {
case hasFlacTrackArt(path):
img, err = getFlacArt(path)
if err != nil { if err != nil {
img = defaultArt() img, err = getCoverJpg(path)
if err != nil {
log.Println(err.Error())
img = getDefaultArt()
}
} }
} else if strings.HasSuffix(filepath, ".mp3") { case hasMp3TrackArt(path):
img, err = getMP3Art(filepath) img, err = getMP3Art(path)
if err != nil { if err != nil {
img = defaultArt() img, err = getCoverJpg(path)
if err != nil {
log.Println(err.Error())
img = getDefaultArt()
}
} }
} else { case hasCoverJpg(path):
img = defaultArt() img, err = getCoverJpg(path)
if err != nil {
log.Println(err.Error())
img = getDefaultArt()
}
default:
img = getDefaultArt()
} }
imgBuff := bytes.NewBuffer(img) imgBuff := bytes.NewBuffer(img)
imgOrig, _, err := image.Decode(imgBuff) imgOrig, _, err := image.Decode(imgBuff)
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Panic(err.Error())
} }
imgOut := image.NewRGBA(image.Rect(0, 0, IMAGE_SIZE, IMAGE_SIZE)) imgOut := image.NewRGBA(image.Rect(0, 0, IMAGE_SIZE, IMAGE_SIZE))
draw.BiLinear.Scale(imgOut, imgOut.Rect, imgOrig, imgOrig.Bounds(), draw.Over, nil) draw.BiLinear.Scale(imgOut, imgOut.Rect, imgOrig, imgOrig.Bounds(), draw.Over, nil)
jpeg.Encode(imgBuff, imgOut, nil) err = jpeg.Encode(imgBuff, imgOut, nil)
if err != nil {
log.Panic(err.Error())
}
writeTxt("SongAlbum", album) writeTxt("SongAlbum", album)
writeTxt("SongArtist", artist) writeTxt("SongArtist", artist)
@ -90,11 +110,87 @@ func main() {
writeJpg("AlbumArt", img) writeJpg("AlbumArt", img)
} }
prevFilepath = filepath prevFilepath = path
time.Sleep(TIMER * time.Second) time.Sleep(TIMER * time.Second)
} }
} }
// has
func hasFlacTrackArt(s string) bool {
// dumb check
if !strings.HasSuffix(s, ".flac") {
return false
}
// is parsable
f, err := flac.ParseFile(s)
if err != nil {
return false
}
// has any frames
if len(f.Meta) == 0 {
return false
}
// has any pictures
for _, metadata := range f.Meta {
if metadata.Type == flac.Picture {
return true
}
}
// no pictures
return false
}
func hasMp3TrackArt(s string) bool {
// dumb check
if !strings.HasSuffix(s, ".mp3") {
return false
}
// is parsable
m, err := id3v2.Open(s, id3v2.Options{Parse: true})
if err != nil {
return false
}
defer m.Close()
// has a picture
pic := m.GetFrames(m.CommonID("Attached picture"))
if pic != nil {
return true
}
// no pictures
return false
}
func hasCoverJpg(s string) bool {
exts := []string{".jpg", ".jpeg", ".png", ".gif"} // 'hasCoverJpg' is a misnomer, check all sane image types
dir := filepath.Dir(s)
file, err := os.Open(dir)
if err != nil {
log.Printf("can't open %v; %v\n", dir, err.Error())
return false
}
defer file.Close()
indexes, _ := file.ReadDir(0)
for i := range indexes {
for _, key := range exts {
if "cover"+key == indexes[i].Name() {
return true
}
}
}
return false
}
// get
func getFlacArt(s string) ([]byte, error) { func getFlacArt(s string) ([]byte, error) {
f, err := flac.ParseFile(s) f, err := flac.ParseFile(s)
if err != nil { if err != nil {
@ -102,6 +198,7 @@ func getFlacArt(s string) ([]byte, error) {
} }
for _, metadata := range f.Meta { for _, metadata := range f.Meta {
if metadata.Type == flac.Picture { if metadata.Type == flac.Picture {
// do not care if it has multiple pictures, pick the first one.
pic, err := flacpicture.ParseFromMetaDataBlock(*metadata) pic, err := flacpicture.ParseFromMetaDataBlock(*metadata)
return pic.ImageData, err return pic.ImageData, err
} }
@ -117,12 +214,44 @@ func getMP3Art(s string) ([]byte, error) {
defer tags.Close() defer tags.Close()
pic := tags.GetFrames(tags.CommonID("Attached picture")) pic := tags.GetFrames(tags.CommonID("Attached picture"))
if pic != nil { if pic != nil {
return pic[0].(id3v2.PictureFrame).Picture, nil //i literally do not care if it has multiple pictures, pick the first one. // do not care if it has multiple pictures, pick the first one.
return pic[0].(id3v2.PictureFrame).Picture, nil
} }
return nil, errors.New("no image found") return nil, errors.New("no image found")
} }
func defaultArt() []byte { func getCoverJpg(s string) ([]byte, error) {
exts := []string{".jpg", ".jpeg", ".png", ".gif"}
dir := filepath.Dir(s)
file, err := os.Open(dir)
if err != nil {
return nil, fmt.Errorf("can't open %v; %v", dir, err.Error())
}
defer file.Close()
indexes, _ := file.ReadDir(0)
for i := range indexes {
for _, key := range exts {
if "cover"+key == indexes[i].Name() {
cover, err := os.Open(dir + "/" + indexes[i].Name())
if err != nil {
return nil, fmt.Errorf("can't open %v", indexes[i].Name())
}
defer cover.Close()
info, err := indexes[i].Info()
if err != nil {
return nil, fmt.Errorf("cant stat %v; %v", indexes[i].Name(), err.Error())
}
art := make([]byte, info.Size())
cover.Read(art)
return art, nil
}
}
}
return nil, errors.New("cover not found")
}
func getDefaultArt() []byte {
file, err := os.Open("default.jpg") file, err := os.Open("default.jpg")
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Fatal(err.Error())
@ -138,6 +267,23 @@ func defaultArt() []byte {
return art return art
} }
func getAttribute(input []string, prefix string) (string, error) {
var attr string
for i := range input {
has := strings.HasPrefix(input[i], prefix)
if has {
attr = input[i]
}
}
attr, b := strings.CutPrefix(attr, prefix)
if !b {
return "", fmt.Errorf("did not find prefix \"%v\"", prefix)
}
return attr, nil
}
// write
func writeJpg(filename string, input []byte) { func writeJpg(filename string, input []byte) {
os.Mkdir("output", 0755) os.Mkdir("output", 0755)
f, err := os.Create("./output/" + filename + ".jpg") f, err := os.Create("./output/" + filename + ".jpg")
@ -159,18 +305,3 @@ func writeTxt(filename, input string) {
f.Write([]byte(input)) f.Write([]byte(input))
} }
func getAttribute(input []string, prefix string) (string, error) {
var attr string
for i := range input {
has := strings.HasPrefix(input[i], prefix)
if has {
attr = input[i]
}
}
attr, b := strings.CutPrefix(attr, prefix)
if !b {
return "", fmt.Errorf("did not find prefix \"%v\"", prefix)
}
return attr, nil
}