微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

FLAC 和 MP3 的色谱指纹

如何解决FLAC 和 MP3 的色谱指纹

我想使用 Go 中的 chromaprint 库创建 FLAC 或 MP3 文件的声学指纹。我一直在使用以下两个 Go 库:

使用以下代码,可以创建“原始音频数据流”的指纹(其中 reader 的类型为 io.Reader):

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

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

不幸的是,我一直无法弄清楚“原始音频数据流”的确切含义(我的猜测:WAVE LPCM 流),但我知道我不能简单地使用 {{ 打开 FLAC 或 MP3 文件1}} 并将流传递给 os.Open。有一些 examples,但这些适用于以 fingerprint.RawInfo.Src 结尾的文件

如何在 Go 中将 FLAC(或辅助 MP3)文件/流转换为原始音频数据流?我的猜测是使用像 go-flac 这样的 Go FLAC 库,但我不确定从哪里开始。欢迎任何提示

编辑

通过 go-flac.raw 应该可以访问 FLAC 文件的原始音频数据,然后可以使用阅读器将其传递给 GetStreamInfo(我真的不喜欢这样的事实go-flacfingerprint.RawInfo.Src 不返回 GetStreamInfo;而是返回 io.Reader,因此在实际进行进一步处理之前,整个流已加载到内存中)。>

使用以下代码,可以计算 FLAC 文件的指纹(基本上就是 []byte 所做的):

fpcalc

不幸的是,上面的代码没有返回与 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),},) fmt.Println(fprint) } 相同的指纹。我做错了什么?

解决方法

我最终得到了以下代码,它使用 github.com/eaburns/flac(正如 Steven Penny 指出的)将 FLAC 文件解码为原始音频数据,然后将数据传递给 fingerprint/gochroma .

生成的指纹似乎与fpcalc针对同一个FLAC文件报告的指纹不一样,但是使用生成的指纹查询AcoustID数据库时,结果是正确的。

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)
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。