Documentation
¶
Overview ¶
Package ncmrecognize recognizes songs through NetEase Cloud Music's audio-match API. It is a pure-Go reimplementation of the browser plugin's afp.wasm fingerprint algorithm: no cgo, no WebAssembly runtime, no Node.js.
Index ¶
- Constants
- func Fingerprint(ctx context.Context, pcm []float32, sampleRate int, offsetSec float64) (string, error)
- type Audio
- type Client
- func (c *Client) Match(ctx context.Context, fingerprint string) (*Response, error)
- func (c *Client) MatchDuration(ctx context.Context, fingerprint string, duration int) (*Response, error)
- func (c *Client) Recognize(ctx context.Context, audio []byte) (*Response, error)
- func (c *Client) RecognizeAdaptive(ctx context.Context, pcm []float32, sampleRate int, offsetSec, seconds float64) (*Response, error)
- func (c *Client) RecognizeFile(ctx context.Context, path string) (*Response, error)
- func (c *Client) RecognizeFileAdaptive(ctx context.Context, path string, seconds float64) (*Response, error)
- func (c *Client) RecognizeFileAdaptiveAt(ctx context.Context, path string, offsetSec, seconds float64) (*Response, error)
- func (c *Client) RecognizePCM(ctx context.Context, pcm []float32, sampleRate int, offsetSec float64) (*Response, error)
- type Engine
- func (e *Engine) Close(ctx context.Context) error
- func (e *Engine) ExtractQueryFP(ctx context.Context, pcm []float32) ([]byte, error)
- func (e *Engine) Fingerprint(ctx context.Context, pcm []float32, sampleRate int, offsetSec float64) (string, error)
- func (e *Engine) FingerprintAdaptive(ctx context.Context, pcm []float32, sampleRate int, offsetSec, seconds float64) (string, FingerprintInfo, error)
- type FingerprintInfo
- type Response
Constants ¶
const ( // AdaptiveKeep means all requested audio was used unchanged. AdaptiveKeep = "keep" // AdaptivePad means the window was extended to a longer usable length. // If the source ends before that length, the remainder is silence. AdaptivePad = "pad" // AdaptiveTruncate means the tail was dropped to reach a usable length. AdaptiveTruncate = "truncate" )
const ( // FingerprintRate is the sample rate expected by the fingerprint algorithm. FingerprintRate = 8000 // FingerprintSeconds is the clip length used by the NetEase web client. FingerprintSeconds = 6 )
Variables ¶
This section is empty.
Functions ¶
func Fingerprint ¶
func Fingerprint(ctx context.Context, pcm []float32, sampleRate int, offsetSec float64) (string, error)
Fingerprint returns the base64 fingerprint ("rawdata") for the given mono PCM samples, starting offsetSec seconds in. It takes FingerprintSeconds seconds of audio, resampled to 8 kHz like the web client: 48 kHz input is point-sampled every 6th sample; other rates use linear interpolation.
Types ¶
type Audio ¶
Audio is decoded audio: the first channel as float32 in [-1, 1].
type Client ¶
type Client struct {
HTTP *http.Client // defaults to http.DefaultClient
Engine *Engine // defaults to a shared engine
// Duration is the requested clip length in seconds used by Recognize,
// RecognizeFile and RecognizePCM. Zero (the default) means "all available
// audio", adapted to the endpoint's supported lengths (2-16 s). Set it to
// 6 for a 6-second window (clamped to the available audio), or to any
// other value for a custom length.
Duration float64
// Offset is the start offset in seconds used by Recognize and
// RecognizeFile. RecognizePCM takes its offset as an argument.
Offset float64
}
Client calls the NetEase audio match API.
func (*Client) MatchDuration ¶
func (c *Client) MatchDuration(ctx context.Context, fingerprint string, duration int) (*Response, error)
MatchDuration sends an already computed fingerprint with an explicit "duration" form value. Use FingerprintAdaptive to obtain a compatible duration for clips that are not 6 seconds long.
func (*Client) Recognize ¶
Recognize fingerprints the audio (wav/mp3/flac/ogg bytes) and queries the API.
func (*Client) RecognizeAdaptive ¶
func (c *Client) RecognizeAdaptive(ctx context.Context, pcm []float32, sampleRate int, offsetSec, seconds float64) (*Response, error)
RecognizeAdaptive decodes nothing: it fingerprints the given PCM with an adaptive clip length and sends the matching duration to the API. seconds is the clip length starting at offsetSec; <= 0 means all available audio (capped at 16 s).
func (*Client) RecognizeFile ¶
RecognizeFile is Recognize for a file path.
func (*Client) RecognizeFileAdaptive ¶
func (c *Client) RecognizeFileAdaptive(ctx context.Context, path string, seconds float64) (*Response, error)
RecognizeFileAdaptive is RecognizeAdaptive for a file path. seconds <= 0 uses the whole file (bounded by the endpoint's maximum query length).
func (*Client) RecognizeFileAdaptiveAt ¶
func (c *Client) RecognizeFileAdaptiveAt(ctx context.Context, path string, offsetSec, seconds float64) (*Response, error)
RecognizeFileAdaptiveAt is RecognizeFileAdaptive with a start offset.
func (*Client) RecognizePCM ¶
func (c *Client) RecognizePCM(ctx context.Context, pcm []float32, sampleRate int, offsetSec float64) (*Response, error)
RecognizePCM queries the API with mono PCM samples (first channel) starting at offsetSec. The clip length is c.Duration (0 = all available audio, 6 = a 6-second window clamped to the available audio).
type Engine ¶
type Engine struct{}
Engine computes NetEase audio fingerprints. It is stateless and safe for concurrent use.
func NewEngine ¶
NewEngine returns a fingerprint engine. The context is accepted for compatibility; no resources are allocated.
func (*Engine) ExtractQueryFP ¶
ExtractQueryFP computes the raw (encrypted) fingerprint for exactly FingerprintRate*FingerprintSeconds samples of 8 kHz mono PCM.
func (*Engine) Fingerprint ¶
func (e *Engine) Fingerprint(ctx context.Context, pcm []float32, sampleRate int, offsetSec float64) (string, error)
Fingerprint is like the package-level Fingerprint but uses this engine.
func (*Engine) FingerprintAdaptive ¶
func (e *Engine) FingerprintAdaptive(ctx context.Context, pcm []float32, sampleRate int, offsetSec, seconds float64) (string, FingerprintInfo, error)
FingerprintAdaptive fingerprints a clip of the given length (seconds) at offsetSec and adapts it to a duration accepted by the match endpoint. Pass seconds <= 0 to use all audio available after offsetSec (capped at 16 s).
The returned FingerprintInfo.Duration must be sent as the API "duration" field; Client.MatchDuration / Client.RecognizeAdaptive do this automatically.
type FingerprintInfo ¶
type FingerprintInfo struct {
// Duration is the value to send as the API's "duration" form field.
Duration int
// Used is the length of audio actually fingerprinted, in seconds. It is
// also the duration embedded in the fingerprint itself.
Used float64
// Requested is the requested length after clamping to the available audio.
Requested float64
// Action is AdaptiveKeep, AdaptivePad or AdaptiveTruncate.
Action string
}
FingerprintInfo describes how an adaptive fingerprint was produced.
func FingerprintAdaptive ¶
func FingerprintAdaptive(ctx context.Context, pcm []float32, sampleRate int, offsetSec, seconds float64) (string, FingerprintInfo, error)
FingerprintAdaptive is the package-level version of (*Engine).FingerprintAdaptive.
type Response ¶
type Response struct {
Code int `json:"code"`
Data json.RawMessage `json:"data"`
Raw json.RawMessage `json:"-"`
}
Response is the API response. Raw always holds the unmodified JSON.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
ncmrecognize
command
Command ncmrecognize identifies a song file (wav, mp3, flac, ogg) via NetEase Cloud Music.
|
Command ncmrecognize identifies a song file (wav, mp3, flac, ogg) via NetEase Cloud Music. |