diff --git a/README.md b/README.md index 6398e74..93ebc21 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,18 @@ wherever your `$GOPATH` is). mp3chap file.mp3 0 "chapter 1 is great" 123 "chapter 2 is ok" 456 "chapter 3 is boring" -The first argument is the path to the MP3 file, then pairs of arguments each containing -a start time in seconds, and the chapter title. +The first argument is the path to the MP3 file, then pairs of arguments each +containing a start time in seconds, and the chapter title. -It is assumed that each chapter ends where the next one begins, and that the final chapter -ends at the last millisecond of the file (as defined in its `TLEN` ID3 frame). +It is assumed that each chapter ends where the next one begins, and that the +final chapter ends at the last millisecond of the file (as defined in its +`TLEN` ID3 frame). + +If the file does not contain a `TLEN` ID3 frame, a final time argument must +be supplied (in seconds) which will be used as the end time of the final +chapter. + + mp3chap file.mp3 0 "chapter 1 is great" 123 "chapter 2 is ok" 456 "chapter 3 is boring" 789 Changes to the ID3 tag in the MP3 file are written out in-place. diff --git a/mp3chap.go b/mp3chap.go index 1fb983e..8bee5b5 100644 --- a/mp3chap.go +++ b/mp3chap.go @@ -62,8 +62,10 @@ func main() { chaps := make([]Chapter, 0) tocchaps := make([]string, 0) + finalEnd := uint64(0) - for x := 2; x < len(os.Args)-1; x += 2 { + x := 2 + for ; x < len(os.Args)-1; x += 2 { if x+1 > len(os.Args)-2+1 { usage() } @@ -80,6 +82,14 @@ func main() { chaps = append(chaps, chap) } + // if there is a final odd arg, use it as the final chapter end + if x < len(os.Args) { + finalEnd, err = strconv.ParseUint(os.Args[x], 10, 32) + if err != nil { + log.Fatal("failed parsing final seconds %#v: %v", os.Args[x], err) + } + } + // each chapter ends where the next one starts for x := range chaps { if x < len(chaps)-1 { @@ -87,21 +97,25 @@ func main() { } } - // and the last one ends when the file does - tlenf := mp3.Frame("TLEN") - if tlenf == nil { - log.Fatal("can't find TLEN frame, don't know total duration") - } - tlenft, ok := tlenf.(*id3v2.TextFrame) - if !ok { - log.Fatal("can't convert TLEN to TextFrame") - } - tlen, err := strconv.ParseUint(tlenft.Text(), 10, 32) - if err == nil { - log.Fatal("can't parse TLEN value %#v\n", tlenft.Text()) - } + if finalEnd == 0 { + // and the last one ends when the file does + tlenf := mp3.Frame("TLEN") + if tlenf == nil { + log.Fatal("can't find TLEN frame, don't know total duration") + } + tlenft, ok := tlenf.(*id3v2.TextFrame) + if !ok { + log.Fatal("can't convert TLEN to TextFrame") + } + tlen, err := strconv.ParseUint(tlenft.Text(), 10, 32) + if err == nil { + log.Fatal("can't parse TLEN value %#v\n", tlenft.Text()) + } - chaps[len(chaps)-1].endSecs = uint32(tlen) + chaps[len(chaps)-1].endSecs = uint32(tlen) + } else { + chaps[len(chaps)-1].endSecs = uint32(finalEnd) + } // ready to modify the file, clear out what's there mp3.DeleteFrames("CTOC")