Saya ingin membuat sidik jari akustik dari file FLAC atau MP3 menggunakan pustaka chromaprint di Go. Saya telah bermain-main dengan dua perpustakaan Go berikut:

Dengan menggunakan kode berikut, sidik jari dari "aliran data audio mentah" dapat dibuat (dengan reader bertipe io.Reader):

fpcalc := gochroma.New(gochroma.AlgorithmDefault)
defer fpcalc.Close()

fprint, err := fpcalc.Fingerprint(
        fingerprint.RawInfo{
                Src:        reader,
                Channels:   2,
                Rate:       44100,  
                MaxSeconds: 120,
        }       
)

Sayangnya, saya belum dapat memahami apa arti sebenarnya dari "aliran data audio mentah" (tebakan saya: aliran WAVE LPCM), tetapi saya mengerti bahwa saya tidak dapat begitu saja membuka file FLAC atau MP3 menggunakan os.Open dan meneruskan aliran ke fingerprint.RawInfo.Src. Ada beberapa contoh, tetapi ini berfungsi dengan file yang diakhiri dengan .raw.

Bagaimana cara mengonversi file/streaming FLAC (atau, sekunder, MP3) ke stream data audio mentah di Go? Dugaan saya adalah menggunakan perpustakaan Go FLAC seperti go-flac, tapi saya tidak yakin harus mulai dari mana. Setiap petunjuk dipersilakan!

EDIT

Melalui go-flac GetStreamInfo itu harus dimungkinkan untuk mengakses data audio mentah file FLAC, yang kemudian dapat diteruskan ke fingerprint.RawInfo.Src menggunakan pembaca (saya sangat tidak menyukai fakta bahwa go-flac GetStreamInfo tidak mengembalikan io.Reader; melainkan mengembalikan []byte , sehingga seluruh aliran dimuat ke dalam memori sebelum pemrosesan lebih lanjut dapat benar-benar terjadi).

Menggunakan kode berikut, sidik jari file FLAC dapat dihitung (pada dasarnya apa yang fpcalc lakukan):

package main

import (
    "bytes"
    "fmt"
    "os"

    "github.com/go-fingerprint/fingerprint"
    "github.com/go-fingerprint/gochroma"
    "github.com/go-flac/go-flac"
)

func main() {
    f, err := flac.ParseFile(os.Args[1])
    if err != nil {
        panic(err)
    }

    si, err := f.GetStreamInfo()
    if err != nil {
        panic(err)
    }

    fpcalc := gochroma.New(gochroma.AlgorithmDefault)
    defer fpcalc.Close()

    fprint, err := fpcalc.Fingerprint(
        fingerprint.RawInfo{
            Src:        bytes.NewReader(f.Frames),
            Channels:   uint(si.ChannelCount),
            Rate:       uint(si.SampleRate),
            MaxSeconds: 120,
        },
    )

    fmt.Println(fprint)
}

Sayangnya, kode di atas tidak mengembalikan sidik jari yang sama seperti fpcalc. Apa yang saya lakukan salah?

0
watain 6 Mei 2021, 14:31

1 menjawab

Jawaban Terbaik

Saya berakhir dengan kode berikut yang menerjemahkan file FLAC ke data audio mentah menggunakan github.com/eaburns/flac (seperti yang ditunjukkan Steven Penny) dan kemudian meneruskan data ke sidik jari/gochroma.

Sidik jari yang dihasilkan tampaknya tidak sama dengan yang dilaporkan oleh fpcalc untuk file FLAC yang sama, tetapi ketika menanyakan database AcoustID menggunakan sidik jari yang dihasilkan, hasilnya benar.

package main

import (
    "bytes"
    "fmt"
    "log"
    "os"

    "github.com/eaburns/flac"
    "github.com/go-fingerprint/fingerprint"
    "github.com/go-fingerprint/gochroma"
)

func main() {
    if len(os.Args) != 2 {
        log.Fatalf("usage: go run fpcalc.go FILE")
    }

    f, err := os.Open(os.Args[1])
    if err != nil {
        log.Fatalf("os.Open(%s): %s", os.Args[1], err)
    }

    defer f.Close()

    d, metadata, err := flac.Decode(f)
    if err != nil {
        log.Fatalf("flac.Decode: %s", err)
    }

    fpcalc := gochroma.New(gochroma.AlgorithmDefault)
    defer fpcalc.Close()

    fprint, err := fpcalc.Fingerprint(
        fingerprint.RawInfo{
            Src:        bytes.NewBuffer(d),
            Channels:   uint(metadata.NChannels),
            Rate:       uint(metadata.SampleRate),
            MaxSeconds: 120,
        },
    )
    if err != nil {
        log.Fatalf("fpcalc.Fingerprint: %s", err)
    }

    fmt.Println(fprint)
}
0
watain 12 Mei 2021, 11:38