Вы получаете ошибку сегментации, потому что mp3File.Frame("POPM")
фактически возвращает значение nil
.Я сузил его до V23FrameTypeMap
в id3-go
, в котором отсутствует рамка TRDC
.Я действительно не знаком с внутренностями ID3, но, возможно, вам нужно проверить, действительно ли TRDC
присутствует в V2.3, и, если это так, добавить недостающие идентификаторы в V23FrameTypeMap
в id3-go
.
Поскольку изучать ID3 было бы слишком сложно, мне удалось получить тег POPM
, используя другую библиотеку https://github.com/dhowden/tag
f, _ := os.Open("with_popm.mp3")
m, _ := tag.ReadFrom(f)
fmt.Printf("%s\n", m.Raw()["POPM"])
, которая выдает:
traktor@native-instruments.de
Редактировать: я принял TDRC
за TRDC
, моя ошибка.В любом случае, вот что вам нужно сделать, чтобы получить поле POPM
, используя id3-go
Добавьте следующее в V23FrameTypeMap
в github.com/mikkyang/id3-go/v2/idv23.go
V23FrameTypeMap = map[string]FrameType{
//...
"TDRC": FrameType{id: "TDRC", description: "Recording Date", constructor: ParseTextFrame},
}
Тогда вы можете легкополучите поле POPM
, например
package main
import (
"fmt"
id3 "github.com/mikkyang/id3-go"
)
func main() {
f, _ := id3.Open("with_popm.mp3")
p := f.Frame("POPM")
fmt.Printf("%s\n", p.Bytes())
}
Редактировать 2: Я добавил способ, чтобы вы могли анализировать поле POPM
.Затем вы можете получить доступ к рейтингу 255/255 от Popularimeter.Rating
:
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
id3 "github.com/mikkyang/id3-go"
)
func main() {
f, _ := id3.Open("with_popm.mp3")
popm := f.Frame("POPM")
popularimeter, _ := FromData(popm.Bytes())
fmt.Println(popularimeter)
}
type Rating uint8
func (r Rating) String() string {
if r == 0 {
return "unknown"
}
return fmt.Sprintf("%d/255", r)
}
type Popularimeter struct {
Email string
Rating Rating
Counter uint32
}
func FromData(data []byte) (*Popularimeter, error) {
tokens := bytes.SplitN(data, []byte{0x0}, 2)
// Pupolarimeter: <string>, null, 1byte rating, 4bytes counter
if len(tokens) != 2 || len(tokens[1]) != 5 {
return nil, errors.New("invalid Popularimeter")
}
return &Popularimeter{
Email: string(tokens[0]),
Rating: Rating(tokens[1][0]),
Counter: binary.BigEndian.Uint32(tokens[1][1:]),
}, nil
}