Merge branch 'allmp4' of https://github.com/xhenner/tag into xhenner-allmp4

This commit is contained in:
David Howden 2015-05-25 22:36:14 +10:00
commit 3f92286cdb

77
mp4.go
View File

@ -6,6 +6,7 @@ package tag
import (
"encoding/binary"
"errors"
"fmt"
"io"
"os"
@ -69,9 +70,62 @@ func ReadAtoms(r io.ReadSeeker) (Metadata, error) {
return m, err
}
func readCustomAtom(r io.ReadSeeker, size uint32) (string, uint32, error) {
var datasize uint32
var datapos int64
var name string
var mean string
for size > 8 {
var subsize uint32
err := binary.Read(r, binary.BigEndian, &subsize)
if err != nil {
return "----", size - 4, err
}
subname, err := readString(r, 4)
if err != nil {
return "----", size - 8, err
}
b, err := readBytes(r, int(subsize-8))
if err != nil {
return "----", size - subsize, err
}
// Remove the size of the atom from the size counter
size -= subsize
switch string(subname) {
case "mean":
mean = string(b[4:])
case "name":
name = string(b[4:])
case "data":
datapos, err = r.Seek(0, os.SEEK_CUR)
if err != nil {
return "----", size, err
}
datasize = subsize
datapos -= int64(subsize)
}
}
// there should remain only the header size
if size != 8 {
return "----", size, errors.New("---- atom out of bound")
}
if mean == "com.apple.iTunes" && datasize != 0 && name != "" {
// we jump just before the data subatom
_, err := r.Seek(datapos, os.SEEK_SET)
if err != nil {
return "----", size, err
}
return name, datasize + 8, nil
}
return "----", size, nil
}
func (m metadataMP4) readAtoms(r io.ReadSeeker) error {
for {
var size uint32
ok := false
err := binary.Read(r, binary.BigEndian, &size)
if err != nil {
if err == io.EOF {
@ -101,8 +155,25 @@ func (m metadataMP4) readAtoms(r io.ReadSeeker) error {
return err
}
continue
case "mdat": // stop when we get to the data
return nil
case "mdat": // skip the data, the metadata can be at the end
_, err := r.Seek(int64(size-8), os.SEEK_CUR)
if err != nil {
return err
}
continue
case "----":
// Generic atom.
// Should have 3 sub atoms : mean, name and data.
// We check that mean=="com.apple.iTunes" and we use the subname as
// the name, and move to the data atom.
// If anything goes wrong, we jump at the end of the "----" atom.
name, size, err = readCustomAtom(r, size)
if err != nil {
return err
}
ok = (name != "----")
default:
_, ok = atoms[name]
}
b, err := readBytes(r, int(size-8))
@ -110,7 +181,7 @@ func (m metadataMP4) readAtoms(r io.ReadSeeker) error {
return err
}
_, ok := atoms[name]
// At this point, we allow all known atoms and the valid "----" atoms
if !ok {
continue
}