Selaa lähdekoodia

1.添加Amf3基本脚本数据

2.添加flv解析工具及测试用例
tags/v1.1.0
smallchi 5 vuotta sitten
vanhempi
commit
dd45f3000d
31 muutettua tiedostoa jossa 556 lisäystä ja 34 poistoa
  1. +1
    -0
      doc/ffmpeginfo.txt
  2. BIN
      doc/tools/FlvAnalyzer.exe
  3. BIN
      doc/tools/FlvAnalyzer.zip
  4. BIN
      doc/video/demo.flv
  5. BIN
      doc/video/demo.mp4
  6. +20
    -0
      src/JT1078.Flv.Test/JT1078.Flv.Test.csproj
  7. +29
    -0
      src/JT1078.Flv.Test/Metadata/Amf3MetadataTest.cs
  8. +2
    -2
      src/JT1078.Flv/Enums/AVCPacketType.cs
  9. +28
    -0
      src/JT1078.Flv/Enums/Amf3Type.cs
  10. +1
    -1
      src/JT1078.Flv/Enums/CodecId.cs
  11. +1
    -1
      src/JT1078.Flv/Enums/FrameType.cs
  12. +19
    -0
      src/JT1078.Flv/Extensions/Amf3Extensions.cs
  13. +129
    -0
      src/JT1078.Flv/Extensions/HexExtensions.cs
  14. +1
    -1
      src/JT1078.Flv/FlvBody.cs
  15. +11
    -4
      src/JT1078.Flv/FlvTags.cs
  16. +4
    -2
      src/JT1078.Flv/JT1078.Flv.csproj
  17. +2
    -1
      src/JT1078.Flv/MessagePack/FlvMessagePackWriter_Amf0.cs
  18. +19
    -3
      src/JT1078.Flv/MessagePack/FlvMessagePackWriter_Amf3.cs
  19. +55
    -10
      src/JT1078.Flv/MessagePack/FlvMessagePackWriter_Flv.cs
  20. +19
    -0
      src/JT1078.Flv/Metadata/Amf3.cs
  21. +27
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_Duration.cs
  22. +26
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_FileSize.cs
  23. +26
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_FrameRate.cs
  24. +26
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_Height.cs
  25. +26
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_VideoCodecId.cs
  26. +26
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_VideoDataRate.cs
  27. +26
    -0
      src/JT1078.Flv/Metadata/Amf3Metadata_Width.cs
  28. +15
    -0
      src/JT1078.Flv/Metadata/IAmf3Metadata.cs
  29. +3
    -3
      src/JT1078.Flv/Metadata/VideoTags.cs
  30. +6
    -5
      src/JT1078.Protocol/JT1078.Protocol.csproj
  31. +8
    -1
      src/JT1078.sln

+ 1
- 0
doc/ffmpeginfo.txt Näytä tiedosto

@@ -0,0 +1 @@
ffmpeg -i demo.mp4 -c copy -f flv -vcodec h264 -acodec aac demo_flv.flv

BIN
doc/tools/FlvAnalyzer.exe Näytä tiedosto


BIN
doc/tools/FlvAnalyzer.zip Näytä tiedosto


BIN
doc/video/demo.flv Näytä tiedosto


BIN
doc/video/demo.mp4 Näytä tiedosto


+ 20
- 0
src/JT1078.Flv.Test/JT1078.Flv.Test.csproj Näytä tiedosto

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\JT1078.Flv\JT1078.Flv.csproj" />
</ItemGroup>

</Project>

+ 29
- 0
src/JT1078.Flv.Test/Metadata/Amf3MetadataTest.cs Näytä tiedosto

@@ -0,0 +1,29 @@
using JT1078.Flv.Metadata;
using JT1078.Flv.Extensions;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace JT1078.Flv.Test.Metadata
{
public class Amf3MetadataTest
{
[Fact]
public void Amf3Metadata_Duration_Test_1_1()
{
Amf3Metadata_Duration amf3Metadata = new Amf3Metadata_Duration();
amf3Metadata.Value = 7.22100;
var hex=amf3Metadata.ToBuffer().ToArray().ToHexString();
Assert.Equal("00086475726174696F6E00401CE24DD2F1A9FC", hex);
}

[Fact]
public void Test1()
{
byte[] d1 = new byte[] { 0xFC, 0xA9, 0xF1, 0xD2, 0x4D, 0xE2, 0x1c, 0x40 };
var buffer = BitConverter.GetBytes(7.22100);
//flv需要倒序的
}
}
}

+ 2
- 2
src/JT1078.Flv/Enums/AVCPacketType.cs Näytä tiedosto

@@ -4,9 +4,9 @@ using System.Text;

namespace JT1078.Flv.Enums
{
public enum AvcPacketType
public enum AvcPacketType:byte
{
SequenceHeader=1,
SequenceHeader = 0,
Raw,
AVCEndSequence
}


+ 28
- 0
src/JT1078.Flv/Enums/Amf3Type.cs Näytä tiedosto

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Flv.Enums
{
public enum Amf3Type : byte
{
Undefined,
Null,
False,
True,
Integer,
Double,
String,
XmlDocument,
Date,
Array,
Object,
Xml,
ByteArray,
VectorInt,
VectorUInt,
VectorDouble,
VectorObject,
Dictionary
}
}

+ 1
- 1
src/JT1078.Flv/Enums/CodecId.cs Näytä tiedosto

@@ -12,6 +12,6 @@ namespace JT1078.Flv.Enums
Vp6,
Vp6WithAlpha,
ScreenVideo2,
Avc
AvcVideoPacke
}
}

+ 1
- 1
src/JT1078.Flv/Enums/FrameType.cs Näytä tiedosto

@@ -4,7 +4,7 @@ using System.Text;

namespace JT1078.Flv.Enums
{
public enum FrameType
public enum FrameType:byte
{
KeyFrame = 1,
InterFrame,


+ 19
- 0
src/JT1078.Flv/Extensions/Amf3Extensions.cs Näytä tiedosto

@@ -0,0 +1,19 @@
using JT1078.Flv.Metadata;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace JT1078.Flv.Extensions
{
public static class Amf3Extensions
{
public static void WriteDouble(this IAmf3Metadata metadata, Span<byte> value)
{
var flvBuffer = BitConverter.GetBytes((double)metadata.Value).AsSpan();
flvBuffer.Reverse();
flvBuffer.CopyTo(value);
}
}
}

+ 129
- 0
src/JT1078.Flv/Extensions/HexExtensions.cs Näytä tiedosto

@@ -0,0 +1,129 @@
using System;

namespace JT1078.Flv.Extensions
{
/// <summary>
///
/// ref:"www.codeproject.com/tips/447938/high-performance-csharp-byte-array-to-hex-string-t"
/// </summary>
public static partial class HexExtensions
{
public static string ToHexString(this byte[] source)
{
return HexUtil.DoHexDump(source, 0, source.Length).ToUpper();
}

public static int WriteHexStringLittle(byte[] bytes, int offset, string data, int len)
{
if (data == null) data = "";
data = data.Replace(" ", "");
int startIndex = 0;
if (data.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{
startIndex = 2;
}
int length = len;
if (length == -1)
{
length = (data.Length - startIndex) / 2;
}
int noOfZero = length * 2 + startIndex - data.Length;
if (noOfZero > 0)
{
data = data.Insert(startIndex, new string('0', noOfZero));
}
int byteIndex = 0;
while (startIndex < data.Length && byteIndex < length)
{
bytes[offset + byteIndex] = Convert.ToByte(data.Substring(startIndex, 2), 16);
startIndex += 2;
byteIndex++;
}
return length;
}

/// <summary>
/// 16进制字符串转16进制数组
/// </summary>
/// <param name="hexString"></param>
/// <param name="separator"></param>
/// <returns></returns>
public static byte[] ToHexBytes(this string hexString)
{
hexString = hexString.Replace(" ", "");
byte[] buf = new byte[hexString.Length / 2];
ReadOnlySpan<char> readOnlySpan = hexString.AsSpan();
for (int i = 0; i < hexString.Length; i++)
{
if (i % 2 == 0)
{
buf[i / 2] = Convert.ToByte(readOnlySpan.Slice(i, 2).ToString(), 16);
}
}
return buf;
}

public static string ReadHexStringLittle(ReadOnlySpan<byte> read, ref int offset, int len)
{
ReadOnlySpan<byte> source = read.Slice(offset, len);
string hex = HexUtil.DoHexDump(read, offset, len);
offset += len;
return hex;
}

/// <summary>
/// Copyright (c) Microsoft. All rights reserved.
/// Licensed under the MIT license. See LICENSE file in the project root for full license information.
/// <see cref="DotNetty.Buffers.ByteBufferUtil"/>
/// </summary>

}

public static class HexUtil
{
static readonly char[] HexdumpTable = new char[256 * 4];
static HexUtil()
{
char[] digits = "0123456789ABCDEF".ToCharArray();
for (int i = 0; i < 256; i++)
{
HexdumpTable[i << 1] = digits[(int)((uint)i >> 4 & 0x0F)];
HexdumpTable[(i << 1) + 1] = digits[i & 0x0F];
}
}

public static string DoHexDump(ReadOnlySpan<byte> buffer, int fromIndex, int length)
{
if (length == 0)
{
return "";
}
int endIndex = fromIndex + length;
var buf = new char[length << 1];
int srcIdx = fromIndex;
int dstIdx = 0;
for (; srcIdx < endIndex; srcIdx++, dstIdx += 2)
{
Array.Copy(HexdumpTable, buffer[srcIdx] << 1, buf, dstIdx, 2);
}
return new string(buf);
}

public static string DoHexDump(byte[] array, int fromIndex, int length)
{
if (length == 0)
{
return "";
}
int endIndex = fromIndex + length;
var buf = new char[length << 1];
int srcIdx = fromIndex;
int dstIdx = 0;
for (; srcIdx < endIndex; srcIdx++, dstIdx += 2)
{
Array.Copy(HexdumpTable, (array[srcIdx] & 0xFF) << 1, buf, dstIdx, 2);
}
return new string(buf);
}
}
}

+ 1
- 1
src/JT1078.Flv/FlvBody.cs Näytä tiedosto

@@ -10,6 +10,6 @@ namespace JT1078.Flv
/// 前一个tag的长度
/// </summary>
public uint PreviousTagSize { get; set; }
public FlvTag Tag { get; set; }
public FlvTags Tag { get; set; }
}
}

src/JT1078.Flv/FlvTag.cs → src/JT1078.Flv/FlvTags.cs Näytä tiedosto

@@ -1,8 +1,11 @@
namespace JT1078.Flv
using JT1078.Flv.Enums;
using JT1078.Flv.Metadata;

namespace JT1078.Flv
{
public class FlvTag
public class FlvTags
{
public byte Type { get; set; }
public TagType Type { get; set; }
/// <summary>
/// Tag Data部分大小
/// 3个字节
@@ -22,6 +25,10 @@
/// <summary>
/// 根据tag类型
/// </summary>
public byte[] TagData { get; set; }
public VideoTags VideoTagsData { get; set; }
/// <summary>
/// 根据tag类型
/// </summary>
public Amf3 DataTagsData { get; set; }
}
}

+ 4
- 2
src/JT1078.Flv/JT1078.Flv.csproj Näytä tiedosto

@@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>8.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>
</Project>

+ 2
- 1
src/JT1078.Flv/MessagePack/FlvMessagePackWriter_Amf0.cs Näytä tiedosto

@@ -7,13 +7,14 @@ namespace JT1078.Flv.MessagePack
ref partial struct FlvMessagePackWriter
{
private readonly static byte[] FixedAmf0Data = new byte[] { 0x6F, 0x6E, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61 };
public void WriteAmf0()
public void WriteAmf1()
{
var span = writer.Free;
span[0] = 0x02;
span[1] = 0;
span[2] = 10;
FixedAmf0Data.CopyTo(span.Slice(3));
writer.Advance(13);
}
}
}

+ 19
- 3
src/JT1078.Flv/MessagePack/FlvMessagePackWriter_Amf3.cs Näytä tiedosto

@@ -1,4 +1,5 @@
using System;
using JT1078.Flv.Metadata;
using System;
using System.Collections.Generic;
using System.Text;

@@ -6,7 +7,22 @@ namespace JT1078.Flv.MessagePack
{
ref partial struct FlvMessagePackWriter
{
public void WriteAmf3(Amf3 amf3)
{
WriteByte(amf3.DataType);
if(amf3.Amf3Metadatas!=null && amf3.Amf3Metadatas.Count > 0)
{
WriteInt32(amf3.Amf3Metadatas.Count);
foreach(var item in amf3.Amf3Metadatas)
{
//根据数据类型
WriteArray(item.ToBuffer());
}
}
else
{
WriteInt32(0);
}
}
}
}

+ 55
- 10
src/JT1078.Flv/MessagePack/FlvMessagePackWriter_Flv.cs Näytä tiedosto

@@ -1,4 +1,5 @@
using JT1078.Flv.Enums;
using JT1078.Flv.Metadata;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
@@ -17,40 +18,84 @@ namespace JT1078.Flv.MessagePack
}
}

public void WriteFlvTag(FlvTag tag)
public void WriteFlvTag(FlvTags tag)
{
WriteByte(tag.Type);
WriteByte((byte)tag.Type);
Skip(3, out int DataSizePosition);
WriteUInt24(tag.Timestamp);
WriteByte(tag.TimestampExt);
WriteUInt24(tag.StreamId);
switch ((TagType)tag.Type)
switch (tag.Type)
{
case TagType.Video:

//VideoTag
WriteVideoTags(tag.VideoTagsData);
break;
case TagType.ScriptData:
//DataTags
//flv Amf0
WriteAmf0();
WriteAmf1();
//flv Amf3
WriteAmf3(tag.DataTagsData);
break;
case TagType.Audio:
//VIDEODATA
break;
}
WriteInt32Return(GetCurrentPosition() - DataSizePosition - 3, DataSizePosition);
WriteInt24Return(GetCurrentPosition() - DataSizePosition - 3, DataSizePosition);
}

public void WriteUInt24(uint value)
{
BinaryPrimitives.WriteUInt32BigEndian(writer.Free, value);
var span = writer.Free;
span[0] = (byte)(value >> 16);
span[1] = (byte)(value >> 8);
span[2] = (byte)value;
writer.Advance(3);
}

public void WriteInt32Return(int value, int position)
public void WriteInt24Return(int value, int position)
{
var span = writer.Written.Slice(position, 3);
span[0] = (byte)(value >> 16);
span[1] = (byte)(value >> 8);
span[2] = (byte)value;
}

public void WriteVideoTags(VideoTags videoTags)
{
BinaryPrimitives.WriteInt32BigEndian(writer.Written.Slice(position, 3), value);
WriteByte((byte)((byte)videoTags.FrameType | (byte)videoTags.CodecId));
#warning 只处理H.264媒体数据
if (videoTags.CodecId== CodecId.AvcVideoPacke)
{
WriteAvcVideoPacke(videoTags.VideoData);
}
}

public void WriteAvcVideoPacke(AvcVideoPacke videoPacke)
{
WriteByte((byte)videoPacke.AvcPacketType);
if (videoPacke.AvcPacketType== AvcPacketType.SequenceHeader)
{
videoPacke.CompositionTime = 0;
WriteUInt24(videoPacke.CompositionTime);
//AVCDecoderConfigurationRecord
#warning AVCDecoderConfigurationRecord
WriteArray(videoPacke.Data);
}
else if(videoPacke.AvcPacketType == AvcPacketType.Raw)
{
WriteUInt24(videoPacke.CompositionTime);
#warning One or more NALUs
//One or more NALUs
WriteArray(videoPacke.Data);
}
else
{
videoPacke.CompositionTime = 0;
WriteUInt24(videoPacke.CompositionTime);
//Empty
}
}
}
}

+ 19
- 0
src/JT1078.Flv/Metadata/Amf3.cs Näytä tiedosto

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Flv.Metadata
{
public class Amf3
{
/// <summary>
/// AMF3数据类型
/// </summary>
public byte DataType { get; set; } = 0x08;
/// <summary>
/// 元素个数
/// </summary>
public uint Count { get; set; }
public List<IAmf3Metadata> Amf3Metadatas { get; set; }
}
}

+ 27
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_Duration.cs Näytä tiedosto

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;
using JT1078.Flv.Extensions;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_Duration : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "duration";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[2+8+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp,(ushort)b1.Length);
b1.CopyTo(tmp.Slice(2));
tmp[10] = DataType;
this.WriteDouble(tmp.Slice(11));
return tmp;
}
}
}

+ 26
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_FileSize.cs Näytä tiedosto

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_FileSize : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "filesize";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[2+8+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp, (ushort)b1.Length);
b1.CopyTo(tmp.Slice(4));
tmp[11] = DataType;
BinaryPrimitives.WriteInt64BigEndian(tmp.Slice(12), (long)Value);
return tmp;
}
}
}

+ 26
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_FrameRate.cs Näytä tiedosto

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_FrameRate : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "framerate";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[4+9+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp, (ushort)b1.Length);
b1.CopyTo(tmp.Slice(4));
tmp[11] = DataType;
BinaryPrimitives.WriteInt64BigEndian(tmp.Slice(12), (long)Value);
return tmp;
}
}
}

+ 26
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_Height.cs Näytä tiedosto

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_Height : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "height";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[4+6+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp, (ushort)b1.Length);
b1.CopyTo(tmp.Slice(3));
tmp[11] = DataType;
BinaryPrimitives.WriteInt64BigEndian(tmp.Slice(12), (long)Value);
return tmp;
}
}
}

+ 26
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_VideoCodecId.cs Näytä tiedosto

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_VideoCodecId : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "videocodecid";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[4+12+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp, (ushort)b1.Length);
b1.CopyTo(tmp.Slice(4));
tmp[11] = DataType;
BinaryPrimitives.WriteInt64BigEndian(tmp.Slice(12), (long)Value);
return tmp;
}
}
}

+ 26
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_VideoDataRate.cs Näytä tiedosto

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_VideoDataRate : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "videodatarate";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[4+13+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp, (ushort)b1.Length);
b1.CopyTo(tmp.Slice(4));
tmp[11] = DataType;
BinaryPrimitives.WriteInt64BigEndian(tmp.Slice(12), (long)Value);
return tmp;
}
}
}

+ 26
- 0
src/JT1078.Flv/Metadata/Amf3Metadata_Width.cs Näytä tiedosto

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Buffers.Binary;

namespace JT1078.Flv.Metadata
{
public class Amf3Metadata_Width : IAmf3Metadata
{
public ushort FieldNameLength { get; set; }
public string FieldName { get; set; } = "width";
public byte DataType { get; set; } = 0x00;
public object Value { get; set; }

public ReadOnlySpan<byte> ToBuffer()
{
Span<byte> tmp = new byte[4+5+1+8];
var b1 = Encoding.ASCII.GetBytes(FieldName);
BinaryPrimitives.WriteUInt16BigEndian(tmp, (ushort)b1.Length);
b1.CopyTo(tmp.Slice(3));
tmp[11] = DataType;
BinaryPrimitives.WriteInt64BigEndian(tmp.Slice(12), (long)Value);
return tmp;
}
}
}

+ 15
- 0
src/JT1078.Flv/Metadata/IAmf3Metadata.cs Näytä tiedosto

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Flv.Metadata
{
public interface IAmf3Metadata
{
ushort FieldNameLength { get; set; }
string FieldName { get; set; }
byte DataType { get; set; }
object Value { get; set; }
ReadOnlySpan<byte> ToBuffer();
}
}

src/JT1078.Flv/Metadata/VideoTag.cs → src/JT1078.Flv/Metadata/VideoTags.cs Näytä tiedosto

@@ -5,7 +5,7 @@ using System.Text;

namespace JT1078.Flv.Metadata
{
public class VideoTag
public class VideoTags
{
/// <summary>
/// 1: keyframe(for AVC, a seekable frame) —— 即H.264的IDR帧;
@@ -15,7 +15,7 @@ namespace JT1078.Flv.Metadata
/// <summary>
/// 当 CodecID 为 7 时,VideoData 为 AVCVIDEOPACKE,也即 H.264媒体数据
/// </summary>
public CodecId CodecId { get; set; }
public byte[] VideoData { get; set; }
public CodecId CodecId { get; set; } = CodecId.AvcVideoPacke;
public AvcVideoPacke VideoData { get; set; }
}
}

+ 6
- 5
src/JT1078.Protocol/JT1078.Protocol.csproj Näytä tiedosto

@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.3</LangVersion>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>8.0</LangVersion>
<Copyright>Copyright 2019.</Copyright>
<Authors>SmallChi(Koike)</Authors>
<PackageId>JT1078</PackageId>
@@ -14,16 +14,17 @@
<licenseUrl>https://github.com/SmallChi/JT1078/blob/master/LICENSE</licenseUrl>
<license>https://github.com/SmallChi/JT1078/blob/master/LICENSE</license>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<SignAssembly>false</SignAssembly>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>

<ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Pack>True</Pack>


+ 8
- 1
src/JT1078.sln Näytä tiedosto

@@ -27,7 +27,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol.Extensions.WebApiTest", "JT808.Protocol.Extensions.WebApiTest\JT808.Protocol.Extensions.WebApiTest.csproj", "{9DB37370-AC73-434B-9CE2-6659321858C8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT1078.Flv", "JT1078.Flv\JT1078.Flv.csproj", "{33E54FFC-7D91-42E5-9DC1-853738AB8980}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Flv", "JT1078.Flv\JT1078.Flv.csproj", "{33E54FFC-7D91-42E5-9DC1-853738AB8980}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT1078.Flv.Test", "JT1078.Flv.Test\JT1078.Flv.Test.csproj", "{D13FE092-1D11-4545-A322-9F06BCDAC0FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -71,6 +73,10 @@ Global
{33E54FFC-7D91-42E5-9DC1-853738AB8980}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33E54FFC-7D91-42E5-9DC1-853738AB8980}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33E54FFC-7D91-42E5-9DC1-853738AB8980}.Release|Any CPU.Build.0 = Release|Any CPU
{D13FE092-1D11-4545-A322-9F06BCDAC0FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D13FE092-1D11-4545-A322-9F06BCDAC0FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D13FE092-1D11-4545-A322-9F06BCDAC0FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D13FE092-1D11-4545-A322-9F06BCDAC0FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -80,6 +86,7 @@ Global
{E9FF2716-EF30-4180-879B-E8AB979ACFF3} = {0655AF84-E578-409F-AB0E-B47E0D2F6814}
{9ADD82F9-E0B2-4263-8573-151F673BB33F} = {0655AF84-E578-409F-AB0E-B47E0D2F6814}
{9DB37370-AC73-434B-9CE2-6659321858C8} = {0655AF84-E578-409F-AB0E-B47E0D2F6814}
{D13FE092-1D11-4545-A322-9F06BCDAC0FD} = {0655AF84-E578-409F-AB0E-B47E0D2F6814}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FAE1656D-226F-4B4B-8C33-615D7E632B26}


Ladataan…
Peruuta
Tallenna