electricboogaloo/parse.go

164 lines
3.2 KiB
Go

package main
import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"github.com/bogem/id3v2/v2"
"github.com/go-flac/flacpicture"
"github.com/go-flac/go-flac"
)
// 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 hasCoverArtFile(s string) bool {
exts := []string{".jpg", ".jpeg", ".png", ".gif"} // 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) {
f, err := flac.ParseFile(s)
if err != nil {
return nil, fmt.Errorf("can't open file")
}
for _, metadata := range f.Meta {
if metadata.Type == flac.Picture {
// do not care if it has multiple pictures, pick the first one.
pic, err := flacpicture.ParseFromMetaDataBlock(*metadata)
return pic.ImageData, err
}
}
return nil, fmt.Errorf("no image found")
}
func getMP3Art(s string) ([]byte, error) {
tags, err := id3v2.Open(s, id3v2.Options{Parse: true})
if err != nil {
return nil, fmt.Errorf("can't open mp3 tags")
}
defer tags.Close()
pic := tags.GetFrames(tags.CommonID("Attached picture"))
if pic != nil {
// do not care if it has multiple pictures, pick the first one.
return pic[0].(id3v2.PictureFrame).Picture, nil
}
return nil, fmt.Errorf("no image found")
}
func getCoverArtFile(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()
if err != nil {
return nil, fmt.Errorf("cant stat %v; %v", indexes[i].Name(), err.Error())
}
return io.ReadAll(cover)
}
}
}
return nil, fmt.Errorf("cover not found")
}
func getDefaultArt() ([]byte, error) {
file, err := os.Open("default.jpg")
if err != nil {
return []byte{}, err
}
defer file.Close()
info, err := file.Stat()
if err != nil {
return []byte{}, err
}
art := make([]byte, info.Size())
file.Read(art)
return art, err
}