mov/mov.go

57 lines
1.0 KiB
Go
Raw Normal View History

2016-12-10 15:28:23 -08:00
package mov
import (
"bytes"
"encoding/binary"
"errors"
2016-12-10 15:41:31 -08:00
"io"
2016-12-10 15:28:23 -08:00
"time"
)
const epochAdjust = 2082844800
// Created attempts to find a created time from the metadata in a .mov file.
2016-12-10 15:41:31 -08:00
func Created(file io.ReadSeeker) (time.Time, error) {
2016-12-10 15:28:23 -08:00
var r time.Time
2016-12-10 15:41:31 -08:00
var err error
2016-12-10 15:28:23 -08:00
buf := [8]byte{}
for {
2016-12-10 15:41:31 -08:00
_, err := file.Read(buf[:])
2016-12-10 15:28:23 -08:00
if err != nil {
return r, err
}
if bytes.Equal(buf[4:8], []byte("moov")) {
break
} else {
atomSize := binary.BigEndian.Uint32(buf[:])
2016-12-10 15:41:31 -08:00
file.Seek(int64(atomSize)-8, 1)
2016-12-10 15:28:23 -08:00
}
}
2016-12-10 15:41:31 -08:00
_, err = file.Read(buf[:])
2016-12-10 15:28:23 -08:00
if err != nil {
return r, err
}
s := string(buf[4:8])
switch s {
case "mvhd":
2016-12-10 15:41:31 -08:00
if _, err := file.Seek(4, 1); err != nil {
2016-12-10 15:28:23 -08:00
return r, err
}
2016-12-10 15:41:31 -08:00
_, err = file.Read(buf[:4])
2016-12-10 15:28:23 -08:00
if err != nil {
return r, err
}
i := int64(binary.BigEndian.Uint32(buf[:4]))
c := i - epochAdjust
u := time.Unix(c, 0).Local()
return u, nil
case "cmov":
return r, errors.New("moov atom is compressed")
default:
return r, errors.New("expected to find 'mvhd' header, didn't")
}
}