Skip to content

Commit

Permalink
fix: mvhd and tkhd timestamps
Browse files Browse the repository at this point in the history
timestamps were off by one day.
Added methods to set and get creation and modification times
for mvhd and tkhd boxes with unix epoch reference.
  • Loading branch information
tobbee committed Jul 20, 2024
1 parent b4b85be commit bccd30e
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 23 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Nothing yet
### Fixed

- mvhd and tkhd timestamp was off by one day

### Added

- mvhd and tkhd methods to set and get creation and modification times

## [0.45.1] - 2024-07-12

Expand Down
26 changes: 24 additions & 2 deletions mp4/mvhd.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ type MvhdBox struct {
Volume Fixed16
}

// EpochDiffS is the difference in seconds between Jan 1, 1904 and Jan 1, 1970
const EpochDiffS = int64((66*365 + 17) * 24 * 3600)

// CreateMvhd - create mvhd box with reasonable values
func CreateMvhd() *MvhdBox {
return &MvhdBox{
Expand Down Expand Up @@ -140,10 +143,29 @@ func (b *MvhdBox) Info(w io.Writer, specificBoxLevels, indent, indentStep string
return bd.err
}

// CraetionTimeS returns the creation time in seconds since Jan 1, 1970
func (b *MvhdBox) CreationTimeS() int64 {
return int64(b.CreationTime) - EpochDiffS
}

// ModificationTimeS returns the modification time in seconds since Jan 1, 1970
func (b *MvhdBox) ModificationTimeS() int64 {
return int64(b.ModificationTime) - EpochDiffS
}

// SetCreationTimeS sets the creation time from seconds since Jan 1, 1970
func (b *MvhdBox) SetCreationTimeS(unixTimeS int64) {
b.CreationTime = uint64(unixTimeS + EpochDiffS)
}

// SetModificationTimeS sets the modification time from seconds since Jan 1, 1970
func (b *MvhdBox) SetModificationTimeS(unixTimeS int64) {
b.ModificationTime = uint64(unixTimeS + EpochDiffS)
}

// Make time string from t which is seconds since Jan. 1 1904
func timeStr(t uint64) string {
epochDiffS := int64((66*365 + 16) * 24 * 3600)
unixSeconds := int64(t) - epochDiffS
unixSeconds := int64(t) - EpochDiffS
if unixSeconds < 0 {
return "0"
}
Expand Down
38 changes: 24 additions & 14 deletions mp4/mvhd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,43 @@ package mp4

import (
"bytes"
"reflect"
"os"
"testing"
)

func TestMvhd(t *testing.T) {
var buf bytes.Buffer
mvhd := CreateMvhd()
boxDiffAfterEncodeAndDecode(t, mvhd)

mvhdCreated := CreateMvhd()
err := mvhdCreated.Encode(&buf)
if err != nil {
t.Error(err)
recentTime := int64(1721459921)
mvhd.SetCreationTimeS(recentTime)
mvhd.SetModificationTimeS(recentTime)
if mvhd.CreationTimeS() != recentTime {
t.Errorf("CreationTimeS %d not %d", mvhd.CreationTimeS(), recentTime)
}

if uint64(buf.Len()) != mvhdCreated.Size() {
t.Errorf("Mismatch bytes written %d not equal to size %d", buf.Len(), mvhdCreated.Size())
if mvhd.ModificationTimeS() != recentTime {
t.Errorf("ModificationTimeS %d not %d", mvhd.ModificationTimeS(), recentTime)
}
}

reader := &buf
hdr, err := DecodeHeader(reader)
func TestMvhdTimeDecodeS(t *testing.T) {
data, err := os.ReadFile("testdata/mvhd_1970.dat")
if err != nil {
t.Error(err)
}
mvhdRead, err := DecodeMvhd(hdr, 0, reader)
reader := bytes.NewReader(data)
box, err := DecodeBox(0, reader)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(mvhdRead, mvhdCreated) {
t.Errorf("Mismatch mvhdCreated vs mvhdRead:\n%+v\n%+v", mvhdCreated, mvhdRead)
mvhd, ok := box.(*MvhdBox)
if !ok {
t.Errorf("Not a MvhdBox %+v", box)
}
if mvhd.CreationTimeS() != 0 {
t.Errorf("CreationTimeS %d not 0", mvhd.CreationTimeS())
}
if mvhd.ModificationTimeS() != 0 {
t.Errorf("ModificationTimeS %d not 0", mvhd.ModificationTimeS())
}
}
12 changes: 6 additions & 6 deletions mp4/testdata/golden_init_prog_mp4_dump.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@
[mvhd] size=108 version=0 flags=000000
- timeScale: 600
- duration: 11520
- creation time: 2020-03-11T08:59:14Z
- modification time: 2020-03-11T08:59:14Z
- creation time: 2020-03-10T08:59:14Z
- modification time: 2020-03-10T08:59:14Z
[iods] size=21
- not implemented or unknown box
- 000000001007004fffffff7fff
[trak] size=4952
[tkhd] size=92 version=0 flags=000001
- trackID: 1
- duration: 11520
- creation time: 2020-03-11T08:59:14Z
- modification time: 2020-03-11T08:59:14Z
- creation time: 2020-03-10T08:59:14Z
- modification time: 2020-03-10T08:59:14Z
- Width: 960.0, Height: 540.0
[edts] size=36
[elst] size=28 version=0 flags=000000
- entry[1]: segmentDuration=11520 mediaTime=4, mediaRateInteger=1 mediaRateFraction=0
[mdia] size=4816
[mdhd] size=32 version=0 flags=000000
- timeScale: 100
- creation time: 2020-03-11T08:59:14Z
- modification time: 2020-03-11T08:59:14Z
- creation time: 2020-03-10T08:59:14Z
- modification time: 2020-03-10T08:59:14Z
- language: und
[hdlr] size=57 version=0 flags=000000
- handlerType: vide
Expand Down
Binary file added mp4/testdata/mvhd_1970.dat
Binary file not shown.
20 changes: 20 additions & 0 deletions mp4/tkhd.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,23 @@ func (b *TkhdBox) Info(w io.Writer, specificBoxLevels, indent, indentStep string
}
return bd.err
}

// CraetionTimeS returns the creation time in seconds since Jan 1, 1970
func (b *TkhdBox) CreationTimeS() int64 {
return int64(b.CreationTime) - EpochDiffS
}

// ModificationTimeS returns the modification time in seconds since Jan 1, 1970
func (b *TkhdBox) ModificationTimeS() int64 {
return int64(b.ModificationTime) - EpochDiffS
}

// SetCreationTimeS sets the creation time from seconds since Jan 1, 1970
func (b *TkhdBox) SetCreationTimeS(unixTimeS int64) {
b.CreationTime = uint64(unixTimeS + EpochDiffS)
}

// SetModificationTimeS sets the modification time from seconds since Jan 1, 1970
func (b *TkhdBox) SetModificationTimeS(unixTimeS int64) {
b.ModificationTime = uint64(unixTimeS + EpochDiffS)
}

0 comments on commit bccd30e

Please sign in to comment.