Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 23 additions & 29 deletions chapter_frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type ChapterFrame struct {
StartOffset uint32
EndOffset uint32
Title *TextFrame
SubTitle *TextFrame
Description *TextFrame
}

func (cf ChapterFrame) Size() int {
Expand All @@ -36,10 +36,10 @@ func (cf ChapterFrame) Size() int {
frameHeaderSize + // Title frame header size
cf.Title.Size()
}
if cf.SubTitle != nil {
if cf.Description != nil {
size = size +
frameHeaderSize + // SubTitle frame header size
cf.SubTitle.Size()
frameHeaderSize + // Description frame header size
cf.Description.Size()
}
return size
}
Expand All @@ -63,14 +63,15 @@ func (cf ChapterFrame) WriteTo(w io.Writer) (n int64, err error) {
writeFrame(bw, "TIT2", *cf.Title, true)
}

if cf.SubTitle != nil {
writeFrame(bw, "TIT3", cf.SubTitle, true)
if cf.Description != nil {
writeFrame(bw, "TIT3", *cf.Description, true)
}
})
}

func parseChapterFrame(br *bufReader) (Framer, error) {
func parseChapterFrame(br *bufReader, version byte) (Framer, error) {
ElementID := br.ReadText(EncodingISO)
var synchSafe bool
var startTime uint32
var startOffset uint32
var endTime uint32
Expand All @@ -90,47 +91,40 @@ func parseChapterFrame(br *bufReader) (Framer, error) {
}

var title TextFrame
var subTitle TextFrame
var description TextFrame

// borrowed from parse.go
buf := getByteSlice(32 * 1024)
defer putByteSlice(buf)
if version == 4 {
synchSafe = true
} else {
synchSafe = false
}
for {
// no way to determine whether this should be true or not
// this is likely should be fixed
header, err := parseFrameHeader(buf, br, true)
header, err := parseFrameHeader(buf, br, synchSafe)
if err == io.EOF || err == errBlankFrame || err == ErrInvalidSizeFormat {
break
}
if err != nil {
return nil, err
}
id, bodySize := header.ID, header.BodySize
if id == "TIT2" {
if id == "TIT2" || id == "TIT3" {
bodyRd := getLimitedReader(br, bodySize)
br2 := newBufReader(bodyRd)
frame, err := parseTextFrame(br2)
br := newBufReader(bodyRd)
frame, err := parseTextFrame(br)
if err != nil {
putLimitedReader(bodyRd)
return nil, err
}
title = frame.(TextFrame)

putLimitedReader(bodyRd)
break
}
if id == "TIT3" {
bodyRd := getLimitedReader(br, bodySize)
br3 := newBufReader(bodyRd)
frame, err := parseTextFrame(br3)
if err != nil {
putLimitedReader(bodyRd)
return nil, err
if id == "TIT2" {
title = frame.(TextFrame)
} else if id == "TIT3" {
description = frame.(TextFrame)
}
subTitle = frame.(TextFrame)

putLimitedReader(bodyRd)
break
}
}

Expand All @@ -143,7 +137,7 @@ func parseChapterFrame(br *bufReader) (Framer, error) {
StartOffset: startOffset,
EndOffset: endOffset,
Title: &title,
SubTitle: &subTitle,
Description: &description,
}
return cf, nil
}
272 changes: 151 additions & 121 deletions chapter_frame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,129 +29,159 @@ func prepareTestFile() (*os.File, error) {
}

func TestAddChapterFrame(t *testing.T) {
tmpFile, err := prepareTestFile()
if err != nil {
t.Error(err)
}
defer os.Remove(tmpFile.Name())

tag, err := Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}

chap := ChapterFrame{
ElementID: "chap0",
StartTime: 0,
EndTime: time.Duration(1000 * nanosInMillis),
StartOffset: 0,
EndOffset: 0,
}
tag.AddChapterFrame(chap)

if err := tag.Save(); err != nil {
t.Error(err)
}
tag.Close()

tag, err = Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}
frame := tag.GetLastFrame("CHAP").(ChapterFrame)
if frame.ElementID != "chap0" {
t.Error(err)
}
if frame.StartTime != 0 {
t.Errorf("expected: %d, but got %s", 0, frame.StartTime)
}
if frame.EndTime.Seconds()*1000 != 1000 {
t.Errorf("expected: %d, but got %d", 1000, int(frame.EndTime.Seconds()*1000))
}
}

func TestAddChapterFrameWithTitle(t *testing.T) {
tmpFile, err := prepareTestFile()
if err != nil {
t.Error(err)
}
defer os.Remove(tmpFile.Name())

tag, err := Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}

chap := ChapterFrame{
ElementID: "chap0",
StartTime: 0,
EndTime: 0,
StartOffset: 0,
EndOffset: 0,
Title: &TextFrame{
Encoding: EncodingUTF8,
Text: "chapter 0",
type fields struct {
ElementID string
StartTime time.Duration
EndTime time.Duration
StartOffset uint32
EndOffset uint32
Title *TextFrame
Description *TextFrame
}
tests := []struct {
name string
fields fields
wantElementId string
wantTitle string
wantDescription string
}{
{
name: "element id only",
fields: fields{
ElementID: "chap0",
StartTime: 0,
EndTime: time.Duration(1000 * nanosInMillis),
StartOffset: 0,
EndOffset: 0,
},
wantElementId: "chap0",
wantTitle: "",
wantDescription: "",
},
}
tag.AddChapterFrame(chap)

if err := tag.Save(); err != nil {
t.Error(err)
}
tag.Close()

tag, err = Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}
frame := tag.GetLastFrame("CHAP").(ChapterFrame)
if frame.ElementID != "chap0" {
t.Error(err)
}
if frame.Title.Text != "chapter 0" {
t.Errorf("expected: %s, but got %s", "chapter 0", frame.Title)
}
}

func TestAddChapterFrameWithSubTitle(t *testing.T) {
tmpFile, err := prepareTestFile()
if err != nil {
t.Error(err)
}
defer os.Remove(tmpFile.Name())

tag, err := Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}

chap := ChapterFrame{
ElementID: "chap0",
StartTime: 0,
EndTime: 0,
StartOffset: 0,
EndOffset: 0,
SubTitle: &TextFrame{
Encoding: EncodingUTF8,
Text: "chapter 0",
{
name: "with title",
fields: fields{
ElementID: "chap0",
StartTime: 0,
EndTime: time.Duration(1000 * nanosInMillis),
StartOffset: 0,
EndOffset: 0,
Title: &TextFrame{
Encoding: EncodingUTF8,
Text: "chapter 0",
},
},
wantElementId: "chap0",
wantTitle: "chapter 0",
wantDescription: "",
},
{
name: "with description",
fields: fields{
ElementID: "chap0",
StartTime: 0,
EndTime: time.Duration(1000 * nanosInMillis),
StartOffset: 0,
EndOffset: 0,
Description: &TextFrame{
Encoding: EncodingUTF8,
Text: "chapter 0",
},
},
wantElementId: "chap0",
wantTitle: "",
wantDescription: "chapter 0",
},
{
name: "with title and description",
fields: fields{
ElementID: "chap0",
StartTime: 0,
EndTime: time.Duration(1000 * nanosInMillis),
StartOffset: 0,
EndOffset: 0,
Title: &TextFrame{
Encoding: EncodingUTF8,
Text: "chapter 0 title",
},
Description: &TextFrame{
Encoding: EncodingUTF8,
Text: "chapter 0 description",
},
},
wantElementId: "chap0",
wantTitle: "chapter 0 title",
wantDescription: "chapter 0 description",
},
{
name: "non-zero time and offset",
fields: fields{
ElementID: "chap0",
StartTime: time.Duration(1000 * nanosInMillis),
EndTime: time.Duration(1000 * nanosInMillis),
StartOffset: 10,
EndOffset: 10,
},
wantElementId: "chap0",
wantTitle: "",
wantDescription: "",
},
}
tag.AddChapterFrame(chap)

if err := tag.Save(); err != nil {
t.Error(err)
}
tag.Close()

tag, err = Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}
frame := tag.GetLastFrame("CHAP").(ChapterFrame)
if frame.ElementID != "chap0" {
t.Error(err)
}
if frame.SubTitle.Text != "chapter 0" {
t.Errorf("expected: %s, but got %s", "chapter 0", frame.Title)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tmpFile, err := prepareTestFile()
if err != nil {
t.Error(err)
}
defer os.Remove(tmpFile.Name())

tag, err := Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}

cf := ChapterFrame{
ElementID: tt.fields.ElementID,
StartTime: tt.fields.StartTime,
EndTime: tt.fields.EndTime,
StartOffset: tt.fields.StartOffset,
EndOffset: tt.fields.EndOffset,
Title: tt.fields.Title,
Description: tt.fields.Description,
}
tag.AddChapterFrame(cf)

if err := tag.Save(); err != nil {
t.Error(err)
}
tag.Close()

tag, err = Open(tmpFile.Name(), Options{Parse: true})
if tag == nil || err != nil {
log.Fatal("Error while opening mp3 file: ", err)
}
frame := tag.GetLastFrame("CHAP").(ChapterFrame)
if frame.ElementID != tt.wantElementId {
t.Errorf("expected: %s, but got %s", tt.wantElementId, frame.ElementID)
}
if frame.Title.Text != tt.wantTitle {
t.Errorf("expected: %s, but got %s", tt.wantTitle, frame.Title)
}
if frame.Description.Text != tt.wantDescription {
t.Errorf("expected: %s, but got %s", tt.wantDescription, frame.Description.Text)
}
if frame.StartTime != tt.fields.StartTime {
t.Errorf("expected: %s, but got %s", tt.fields.StartTime, frame.StartTime)
}
if frame.EndTime != tt.fields.EndTime {
t.Errorf("expected: %s, but got %s", tt.fields.EndTime, frame.EndTime)
}
if frame.StartOffset != tt.fields.StartOffset {
t.Errorf("expected: %d, but got %d", tt.fields.StartOffset, frame.StartOffset)
}
if frame.EndOffset != tt.fields.EndOffset {
t.Errorf("expected: %d, but got %d", tt.fields.EndOffset, frame.EndOffset)
}
})
}
}
Loading