From 1c78cba18679e130454d9f82a18752e849fd1b4c Mon Sep 17 00:00:00 2001 From: "SmallChi(Koike)" <564952747@qq.com> Date: Thu, 18 Mar 2021 18:23:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=861078=E8=BD=ACfmp4=5F3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/JT1078.FMp4.Test/H264/placeholder.txt | 1 + src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj | 4 + src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs | 139 +++++++++++++----- src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs | 3 +- src/JT1078.FMp4/Boxs/HandlerBox.cs | 10 +- src/JT1078.FMp4/Boxs/MediaDataBox.cs | 14 +- src/JT1078.FMp4/Boxs/MediaHeaderBox.cs | 2 +- src/JT1078.FMp4/Boxs/MovieBox.cs | 8 + .../MovieFragmentRandomAccessOffsetBox.cs | 4 +- src/JT1078.FMp4/Boxs/MovieHeaderBox.cs | 2 +- .../TrackFragmentBaseMediaDecodeTimeBox.cs | 11 +- .../Boxs/TrackFragmentHeaderBox.cs | 1 + .../Boxs/TrackFragmentRandomAccessBox.cs | 6 + src/JT1078.FMp4/Boxs/TrackHeaderBox.cs | 17 ++- src/JT1078.FMp4/Boxs/UserDataBox.cs | 18 ++- src/JT1078.FMp4/FMp4Box.cs | 4 + src/JT1078.FMp4/JT1078.FMp4.xml | 21 +++ .../MessagePack/FMp4MessagePackWriter.cs | 6 + 18 files changed, 222 insertions(+), 49 deletions(-) create mode 100644 src/JT1078.FMp4.Test/H264/placeholder.txt diff --git a/src/JT1078.FMp4.Test/H264/placeholder.txt b/src/JT1078.FMp4.Test/H264/placeholder.txt new file mode 100644 index 0000000..c3833e4 --- /dev/null +++ b/src/JT1078.FMp4.Test/H264/placeholder.txt @@ -0,0 +1 @@ +placeholder \ No newline at end of file diff --git a/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj b/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj index 026873a..4587528 100644 --- a/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj +++ b/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj @@ -30,6 +30,7 @@ Always + @@ -51,6 +52,9 @@ Always + + Always + diff --git a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs index afe89ec..48ed35e 100644 --- a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs +++ b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs @@ -5,6 +5,7 @@ using JT1078.Protocol; using JT1078.Protocol.Extensions; using JT1078.Protocol.H264; using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.IO; using System.Linq; @@ -38,34 +39,27 @@ namespace JT1078.FMp4.Test fileTypeBox.CompatibleBrands.Add("mp41"); //moov MovieBox movieBox = new MovieBox(); - movieBox.MovieHeaderBox = new MovieHeaderBox(1, 0); - movieBox.MovieHeaderBox.CreationTime = 2; - movieBox.MovieHeaderBox.ModificationTime = 3; - //var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); - //var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); - movieBox.MovieHeaderBox.Duration = 1; + movieBox.MovieHeaderBox = new MovieHeaderBox(0, 0); + movieBox.MovieHeaderBox.CreationTime = 0; + movieBox.MovieHeaderBox.ModificationTime = 0; + movieBox.MovieHeaderBox.Duration = 0; movieBox.MovieHeaderBox.Timescale = 1000; + movieBox.MovieHeaderBox.NextTrackID = 2; movieBox.TrackBox = new TrackBox(); - movieBox.TrackBox.TrackHeaderBox = new TrackHeaderBox(1, 7); - movieBox.TrackBox.TrackHeaderBox.CreationTime = 2; - movieBox.TrackBox.TrackHeaderBox.ModificationTime = 3; - movieBox.TrackBox.TrackHeaderBox.TrackID = movieBox.MovieHeaderBox.NextTrackID; - //duration = track.duration * track.timescale, - //upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)), - //lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); + movieBox.TrackBox.TrackHeaderBox = new TrackHeaderBox(0, 3); + movieBox.TrackBox.TrackHeaderBox.CreationTime = 0; + movieBox.TrackBox.TrackHeaderBox.ModificationTime = 0; + movieBox.TrackBox.TrackHeaderBox.TrackID = 1; movieBox.TrackBox.TrackHeaderBox.Duration = 0; movieBox.TrackBox.TrackHeaderBox.TrackIsAudio = false; movieBox.TrackBox.TrackHeaderBox.Width = 352; movieBox.TrackBox.TrackHeaderBox.Height = 288; movieBox.TrackBox.MediaBox = new MediaBox(); movieBox.TrackBox.MediaBox.MediaHeaderBox = new MediaHeaderBox(); - //duration *= timescale; - //var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)); - //var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1)); - movieBox.TrackBox.MediaBox.MediaHeaderBox.CreationTime = 2; - movieBox.TrackBox.MediaBox.MediaHeaderBox.ModificationTime = 3; - movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1000; - movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration = 1; + movieBox.TrackBox.MediaBox.MediaHeaderBox.CreationTime = 0; + movieBox.TrackBox.MediaBox.MediaHeaderBox.ModificationTime = 0; + movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1200000; + movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration = 0; movieBox.TrackBox.MediaBox.HandlerBox = new HandlerBox(); movieBox.TrackBox.MediaBox.HandlerBox.HandlerType = HandlerType.vide; movieBox.TrackBox.MediaBox.HandlerBox.Name = "VideoHandler"; @@ -85,7 +79,10 @@ namespace JT1078.FMp4.Test avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height; avc1.AVCConfigurationBox.AVCLevelIndication = 20; avc1.AVCConfigurationBox.AVCProfileIndication = 77; - avc1.AVCConfigurationBox.PPSs = new List() { ppsNALU.RawData }; + //todo:pps解析多一位 + var a = ppsNALU.RawData.ToList(); + a.Add(0); + avc1.AVCConfigurationBox.PPSs = new List() { a.ToArray() }; avc1.AVCConfigurationBox.SPSs = new List() { spsNALU.RawData }; avc1.AVCConfigurationBox.ProfileCompatibility = 0; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1); @@ -96,46 +93,68 @@ namespace JT1078.FMp4.Test movieBox.MovieExtendsBox = new MovieExtendsBox(); movieBox.MovieExtendsBox.TrackExtendsBoxs = new List(); TrackExtendsBox trex = new TrackExtendsBox(); - trex.TrackID = movieBox.MovieHeaderBox.NextTrackID; + trex.TrackID = 1; trex.DefaultSampleDescriptionIndex = 1; trex.DefaultSampleDuration = 0; trex.DefaultSampleSize = 0; - trex.DefaultSampleFlags = 1; + trex.DefaultSampleFlags = 0; movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex); + //用户自定义可以不用 + //movieBox.UserDataBox = new UserDataBox(); + //movieBox.UserDataBox.Data = "0000005a6d657461000000000000002168646c7200000000000000006d6469726170706c0000000000000000000000002d696c737400000025a9746f6f0000001d6461746100000001000000004c61766635382e34352e313030".ToHexBytes(); //fragment moof n List moofs = new List(); FragmentBox fragmentBox = new FragmentBox(); fragmentBox.MovieFragmentBox = new MovieFragmentBox(); fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox(); - fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 0; + fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 1; fragmentBox.MovieFragmentBox.TrackFragmentBox = new TrackFragmentBox(); - fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(); - fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = movieBox.MovieHeaderBox.NextTrackID; - fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox = new SampleDependencyTypeBox(); - fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes = new List(); + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x39); + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1; + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = 0x000000000000028c; + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 48000; + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)jT1078Package.Bodies.Length; + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000; + //fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox = new SampleDependencyTypeBox(); + //fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes = new List(); //todo:fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox(); //upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)), //lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1)); fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0; //trun - fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(); + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x5); + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.DataOffset = 120; + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 33554432; + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List(); + fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo()); fragmentBox.MediaDataBox = new MediaDataBox(); - var nalUnitTypes = new List() { 7, 8 }; fragmentBox.MediaDataBox.Data = nalus - .Where(w => !nalUnitTypes.Contains(w.NALUHeader.NalUnitType)) .Select(s => s.RawData) - .SelectMany(a => a) - .ToArray(); + .ToList(); moofs.Add(fragmentBox); - - //mfra + MovieFragmentRandomAccessBox movieFragmentRandomAccessBox = new MovieFragmentRandomAccessBox(); + //mfra->tfra + movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox = new TrackFragmentRandomAccessBox(1); + movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackID = 0x01; + movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos = new List(); + TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo trackFragmentRandomAccessInfo1 = new TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo(); + trackFragmentRandomAccessInfo1.Time = 0; + trackFragmentRandomAccessInfo1.MoofOffset = 0x000000000000028c; + trackFragmentRandomAccessInfo1.TrafNumber = 0x01; + trackFragmentRandomAccessInfo1.TrunNumber = 0x01; + trackFragmentRandomAccessInfo1.SampleNumber = 0x01; + movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos.Add(trackFragmentRandomAccessInfo1); + //mfra->mfro + movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox = new MovieFragmentRandomAccessOffsetBox(0); + movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox.MfraSize = 0x00000043; FMp4Box fMp4Box = new FMp4Box(); fMp4Box.FileTypeBox = fileTypeBox; fMp4Box.MovieBox = movieBox; fMp4Box.FragmentBoxs = moofs; + fMp4Box.MovieFragmentRandomAccessBox = movieFragmentRandomAccessBox; FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[65535]); fMp4Box.ToBuffer(ref writer); var buffer = writer.FlushAndGetArray(); @@ -147,9 +166,59 @@ namespace JT1078.FMp4.Test using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); fileStream.Write(buffer); fileStream.Close(); + } + + [Fact] + public void tkhd_width_height_test() + { + //01 60 00 00 + //01 20 00 00 + var a = BinaryPrimitives.ReadUInt32LittleEndian(new byte[] { 0x01, 0x60, 0, 0 }); + var b = BinaryPrimitives.ReadUInt32LittleEndian(new byte[] { 0x01, 0x20, 0, 0 }); + + //00 00 01 60 + //00 00 01 20 + var c = BinaryPrimitives.ReadUInt32BigEndian(new byte[] { 0, 0, 0x01, 0x20 }); + var d = BinaryPrimitives.ReadUInt32BigEndian(new byte[] { 0, 0, 0x01, 0x60 }); + + var e = new byte[4]; + var f = new byte[4]; + BinaryPrimitives.WriteUInt32LittleEndian(e, 352); + BinaryPrimitives.WriteUInt32LittleEndian(f, 288); + //60 01 00 00 + //20 01 00 00 + var g = e.ToHexString(); + var h = f.ToHexString(); + } + [Fact] + public void tfdt_test() + { + var TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox(); + TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0; + FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[65535]); + TrackFragmentBaseMediaDecodeTimeBox.ToBuffer(ref writer); + var buffer = writer.FlushAndGetArray().ToHexString(); } + [Fact] + public void match_test() + { + var filepath1 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.mp4"); + var filepath2 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_1_fragmented.mp4"); + var byte1=File.ReadAllBytes(filepath1); + var byte2=File.ReadAllBytes(filepath2); + if(byte1.Length== byte2.Length) + { + for(var i=0;i< byte1.Length; i++) + { + if (byte1[i] != byte2[i]) + { + + } + } + } + } public JT1078Package ParseNALUTest() { diff --git a/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs b/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs index 676d4ec..e84b9d3 100644 --- a/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs +++ b/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs @@ -62,7 +62,8 @@ namespace JT1078.FMp4 writer.WriteByte(AVCProfileIndication); writer.WriteByte(ProfileCompatibility); writer.WriteByte(AVCLevelIndication); - writer.WriteByte((byte)(0xfc | LengthSizeMinusOne)); + //writer.WriteByte((byte)(0xfc | LengthSizeMinusOne)); + writer.WriteByte(0xff); if (SPSs!=null && SPSs.Count > 0) { //NumOfSequenceParameterSets diff --git a/src/JT1078.FMp4/Boxs/HandlerBox.cs b/src/JT1078.FMp4/Boxs/HandlerBox.cs index a5400e3..c2fed40 100644 --- a/src/JT1078.FMp4/Boxs/HandlerBox.cs +++ b/src/JT1078.FMp4/Boxs/HandlerBox.cs @@ -43,7 +43,15 @@ namespace JT1078.FMp4 { writer.WriteUInt32(r); } - writer.WriteUTF8(Name??"\0"); + if (!string.IsNullOrEmpty(Name)) + { + writer.WriteUTF8(Name); + writer.WriteUTF8("\0"); + } + else + { + writer.WriteUTF8("\0"); + } End(ref writer); } } diff --git a/src/JT1078.FMp4/Boxs/MediaDataBox.cs b/src/JT1078.FMp4/Boxs/MediaDataBox.cs index f826a95..e107f41 100644 --- a/src/JT1078.FMp4/Boxs/MediaDataBox.cs +++ b/src/JT1078.FMp4/Boxs/MediaDataBox.cs @@ -23,14 +23,22 @@ namespace JT1078.FMp4 /// Filter out AUD/SPS/PPS NAL units from your stream
/// Write you converted NAL units into the MDAT box
/// - public byte[] Data { get; set; } + public List Data { get; set; } public void ToBuffer(ref FMp4MessagePackWriter writer) { Start(ref writer); - if (Data != null && Data.Length > 0) + + if (Data != null && Data.Count > 0) { - writer.WriteArray(Data); + foreach(var nalu in Data) + { + if(nalu!=null && nalu.Length > 0) + { + writer.WriteInt32(nalu.Length); + writer.WriteArray(nalu); + } + } } End(ref writer); } diff --git a/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs b/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs index e0fd9ed..6c523ba 100644 --- a/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs +++ b/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs @@ -16,7 +16,7 @@ namespace JT1078.FMp4 /// /// /// - public MediaHeaderBox(byte version=1, uint flags=0) : base("mdhd", version, flags) + public MediaHeaderBox(byte version=0, uint flags=0) : base("mdhd", version, flags) { } public ulong CreationTime { get; set; } diff --git a/src/JT1078.FMp4/Boxs/MovieBox.cs b/src/JT1078.FMp4/Boxs/MovieBox.cs index d8530d2..231fbb7 100644 --- a/src/JT1078.FMp4/Boxs/MovieBox.cs +++ b/src/JT1078.FMp4/Boxs/MovieBox.cs @@ -30,6 +30,10 @@ namespace JT1078.FMp4 /// mvex /// public MovieExtendsBox MovieExtendsBox { get; set; } + /// + /// udta + /// + public UserDataBox UserDataBox { get; set; } public void ToBuffer(ref FMp4MessagePackWriter writer) { @@ -37,6 +41,10 @@ namespace JT1078.FMp4 MovieHeaderBox.ToBuffer(ref writer); TrackBox.ToBuffer(ref writer); MovieExtendsBox.ToBuffer(ref writer); + if (UserDataBox != null) + { + UserDataBox.ToBuffer(ref writer); + } End(ref writer); } } diff --git a/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs b/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs index 28da638..105ad7e 100644 --- a/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs +++ b/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs @@ -19,7 +19,9 @@ namespace JT1078.FMp4 public MovieFragmentRandomAccessOffsetBox(byte version, uint flags=0) : base("mfro", version, flags) { } - + /// + /// mfra 盒子大小 + /// public uint MfraSize { get; set; } public void ToBuffer(ref FMp4MessagePackWriter writer) diff --git a/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs b/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs index 7a73c98..e330ccc 100644 --- a/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs +++ b/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs @@ -16,7 +16,7 @@ namespace JT1078.FMp4 /// /// /// - public MovieHeaderBox(byte version=1, uint flags=0) : base("mvhd", version, flags) + public MovieHeaderBox(byte version, uint flags=0) : base("mvhd", version, flags) { } public ulong CreationTime { get; set; } diff --git a/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs b/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs index b5c14b8..5fbc75c 100644 --- a/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs +++ b/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs @@ -19,13 +19,20 @@ namespace JT1078.FMp4 public TrackFragmentBaseMediaDecodeTimeBox(byte version=1, uint flags=0) : base("tfdt", version, flags) { } - public uint BaseMediaDecodeTime { get; set; } + public ulong BaseMediaDecodeTime { get; set; } public void ToBuffer(ref FMp4MessagePackWriter writer) { Start(ref writer); WriterFullBoxToBuffer(ref writer); - writer.WriteUInt32(BaseMediaDecodeTime); + if (Version == 1) + { + writer.WriteUInt64(BaseMediaDecodeTime); + } + else + { + writer.WriteUInt32((uint)BaseMediaDecodeTime); + } End(ref writer); } } diff --git a/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs b/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs index f293e7e..290d8ed 100644 --- a/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs +++ b/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs @@ -44,6 +44,7 @@ namespace JT1078.FMp4 public uint DefaultSampleDuration { get; set; } /// /// TFHD_FLAG_DEFAULT_SIZE + /// H.264 NALU SIZE /// public uint DefaultSampleSize { get; set; } /// diff --git a/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs b/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs index 1bf9f1e..50b9151 100644 --- a/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs +++ b/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs @@ -37,6 +37,9 @@ namespace JT1078.FMp4 /// public byte LengthSizeOfSampleNum { get; set; } public uint NumberOfEntry { get; set; } + /// + /// (moof+mdta)N + /// public List TrackFragmentRandomAccessInfos { get; set; } public void ToBuffer(ref FMp4MessagePackWriter writer) @@ -97,6 +100,9 @@ namespace JT1078.FMp4 public class TrackFragmentRandomAccessInfo { public ulong Time { get; set; } + /// + /// 需要定位到当前 moof offset + /// public ulong MoofOffset { get; set; } public uint TrafNumber { get; set; } public uint TrunNumber { get; set; } diff --git a/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs b/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs index 05e494a..1ef424c 100644 --- a/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs +++ b/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs @@ -82,8 +82,21 @@ namespace JT1078.FMp4 { writer.WriteInt32(m); } - writer.WriteUInt32(Width); - writer.WriteUInt32(Height); + //好奇葩的解析方式 + //实际 + //01 60 00 00 + //01 20 00 00 + //32位大端 + //00 00 01 60 + //00 00 01 20 + //32位小端 + //60 01 00 00 + //20 01 00 00 + //直接用32位去解析是解析不出来的。 + writer.WriteUInt16((ushort)Width); + writer.WriteUInt16(0); + writer.WriteUInt16((ushort)Height); + writer.WriteUInt16(0); End(ref writer); } } diff --git a/src/JT1078.FMp4/Boxs/UserDataBox.cs b/src/JT1078.FMp4/Boxs/UserDataBox.cs index 7abf7f9..2d1f250 100644 --- a/src/JT1078.FMp4/Boxs/UserDataBox.cs +++ b/src/JT1078.FMp4/Boxs/UserDataBox.cs @@ -1,13 +1,27 @@ -using System; +using JT1078.FMp4.Interfaces; +using JT1078.FMp4.MessagePack; +using System; using System.Collections.Generic; using System.Text; namespace JT1078.FMp4 { - public class UserDataBox : Mp4Box + public class UserDataBox : Mp4Box, IFMp4MessagePackFormatter { public UserDataBox() : base("udta") { } + + public byte[] Data { get; set; } + + public void ToBuffer(ref FMp4MessagePackWriter writer) + { + Start(ref writer); + if(Data!=null && Data.Length > 0) + { + writer.WriteArray(Data); + } + End(ref writer); + } } } diff --git a/src/JT1078.FMp4/FMp4Box.cs b/src/JT1078.FMp4/FMp4Box.cs index 19b86e7..3957d7a 100644 --- a/src/JT1078.FMp4/FMp4Box.cs +++ b/src/JT1078.FMp4/FMp4Box.cs @@ -52,6 +52,10 @@ namespace JT1078.FMp4 item.MediaDataBox.ToBuffer(ref writer); } } + if (MovieFragmentRandomAccessBox != null) + { + MovieFragmentRandomAccessBox.ToBuffer(ref writer); + } } } } diff --git a/src/JT1078.FMp4/JT1078.FMp4.xml b/src/JT1078.FMp4/JT1078.FMp4.xml index a787863..6e97545 100644 --- a/src/JT1078.FMp4/JT1078.FMp4.xml +++ b/src/JT1078.FMp4/JT1078.FMp4.xml @@ -386,6 +386,11 @@ mvex + + + udta + + mvex @@ -482,6 +487,11 @@ + + + mfra 盒子大小 + + mvhd @@ -892,6 +902,7 @@ TFHD_FLAG_DEFAULT_SIZE + H.264 NALU SIZE @@ -931,6 +942,16 @@ 2bit + + + (moof+mdta)N + + + + + 需要定位到当前 moof offset + + tkhd diff --git a/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs b/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs index d12cbcc..ddeab4e 100644 --- a/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs +++ b/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs @@ -49,6 +49,12 @@ namespace JT1078.FMp4.MessagePack writer.Advance(4); } + public void WriteUInt32Little(uint value) + { + BinaryPrimitives.WriteUInt32LittleEndian(writer.Free, value); + writer.Advance(4); + } + public void WriteUInt24(uint value) { var span = writer.Free;