85 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			85 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package media | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"encoding/json" | ||
|  | 	"errors" | ||
|  | 	"fmt" | ||
|  | 	"io" | ||
|  | 	"net/http" | ||
|  | 	u "net/url" | ||
|  | 	"os/exec" | ||
|  | 	"strings" | ||
|  | 
 | ||
|  | 	"codeberg.org/danjones000/strip-beats/config" | ||
|  | ) | ||
|  | 
 | ||
|  | type FPrint struct { | ||
|  | 	Duration    float64 | ||
|  | 	Fingerprint string | ||
|  | } | ||
|  | 
 | ||
|  | func Fingerprint(path string) (FPrint, error) { | ||
|  | 	pr := FPrint{} | ||
|  | 	_, err := exec.LookPath("fpcalc") | ||
|  | 	if err != nil { | ||
|  | 		return pr, errors.Join(errors.New("Unable to find fpcalc in PATH"), err) | ||
|  | 	} | ||
|  | 	cmd := exec.Command("fpcalc", "-json", path) | ||
|  | 	out, err := cmd.Output() | ||
|  | 	if err != nil { | ||
|  | 		return pr, errors.Join(errors.New(fmt.Sprintf("Failed to run %s", strings.Join(cmd.Args, " "))), err) | ||
|  | 	} | ||
|  | 	err = json.Unmarshal(out, &pr) | ||
|  | 	if err != nil { | ||
|  | 		return pr, errors.Join(errors.New("Couldn't parse output from fpcalc"), err) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return pr, nil | ||
|  | } | ||
|  | 
 | ||
|  | type IdResults struct { | ||
|  | 	Status  string | ||
|  | 	Results []IdResult | ||
|  | 	Error   IdError | ||
|  | } | ||
|  | 
 | ||
|  | type IdResult struct { | ||
|  | 	Id         string | ||
|  | 	Score      float64 | ||
|  | 	Recordings []MbRecording | ||
|  | } | ||
|  | 
 | ||
|  | type IdError struct { | ||
|  | 	Code    int | ||
|  | 	Message string | ||
|  | } | ||
|  | 
 | ||
|  | func LookupFingerprint(print FPrint) (IdResults, error) { | ||
|  | 	res := IdResults{} | ||
|  | 	key := config.GetConfig().AcousticIdKey | ||
|  | 	if key == "" { | ||
|  | 		return res, errors.New("Missing acoustic_id_key from config") | ||
|  | 	} | ||
|  | 	url := "https://api.acoustid.org/v2/lookup" | ||
|  | 	form := u.Values{ | ||
|  | 		"format":      {"json"}, | ||
|  | 		"client":      {key}, | ||
|  | 		"duration":    {fmt.Sprintf("%.0f", print.Duration)}, | ||
|  | 		"fingerprint": {print.Fingerprint}, | ||
|  | 		"meta":        {"recordingids"}} | ||
|  | 	resp, err := http.PostForm(url, form) | ||
|  | 	if err != nil { | ||
|  | 		return res, err | ||
|  | 	} | ||
|  | 	defer resp.Body.Close() | ||
|  | 	body, err := io.ReadAll(resp.Body) | ||
|  | 	if err != nil { | ||
|  | 		return res, err | ||
|  | 	} | ||
|  | 	json.Unmarshal(body, &res) | ||
|  | 	if res.Status == "error" { | ||
|  | 		err = errors.New(res.Error.Message) | ||
|  | 	} | ||
|  | 	return res, err | ||
|  | } |