From 287d1625bdc266c156d9cf0aa074c334ed3c41fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BA=86=E8=A3=95?= Date: Tue, 24 Mar 2026 11:13:10 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(mp4):=20=E6=8C=89=20ISO=2014496-12=20?= =?UTF-8?q?=E7=94=A8=20UTC=20=E5=86=99=E5=85=A5=20mvhd/mdhd/tkhd=20?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=88=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-mp4/mdhd-box.go | 6 +++--- go-mp4/mvhd-box.go | 7 ++++--- go-mp4/tkhd-box.go | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/go-mp4/mdhd-box.go b/go-mp4/mdhd-box.go index e3cc507..8a649ca 100644 --- a/go-mp4/mdhd-box.go +++ b/go-mp4/mdhd-box.go @@ -50,11 +50,11 @@ type MediaHeaderBox struct { } func NewMediaHeaderBox() *MediaHeaderBox { - _, offset := time.Now().Zone() + sec := time.Now().Unix() return &MediaHeaderBox{ Box: NewFullBox([4]byte{'m', 'd', 'h', 'd'}, 0), - Creation_time: uint64(time.Now().Unix() + int64(offset) + 0x7C25B080), - Modification_time: uint64(time.Now().Unix() + int64(offset) + 0x7C25B080), + Creation_time: uint64(sec + 0x7C25B080), + Modification_time: uint64(sec + 0x7C25B080), Timescale: 1000, Language: [3]byte{'u', 'n', 'd'}, } diff --git a/go-mp4/mvhd-box.go b/go-mp4/mvhd-box.go index a7afb66..a63799e 100644 --- a/go-mp4/mvhd-box.go +++ b/go-mp4/mvhd-box.go @@ -42,11 +42,12 @@ type MovieHeaderBox struct { } func NewMovieHeaderBox() *MovieHeaderBox { - _, offset := time.Now().Zone() + // ISO 14496-12: creation_time is seconds since 1904-01-01 UTC. Unix() is UTC; do not add Zone offset. + sec := time.Now().Unix() return &MovieHeaderBox{ Box: NewFullBox([4]byte{'m', 'v', 'h', 'd'}, 0), - Creation_time: uint64(time.Now().Unix() + int64(offset) + 0x7C25B080), - Modification_time: uint64(time.Now().Unix() + int64(offset) + 0x7C25B080), + Creation_time: uint64(sec + 0x7C25B080), + Modification_time: uint64(sec + 0x7C25B080), Timescale: 1000, Rate: 0x00010000, Volume: 0x0100, diff --git a/go-mp4/tkhd-box.go b/go-mp4/tkhd-box.go index 96d9197..3c52de3 100644 --- a/go-mp4/tkhd-box.go +++ b/go-mp4/tkhd-box.go @@ -48,11 +48,11 @@ type TrackHeaderBox struct { } func NewTrackHeaderBox() *TrackHeaderBox { - _, offset := time.Now().Zone() + sec := time.Now().Unix() return &TrackHeaderBox{ Box: NewFullBox([4]byte{'t', 'k', 'h', 'd'}, 0), - Creation_time: uint64(time.Now().Unix() + int64(offset) + 0x7C25B080), - Modification_time: uint64(time.Now().Unix() + int64(offset) + 0x7C25B080), + Creation_time: uint64(sec + 0x7C25B080), + Modification_time: uint64(sec + 0x7C25B080), Layer: 0, Alternate_group: 0, Matrix: [9]uint32{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000}, From e502b423d545de06846aca9b979364322f9bd6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BA=86=E8=A3=95?= Date: Sat, 28 Mar 2026 14:11:46 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix(go-mp4):=20=E4=B8=8D=E6=8A=8A=20VPS/SPS?= =?UTF-8?q?/PPS=20=E5=86=99=E5=85=A5=20mdat=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E4=B8=8E=20hvcC/avcC=20=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-mp4/mp4track.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/go-mp4/mp4track.go b/go-mp4/mp4track.go index 911d696..b8dfe55 100644 --- a/go-mp4/mp4track.go +++ b/go-mp4/mp4track.go @@ -320,6 +320,7 @@ func (track *mp4track) writeH264(h264 []byte, pts, dts uint64) (err error) { track.height = height } } + return true // param sets stored in avcC only, not in sample data case codec.H264_NAL_PPS: ppsid := codec.GetPPSIdWithStartCode(nalu) for _, pps := range h264extra.ppss { @@ -330,6 +331,7 @@ func (track *mp4track) writeH264(h264 []byte, pts, dts uint64) (err error) { tmp := make([]byte, len(nalu)) copy(tmp, nalu) h264extra.ppss = append(h264extra.ppss, tmp) + return true // param sets stored in avcC only, not in sample data } //aud/sps/pps/sei 为帧间隔 //通过first_slice_in_mb来判断,改nalu是否为一帧的开头 @@ -389,10 +391,13 @@ func (track *mp4track) writeH265(h265 []byte, pts, dts uint64) (err error) { track.height = height } } + return true // param sets stored in hvcC only, not in sample data case codec.H265_NAL_PPS: h265extra.hvccExtra.UpdatePPS(nalu) + return true case codec.H265_NAL_VPS: h265extra.hvccExtra.UpdateVPS(nalu) + return true } if track.lastSample.hasVcl && isH265NewAccessUnit(nalu) {