ximalaya.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package ximalaya
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "unlock-music.dev/cli/algo/common"
  7. "unlock-music.dev/cli/internal/sniff"
  8. )
  9. type Decoder struct {
  10. rd io.ReadSeeker
  11. offset int
  12. audio io.Reader
  13. }
  14. func NewDecoder(p *common.DecoderParams) common.Decoder {
  15. return &Decoder{rd: p.Reader}
  16. }
  17. func (d *Decoder) Validate() error {
  18. encryptedHeader := make([]byte, x2mHeaderSize)
  19. if _, err := io.ReadFull(d.rd, encryptedHeader); err != nil {
  20. return fmt.Errorf("ximalaya read header: %w", err)
  21. }
  22. { // try to decode with x2m
  23. header := decryptX2MHeader(encryptedHeader)
  24. if _, ok := sniff.AudioExtension(header); ok {
  25. d.audio = io.MultiReader(bytes.NewReader(header), d.rd)
  26. return nil
  27. }
  28. }
  29. { // try to decode with x3m
  30. // not read file again, since x2m and x3m have the same header size
  31. header := decryptX3MHeader(encryptedHeader)
  32. if _, ok := sniff.AudioExtension(header); ok {
  33. d.audio = io.MultiReader(bytes.NewReader(header), d.rd)
  34. return nil
  35. }
  36. }
  37. return fmt.Errorf("ximalaya: unknown format")
  38. }
  39. func (d *Decoder) Read(p []byte) (n int, err error) {
  40. return d.audio.Read(p)
  41. }
  42. func init() {
  43. common.RegisterDecoder("x2m", false, NewDecoder)
  44. common.RegisterDecoder("x3m", false, NewDecoder)
  45. common.RegisterDecoder("xm", false, NewDecoder)
  46. }