/// <summary> /// 编码首帧音频,即audioTag[0] /// <para> /// 注意:本方法已写入<see cref="previousTagSize"/> /// </para> /// </summary> /// <returns></returns> public byte[] EncoderFirstAudioTag(ulong timestamp) { byte[] buffer = FlvArrayPool.Rent(2048); try { FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); //flv body audio tag //flv body tag header FlvTags flvTags = new FlvTags { Type = TagType.Audio, Timestamp = (uint)timestamp, //flv body tag body AudioTagsData = new AudioTags(AACPacketType.AudioSpecificConfig) }; flvMessagePackWriter.WriteUInt32(previousTagSize); flvMessagePackWriter.WriteFlvTag(flvTags); var data = flvMessagePackWriter.FlushAndGetArray(); previousTagSize = (uint)(flvTags.DataSize + 11); return(data); } finally { FlvArrayPool.Return(buffer); } }
private void CreateVideoTagOtherFrame(ref FlvMessagePackWriter flvMessagePackWriter, uint previousTagSize, H264NALU nALU) { //flv body PreviousTagSize flvMessagePackWriter.WriteUInt32(previousTagSize); //flv body video tag //flv body tag header FlvTags flvTags = new FlvTags(); flvTags.Type = TagType.Video; flvTags.Timestamp = nALU.LastIFrameInterval; flvTags.TimestampExt = 0; flvTags.StreamId = 0; //flv body tag body flvTags.VideoTagsData = new VideoTags(); if (nALU.NALUHeader.NalUnitType == 5) { flvTags.VideoTagsData.FrameType = FrameType.KeyFrame; } else { flvTags.VideoTagsData.FrameType = FrameType.InterFrame; } flvTags.VideoTagsData.VideoData = new AvcVideoPacke(); flvTags.VideoTagsData.VideoData.AvcPacketType = AvcPacketType.Raw; flvTags.VideoTagsData.VideoData.CompositionTime = nALU.LastIFrameInterval; flvTags.VideoTagsData.VideoData.Data = nALU.RawData; flvMessagePackWriter.WriteFlvTag(flvTags); }
/// <summary> /// 编码脚本Tag /// </summary> /// <param name="spsInfo">解析后的sps信息</param> /// <param name="hasAudio">是否有音频</param> /// <param name="frameRate">帧率 默认25d 即每秒25帧</param> /// <returns></returns> public byte[] EncoderScriptTag(SPSInfo spsInfo, bool hasAudio = false, double frameRate = 25d) { byte[] buffer = FlvArrayPool.Rent(1024); try { FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); //flv body script tag //flv body tag header FlvTags flvTags = new FlvTags { Type = TagType.ScriptData, //flv body tag body DataTagsData = new Amf3 { Amf3Metadatas = new List <IAmf3Metadata> { new Amf3Metadata_Duration { Value = 0d }, new Amf3Metadata_VideoDataRate { Value = 0d }, new Amf3Metadata_VideoCodecId { Value = 7d }, new Amf3Metadata_FrameRate { Value = frameRate }, new Amf3Metadata_Width() { Value = spsInfo.width }, new Amf3Metadata_Height() { Value = spsInfo.height }, } } }; if (hasAudio) { flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_AudioCodecId()); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_AudioSampleRate()); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_AudioSampleSize()); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_AudioStereo()); } flvMessagePackWriter.WriteFlvTag(flvTags); flvMessagePackWriter.WriteUInt32((uint)(flvTags.DataSize + 11)); return(flvMessagePackWriter.FlushAndGetArray()); } finally { FlvArrayPool.Return(buffer); } }
/// <summary> /// 编码首帧视频,即videoTag[0] /// <para> /// 注意:本方法已写入<see cref="previousTagSize"/> /// </para> /// </summary> /// <param name="sps"></param> /// <param name="pps"></param> /// <param name="sei"></param> /// <returns></returns> public byte[] EncoderFirstVideoTag(H264NALU sps, H264NALU pps, H264NALU sei) { byte[] buffer = FlvArrayPool.Rent(2048); try { FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); var rawData = h264Decoder.DiscardEmulationPreventionBytes(sps.RawData); ExpGolombReader h264GolombReader = new ExpGolombReader(rawData); SPSInfo spsInfo = h264GolombReader.ReadSPS(); //flv body video tag //flv body tag header FlvTags flvTags = new FlvTags { Type = TagType.Video, Timestamp = (uint)sps.Timestamp, TimestampExt = 0, StreamId = 0, //flv body tag body VideoTagsData = new VideoTags() }; flvTags.VideoTagsData.FrameType = FrameType.KeyFrame; flvTags.VideoTagsData.VideoData = new AvcVideoPacke { AvcPacketType = AvcPacketType.SequenceHeader, CompositionTime = 0 }; AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord = new AVCDecoderConfigurationRecord { AVCProfileIndication = spsInfo.profileIdc, ProfileCompatibility = (byte)spsInfo.profileCompat, AVCLevelIndication = spsInfo.levelIdc, NumOfPictureParameterSets = 1, PPSBuffer = pps.RawData, SPSBuffer = sps.RawData }; flvTags.VideoTagsData.VideoData.AVCDecoderConfiguration = aVCDecoderConfigurationRecord; flvMessagePackWriter.WriteUInt32(previousTagSize); flvMessagePackWriter.WriteFlvTag(flvTags); var data = flvMessagePackWriter.FlushAndGetArray(); previousTagSize = (uint)(flvTags.DataSize + 11); return(data); } finally { FlvArrayPool.Return(buffer); } }
public void FlvMessagePackWriter_FlvTags_Test_1() { Span <byte> buffer = new byte[1024]; FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); FlvTags flvTags = new FlvTags { Type = Enums.TagType.ScriptData, DataSize = 156, DataTagsData = new Amf3 { Amf3Metadatas = new List <Flv.Metadata.IAmf3Metadata> { new Amf3Metadata_Duration { Value = 7.22100 }, new Amf3Metadata_FileSize { Value = 2005421.00000 }, new Amf3Metadata_FrameRate { Value = 29.16667 }, new Amf3Metadata_Height { Value = 960.00000 }, new Amf3Metadata_VideoCodecId { Value = 7.00000 }, new Amf3Metadata_VideoDataRate { Value = 0.00000 }, new Amf3Metadata_Width { Value = 544.00000 } } } }; flvMessagePackWriter.WriteFlvTag(flvTags); var hex = flvMessagePackWriter.FlushAndGetArray().ToHexString(); Assert.Equal("1200009C0000000000000002000A6F6E4D65746144617461080000000700086475726174696F6E00401CE24DD2F1A9FC000866696C6573697A6500413E99AD0000000000096672616D657261746500403D2AAAE297396D000668656967687400408E000000000000000C766964656F636F646563696400401C000000000000000D766964656F646174617261746500000000000000000000057769647468004081000000000000", hex); }
private void CreateScriptTagFrame(ref FlvMessagePackWriter flvMessagePackWriter, int width, int height) { //flv body PreviousTagSize awalys 0 flvMessagePackWriter.WriteUInt32(0); //flv body script tag //flv body tag header FlvTags flvTags = new FlvTags(); flvTags.Type = TagType.ScriptData; flvTags.Timestamp = 0; flvTags.TimestampExt = 0; flvTags.StreamId = 0; //flv body tag body flvTags.DataTagsData = new Amf3(); flvTags.DataTagsData.Amf3Metadatas = new List <IAmf3Metadata>(); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_Duration { Value = 0d }); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_VideoDataRate { Value = 0d }); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_VideoCodecId { Value = 7d }); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_FrameRate { Value = 25d }); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_Width { Value = width }); flvTags.DataTagsData.Amf3Metadatas.Add(new Amf3Metadata_Height { Value = height }); flvMessagePackWriter.WriteFlvTag(flvTags); }
private void CreateVideoTag0Frame(ref FlvMessagePackWriter flvMessagePackWriter, uint previousTagSize, AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord) { //flv body PreviousTagSize ScriptTag flvMessagePackWriter.WriteUInt32(previousTagSize); //flv body video tag //flv body tag header FlvTags flvTags = new FlvTags(); flvTags.Type = TagType.Video; flvTags.Timestamp = 0; flvTags.TimestampExt = 0; flvTags.StreamId = 0; //flv body tag body flvTags.VideoTagsData = new VideoTags(); flvTags.VideoTagsData.FrameType = FrameType.KeyFrame; flvTags.VideoTagsData.VideoData = new AvcVideoPacke(); flvTags.VideoTagsData.VideoData.AvcPacketType = AvcPacketType.SequenceHeader; flvTags.VideoTagsData.VideoData.CompositionTime = 0; flvTags.VideoTagsData.VideoData.AVCDecoderConfiguration = aVCDecoderConfigurationRecord; flvMessagePackWriter.WriteFlvTag(flvTags); }