using JT1078.FMp4.MessagePack; using System; using System.Collections.Generic; using System.Text; using Xunit; using JT1078.Protocol.Extensions; using JT1078.FMp4.Enums; using JT1078.FMp4.Samples; using System.Buffers.Binary; using System.IO; using System.Linq; namespace JT1078.FMp4.Test { public class FMp4Box_Test { /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "ftyp")] public void ftyp_test() { var MinorVersion = Encoding.ASCII.GetString(new byte[4] { 0,0,2,0}); FileTypeBox fileTypeBox = new FileTypeBox(); fileTypeBox.MajorBrand = "isom"; fileTypeBox.MinorVersion = "\0\0\u0002\0"; fileTypeBox.CompatibleBrands.Add("isom"); fileTypeBox.CompatibleBrands.Add("iso2"); fileTypeBox.CompatibleBrands.Add("avc1"); fileTypeBox.CompatibleBrands.Add("iso6"); fileTypeBox.CompatibleBrands.Add("mp41"); FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x25]); fileTypeBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("000000246674797069736f6d0000020069736f6d69736f326176633169736f366d703431".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_mvhd")] public void moov_mvhd_test() { MovieHeaderBox movieHeaderBox = new MovieHeaderBox(0); movieHeaderBox.CreationTime = 0; movieHeaderBox.ModificationTime = 0; movieHeaderBox.Timescale = 1000; movieHeaderBox.Duration = 0; movieHeaderBox.NextTrackID = 2; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); movieHeaderBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("0000006c6d766864000000000000000000000000000003e8000000000001000001000000000000000000000000010000000000000000000000000000000100000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_tkhd")] public void moov_trak_tkhd_test() { TrackHeaderBox trackHeaderBox = new TrackHeaderBox(0,3); trackHeaderBox.CreationTime = 0; trackHeaderBox.ModificationTime = 0; trackHeaderBox.TrackID = 1; trackHeaderBox.Duration = 0; trackHeaderBox.Width = 544u; trackHeaderBox.Height = 960u; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); trackHeaderBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("0000005C746B68640000000300000000000000000000000100000000000000000000000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000004000000000000220000003C0".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia")] public void moov_trak_mdia_test() { } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia_mdhd")] public void moov_trak_mdia_mdhd_test() { MediaHeaderBox mediaHeaderBox = new MediaHeaderBox(0, 0); mediaHeaderBox.CreationTime = 0; mediaHeaderBox.ModificationTime = 0; mediaHeaderBox.Timescale = 0x00124f80; mediaHeaderBox.Duration = 0; mediaHeaderBox.Language = "und"; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); mediaHeaderBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); //000000206d64686400000000000000000000000000124f800000000055c40000 //00000020 //6d646864 //00000000 //00000000 //00000000 //00124f80 //00000000 //55c4 //0000 Assert.Equal("000000206d64686400000000000000000000000000124f800000000055c40000".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia_hdlr")] public void moov_trak_mdia_hdlr_test() { HandlerBox handlerBox = new HandlerBox(0, 0); handlerBox.HandlerType = Enums.HandlerType.vide; handlerBox.Name = "VideoHandler"; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); handlerBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("0000002C68646C72000000000000000076696465000000000000000000000000566964656F48616E646C6572".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia_hdlr_minf")] public void moov_trak_mdia_hdlr_minf_test() { HandlerBox handlerBox = new HandlerBox(0, 0); handlerBox.HandlerType = Enums.HandlerType.vide; handlerBox.Name = "VideoHandler\0"; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); handlerBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("0000002D68646C72000000000000000076696465000000000000000000000000566964656F48616E646C657200".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia_hdlr_minf_vmhd")] public void moov_trak_mdia_hdlr_minf_vmhd_test() { VideoMediaHeaderBox videoMediaHeaderBox = new VideoMediaHeaderBox(); FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); videoMediaHeaderBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("00000014766d6864000000010000000000000000".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia_hdlr_minf_dinf")] public void moov_trak_mdia_hdlr_minf_dinf_test() { DataInformationBox dataInformationBox = new DataInformationBox(); DataReferenceBox dataReferenceBox = new DataReferenceBox(); dataReferenceBox.DataEntryBoxes = new List(); dataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(version: 0, flags: 1)); dataInformationBox.DataReferenceBox = dataReferenceBox; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]); dataInformationBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); //0000002464696e660000001c6472656600000000000000010000000c75726c2000000001 Assert.Equal("0000002464696e660000001c6472656600000000000000010000000c75726c2000000001".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_trak_mdia_hdlr_minf_stbl")] public void moov_trak_mdia_hdlr_minf_stbl_test() { //000000e17374626c000000957374736400000000000000010000008561766331000000000000000100000000000000000000000000000000022003c0004800000048000000000000000100000000000000000000000000000000000000000000000000000000000000000018ffff0000002f617663430164001fffe100176764001facd940881e684000f4240037b40883c60c658001000568efbcb0000000001073747473000000000000000000000010737473630000000000000000000000147374737a000000000000000000000000000000107374636f0000000000000000 //stbl SampleTableBox sampleTableBox = new SampleTableBox(); //stbl->stsd SampleDescriptionBox sampleDescriptionBox = new SampleDescriptionBox(HandlerType.none); //stbl->stsd->avc1 AVC1SampleEntry aVC1SampleEntry = new AVC1SampleEntry(); aVC1SampleEntry.Width = 0x0220; aVC1SampleEntry.Height = 0x03c0; //stbl->stsd->avc1->avcc AVCConfigurationBox aVCConfigurationBox = new AVCConfigurationBox(); aVCConfigurationBox.AVCProfileIndication = 0x64; aVCConfigurationBox.ProfileCompatibility = 0; aVCConfigurationBox.AVCLevelIndication = 0x1f; aVCConfigurationBox.LengthSizeMinusOne = 0xff; aVCConfigurationBox.SPSs = new List() { "6764001facd940881e684000f4240037b40883c60c6580".ToHexBytes() }; aVCConfigurationBox.PPSs = new List() { "68efbcb000".ToHexBytes() }; aVC1SampleEntry.AVCConfigurationBox = aVCConfigurationBox; sampleDescriptionBox.SampleEntries = new List() { aVC1SampleEntry }; sampleTableBox.SampleDescriptionBox = sampleDescriptionBox; //stbl->stts sampleTableBox.TimeToSampleBox = new TimeToSampleBox(); //stbl->stsc sampleTableBox.SampleToChunkBox = new SampleToChunkBox(); //stbl->stsz sampleTableBox.SampleSizeBox = new SampleSizeBox(); //stbl->stco sampleTableBox.ChunkOffsetBox = new ChunkOffsetBox(); FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x000000e1]); sampleTableBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("000000e17374626c000000957374736400000000000000010000008561766331000000000000000100000000000000000000000000000000022003c0004800000048000000000000000100000000000000000000000000000000000000000000000000000000000000000018ffff0000002f617663430164001fffe100176764001facd940881e684000f4240037b40883c60c658001000568efbcb0000000001073747473000000000000000000000010737473630000000000000000000000147374737a000000000000000000000000000000107374636f0000000000000000".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_mvex")] public void trak_mvex_test() { //moov->mvex MovieExtendsBox movieExtendsBox = new MovieExtendsBox(); //moov->mvex->trex movieExtendsBox.TrackExtendsBoxs = new List(); TrackExtendsBox trackExtendsBox1 = new TrackExtendsBox(); trackExtendsBox1.TrackID = 0x01; trackExtendsBox1.DefaultSampleDescriptionIndex = 0x01; movieExtendsBox.TrackExtendsBoxs.Add(trackExtendsBox1); FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x00000028]); movieExtendsBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("000000286d7665780000002074726578000000000000000100000001000000000000000000000000".ToUpper(), hex); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moov_udta")] public void moov_udta_test() { //todo:moov->udta } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "moof")] public void moof_test() { //000006d8747261660000002474666864000000390000000100000000000002fc0000bb80000066ee01010000 //00 00 06 d8 //74 72 61 66 //00 00 00 24 //74 66 68 64 //00 //00 00 39 //00 00 00 01 //00 00 00 00 00 00 02 fc //00 00 bb 80 //00 00 66 ee //01 01 00 00 //moof MovieFragmentBox movieFragmentBox = new MovieFragmentBox(); //moof->mfhd movieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox(); movieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 0x01; //moof->traf movieFragmentBox.TrackFragmentBox = new TrackFragmentBox(); //moof->traf->tfhd movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x000039); movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 0x01; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = 0x00000000000002fc; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 0x0000bb80; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = 0x000066ee; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x01010000; //moof->tfdt movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox(); //moof->trun //000006987472756E00000305000000D0000006F802000000 //00 00 06 98 //74 72 75 6E //00 //00 03 05 //00 00 00 D0 SampleCount //00 00 06 F8 DataOffset //02 00 00 00 FirstSampleFlags //fragmented_demo_trun.txt TrackRunInfos movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(0, 0x00000305); movieFragmentBox.TrackFragmentBox.TrackRunBox.SampleCount = 0x000000D0; movieFragmentBox.TrackFragmentBox.TrackRunBox.DataOffset = 0x000006F8; movieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 0x02000000; movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List(); var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FMP4", "fragmented_demo_trun.txt")); var buffers = lines.Where(w => !string.IsNullOrEmpty(w)).Select(s => s.ToHexBytes()).ToList(); //SampleDuration //SampleSize foreach (var buffer in buffers) { var mod = buffer.Length / 8; for (int i = 0; i < mod; i++) { TrackRunBox.TrackRunInfo trackRunInfo = new TrackRunBox.TrackRunInfo(); trackRunInfo.SampleDuration = BinaryPrimitives.ReadUInt32BigEndian(buffer.Skip(i * 4).Take(4).ToArray()); trackRunInfo.SampleSize= BinaryPrimitives.ReadUInt32BigEndian(buffer.Skip((i + 1)*4).Take(4).ToArray()); movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(trackRunInfo); } } Assert.Equal(0x00000698, movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Count*8+4*6); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "mdat")] public void mdat_test() { MediaDataBox mediaDataBox = new MediaDataBox(); var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FMP4", "fragmented_demo_mdat.txt")); var buffers = lines.Where(w => !string.IsNullOrEmpty(w)).Select(s => s.ToHexBytes()).ToList(); List data = new List(); foreach (var buffer in buffers) { data = data.Concat(buffer).ToList(); } //00 0E 3C 9C Size //6D 64 61 74 BoxType Assert.Equal(0x000E3C9C-8, data.Count); } /// /// 使用doc/video/fragmented_demo.mp4 /// [Fact(DisplayName = "mfra")] public void mfra_test() { //000000436d6672610000002b7466726101000000000000010000000000000001000000000000000000000000000002fc010101000000106d66726f0000000000000043 //00 00 00 43 //6d 66 72 61 //00 00 00 2b //74 66 72 61 //01 //00 00 00 //00 00 00 01 //00 00 00 00 //00 00 00 01 //00 00 00 00 00 00 00 00 //00 00 00 00 00 00 02 fc //01 01 01 //00 00 00 10 //6d 66 72 6f //00 //00 00 00 //00 00 00 43 //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 = 0x00000000000002fc; 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; FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x00000043]); movieFragmentRandomAccessBox.ToBuffer(ref writer); var hex = writer.FlushAndGetArray().ToHexString(); Assert.Equal("000000436d6672610000002b7466726101000000000000010000000000000001000000000000000000000000000002fc010101000000106d66726f0000000000000043".ToUpper(), hex); } } }