package ximalaya import ( "bytes" "fmt" "io" "jsuse.com/dev/dec-music/decrypt" "jsuse.com/dev/dec-music/internal/sniff" ) type decoder struct { rd io.ReadSeeker offset int audio io.Reader } func newDecoder(p *decrypt.DecoderParams) decrypt.Decoder { return &decoder{rd: p.Reader} } func (d *decoder) Validate() error { encryptedHeader := make([]byte, x2mHeaderSize) if _, err := io.ReadFull(d.rd, encryptedHeader); err != nil { return fmt.Errorf("ximalaya read header: %w", err) } { // try to decode with x2m header := decryptX2MHeader(encryptedHeader) if _, ok := sniff.AudioExtension(header); ok { d.audio = io.MultiReader(bytes.NewReader(header), d.rd) return nil } } { // try to decode with x3m // not read file again, since x2m and x3m have the same header size header := decryptX3MHeader(encryptedHeader) if _, ok := sniff.AudioExtension(header); ok { d.audio = io.MultiReader(bytes.NewReader(header), d.rd) return nil } } return fmt.Errorf("ximalaya: unknown format") } func (d *decoder) Read(p []byte) (n int, err error) { return d.audio.Read(p) } func init() { decrypt.RegisterDecoder("x2m", false , newDecoder) decrypt.RegisterDecoder("x3m", false , newDecoder) decrypt.RegisterDecoder("xm", false , newDecoder) }