|
|
@ -42,10 +42,10 @@ type Decoder struct {
|
|
|
|
|
|
|
|
|
|
|
|
metaRaw []byte
|
|
|
|
metaRaw []byte
|
|
|
|
metaType string
|
|
|
|
metaType string
|
|
|
|
Meta RawMeta
|
|
|
|
meta RawMeta
|
|
|
|
|
|
|
|
|
|
|
|
Cover []byte
|
|
|
|
cover []byte
|
|
|
|
Audio []byte
|
|
|
|
audio []byte
|
|
|
|
|
|
|
|
|
|
|
|
offsetKey uint32
|
|
|
|
offsetKey uint32
|
|
|
|
offsetMeta uint32
|
|
|
|
offsetMeta uint32
|
|
|
@ -53,16 +53,16 @@ type Decoder struct {
|
|
|
|
offsetAudio uint32
|
|
|
|
offsetAudio uint32
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (d *Decoder) Validate() bool {
|
|
|
|
func (d *Decoder) Validate() error {
|
|
|
|
if !bytes.Equal(magicHeader, d.file[:len(magicHeader)]) {
|
|
|
|
if !bytes.Equal(magicHeader, d.file[:len(magicHeader)]) {
|
|
|
|
return false
|
|
|
|
return errors.New("ncm magic header not match")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*if status.IsDebug {
|
|
|
|
/*if status.IsDebug {
|
|
|
|
logging.Log().Info("the unknown field of the header is: \n" + spew.Sdump(d.file[8:10]))
|
|
|
|
logging.Log().Info("the unknown field of the header is: \n" + spew.Sdump(d.file[8:10]))
|
|
|
|
}*/
|
|
|
|
}*/
|
|
|
|
d.offsetKey = 8 + 2
|
|
|
|
d.offsetKey = 8 + 2
|
|
|
|
return true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//todo: 读取前进行检查长度,防止越界
|
|
|
|
//todo: 读取前进行检查长度,防止越界
|
|
|
@ -141,11 +141,11 @@ func (d *Decoder) buildKeyBox() {
|
|
|
|
func (d *Decoder) parseMeta() error {
|
|
|
|
func (d *Decoder) parseMeta() error {
|
|
|
|
switch d.metaType {
|
|
|
|
switch d.metaType {
|
|
|
|
case "music":
|
|
|
|
case "music":
|
|
|
|
d.Meta = new(RawMetaMusic)
|
|
|
|
d.meta = new(RawMetaMusic)
|
|
|
|
return json.Unmarshal(d.metaRaw, d.Meta)
|
|
|
|
return json.Unmarshal(d.metaRaw, d.meta)
|
|
|
|
case "dj":
|
|
|
|
case "dj":
|
|
|
|
d.Meta = new(RawMetaDJ)
|
|
|
|
d.meta = new(RawMetaDJ)
|
|
|
|
return json.Unmarshal(d.metaRaw, d.Meta)
|
|
|
|
return json.Unmarshal(d.metaRaw, d.meta)
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return errors.New("unknown ncm meta type: " + d.metaType)
|
|
|
|
return errors.New("unknown ncm meta type: " + d.metaType)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -173,7 +173,7 @@ func (d *Decoder) readCoverData() error {
|
|
|
|
if iCoverLen == 0 {
|
|
|
|
if iCoverLen == 0 {
|
|
|
|
return errors.New("no any cover file found")
|
|
|
|
return errors.New("no any cover file found")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
d.Cover = d.file[coverLenStart+4 : 4+coverLenStart+iCoverLen]
|
|
|
|
d.cover = d.file[coverLenStart+4 : 4+coverLenStart+iCoverLen]
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -183,9 +183,9 @@ func (d *Decoder) readAudioData() error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
audioRaw := d.file[d.offsetAudio:]
|
|
|
|
audioRaw := d.file[d.offsetAudio:]
|
|
|
|
audioLen := len(audioRaw)
|
|
|
|
audioLen := len(audioRaw)
|
|
|
|
d.Audio = make([]byte, audioLen)
|
|
|
|
d.audio = make([]byte, audioLen)
|
|
|
|
for i := uint32(0); i < uint32(audioLen); i++ {
|
|
|
|
for i := uint32(0); i < uint32(audioLen); i++ {
|
|
|
|
d.Audio[i] = d.box[i&0xff] ^ audioRaw[i]
|
|
|
|
d.audio[i] = d.box[i&0xff] ^ audioRaw[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -213,23 +213,23 @@ func (d *Decoder) Decode() error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (d Decoder) GetAudioExt() string {
|
|
|
|
func (d Decoder) GetAudioExt() string {
|
|
|
|
if d.Meta != nil {
|
|
|
|
if d.meta != nil {
|
|
|
|
return d.Meta.GetFormat()
|
|
|
|
return d.meta.GetFormat()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (d Decoder) GetAudioData() []byte {
|
|
|
|
func (d Decoder) GetAudioData() []byte {
|
|
|
|
return d.Audio
|
|
|
|
return d.audio
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (d Decoder) GetCoverImage() []byte {
|
|
|
|
func (d Decoder) GetCoverImage() []byte {
|
|
|
|
if d.Cover != nil {
|
|
|
|
if d.cover != nil {
|
|
|
|
return d.Cover
|
|
|
|
return d.cover
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
{
|
|
|
|
imgURL := d.Meta.GetAlbumImageURL()
|
|
|
|
imgURL := d.meta.GetAlbumImageURL()
|
|
|
|
if d.Meta != nil && !strings.HasPrefix(imgURL, "http") {
|
|
|
|
if d.meta != nil && !strings.HasPrefix(imgURL, "http") {
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
resp, err := http.Get(imgURL)
|
|
|
|
resp, err := http.Get(imgURL)
|
|
|
@ -253,5 +253,5 @@ func (d Decoder) GetCoverImage() []byte {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (d Decoder) GetMeta() common.Meta {
|
|
|
|
func (d Decoder) GetMeta() common.Meta {
|
|
|
|
return d.Meta
|
|
|
|
return d.meta
|
|
|
|
}
|
|
|
|
}
|
|
|
|