/// <summary> /// 编码首个视频盒子 /// </summary> /// <param name="package">jt1078完整包</param> /// <returns></returns> public byte[] EncoderFirstVideoBox(JT1078Package package) { byte[] buffer = FMp4ArrayPool.Rent(package.Bodies.Length + 4096); FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[10 * 1024 * 1024]); try { var nalus = h264Decoder.ParseNALU(package); var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7); //SPS spsNALU.RawData = h264Decoder.DiscardEmulationPreventionBytes(spsNALU.RawData); var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8); ppsNALU.RawData = h264Decoder.DiscardEmulationPreventionBytes(ppsNALU.RawData); ExpGolombReader h264GolombReader = new ExpGolombReader(spsNALU.RawData); var spsInfo = h264GolombReader.ReadSPS(); //ftyp FileTypeBox fileTypeBox = new FileTypeBox(); fileTypeBox.MajorBrand = "isom"; fileTypeBox.MinorVersion = "\0\0\u0002\0"; fileTypeBox.CompatibleBrands.Add("isom"); fileTypeBox.CompatibleBrands.Add("iso6"); fileTypeBox.CompatibleBrands.Add("iso2"); fileTypeBox.CompatibleBrands.Add("avc1"); fileTypeBox.CompatibleBrands.Add("mp41"); //moov MovieBox movieBox = new MovieBox(); 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(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 = (uint)spsInfo.width; movieBox.TrackBox.TrackHeaderBox.Height = (uint)spsInfo.height; movieBox.TrackBox.MediaBox = new MediaBox(); movieBox.TrackBox.MediaBox.MediaHeaderBox = new MediaHeaderBox(); 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"; movieBox.TrackBox.MediaBox.MediaInformationBox = new MediaInformationBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.VideoMediaHeaderBox = new VideoMediaHeaderBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox = new DataInformationBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox = new DataReferenceBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List <DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List <SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); //h264 avc1.Width = (ushort)movieBox.TrackBox.TrackHeaderBox.Width; avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height; avc1.AVCConfigurationBox.AVCLevelIndication = spsInfo.levelIdc; avc1.AVCConfigurationBox.AVCProfileIndication = spsInfo.profileIdc; avc1.AVCConfigurationBox.ProfileCompatibility = (byte)spsInfo.profileCompat; avc1.AVCConfigurationBox.PPSs = new List <byte[]>() { ppsNALU.RawData }; avc1.AVCConfigurationBox.SPSs = new List <byte[]>() { spsNALU.RawData }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox(); movieBox.MovieExtendsBox = new MovieExtendsBox(); movieBox.MovieExtendsBox.TrackExtendsBoxs = new List <TrackExtendsBox>(); TrackExtendsBox trex = new TrackExtendsBox(); trex.TrackID = 1; trex.DefaultSampleDescriptionIndex = 1; trex.DefaultSampleDuration = 0; trex.DefaultSampleSize = 0; trex.DefaultSampleFlags = 0; movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex); fileTypeBox.ToBuffer(ref writer); movieBox.ToBuffer(ref writer); var data = writer.FlushAndGetArray(); return(data); } finally { FMp4ArrayPool.Return(buffer); } }
/// <summary> /// 编码moov盒子 /// </summary> /// <returns></returns> public byte[] EncoderMoovBox(List <H264NALU> nalus, int naluLength) { byte[] buffer = FMp4ArrayPool.Rent(naluLength + 4096); FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); try { var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7); //SPS spsNALU.RawData = h264Decoder.DiscardEmulationPreventionBytes(spsNALU.RawData); var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8); ppsNALU.RawData = h264Decoder.DiscardEmulationPreventionBytes(ppsNALU.RawData); ExpGolombReader h264GolombReader = new ExpGolombReader(spsNALU.RawData); var spsInfo = h264GolombReader.ReadSPS(); //moov MovieBox movieBox = new MovieBox(); movieBox.MovieHeaderBox = new MovieHeaderBox(0, 2); movieBox.MovieHeaderBox.CreationTime = 0; movieBox.MovieHeaderBox.ModificationTime = 0; movieBox.MovieHeaderBox.Duration = 0; movieBox.MovieHeaderBox.Timescale = 1000; movieBox.MovieHeaderBox.NextTrackID = 99; movieBox.TrackBox = new TrackBox(); 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 = (uint)spsInfo.width; movieBox.TrackBox.TrackHeaderBox.Height = (uint)spsInfo.height; movieBox.TrackBox.MediaBox = new MediaBox(); movieBox.TrackBox.MediaBox.MediaHeaderBox = new MediaHeaderBox(); 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"; movieBox.TrackBox.MediaBox.MediaInformationBox = new MediaInformationBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.VideoMediaHeaderBox = new VideoMediaHeaderBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox = new DataInformationBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox = new DataReferenceBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List <DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List <SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); //h264 avc1.Width = (ushort)movieBox.TrackBox.TrackHeaderBox.Width; avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height; avc1.AVCConfigurationBox.AVCLevelIndication = spsInfo.levelIdc; avc1.AVCConfigurationBox.AVCProfileIndication = spsInfo.profileIdc; avc1.AVCConfigurationBox.ProfileCompatibility = (byte)spsInfo.profileCompat; avc1.AVCConfigurationBox.PPSs = new List <byte[]>() { ppsNALU.RawData }; avc1.AVCConfigurationBox.SPSs = new List <byte[]>() { spsNALU.RawData }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox() { //TimeToSampleInfos=new List<TimeToSampleBox.TimeToSampleInfo> //{ // new TimeToSampleBox.TimeToSampleInfo // { // SampleCount=0, // SampleDelta=0 // } //} }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox() { //SampleToChunkInfos=new List<SampleToChunkBox.SampleToChunkInfo>() //{ // new SampleToChunkBox.SampleToChunkInfo // { // } //} }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox() { //EntrySize = new List<uint>() //{ // 0 //} }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox() { //ChunkOffset=new List<uint>() //{ // 0 //} }; movieBox.MovieExtendsBox = new MovieExtendsBox(); movieBox.MovieExtendsBox.TrackExtendsBoxs = new List <TrackExtendsBox>(); TrackExtendsBox trex = new TrackExtendsBox(); trex.TrackID = 1; trex.DefaultSampleDescriptionIndex = 1; trex.DefaultSampleDuration = 0; trex.DefaultSampleSize = 0; trex.DefaultSampleFlags = 0; movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex); movieBox.ToBuffer(ref writer); var data = writer.FlushAndGetArray(); return(data); } finally { FMp4ArrayPool.Return(buffer); } }