@@ -249,28 +249,28 @@ namespace JT1078.Flv.Test | |||||
} | } | ||||
} | } | ||||
} | } | ||||
var tmp1 = h264NALULs.Where(w => w.NALUHeader.NalUnitType == 7).ToList(); | |||||
List<SPSInfo> tmpSpss = new List<SPSInfo>(); | |||||
List<ushort> times = new List<ushort>(); | |||||
List<int> type = new List<int>(); | |||||
foreach (var item in h264NALULs) | |||||
{ | |||||
//ExpGolombReader expGolombReader = new ExpGolombReader(item.RawData); | |||||
type.Add(item.NALUHeader.NalUnitType); | |||||
times.Add(item.LastFrameInterval); | |||||
//tmpSpss.Add(expGolombReader.ReadSPS()); | |||||
} | |||||
//fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); | |||||
//fileStream.Write(FlvEncoder.VideoFlvHeaderBuffer); | |||||
//var totalPage = (h264NALULs.Count + 10 - 1) / 10; | |||||
//for (var i = 0; i < totalPage; i++) | |||||
//var tmp1 = h264NALULs.Where(w => w.NALUHeader.NalUnitType == 7).ToList(); | |||||
//List<SPSInfo> tmpSpss = new List<SPSInfo>(); | |||||
//List<ushort> times = new List<ushort>(); | |||||
//List<int> type = new List<int>(); | |||||
//foreach (var item in h264NALULs) | |||||
//{ | //{ | ||||
// var flv2 = encoder.CreateFlvFrame(h264NALULs.Skip(i * 10).Take(10).ToList()); | |||||
// if (flv2.Length != 0) | |||||
// { | |||||
// fileStream.Write(flv2); | |||||
// } | |||||
// //ExpGolombReader expGolombReader = new ExpGolombReader(item.RawData); | |||||
// type.Add(item.NALUHeader.NalUnitType); | |||||
// times.Add(item.LastFrameInterval); | |||||
// //tmpSpss.Add(expGolombReader.ReadSPS()); | |||||
//} | //} | ||||
fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); | |||||
fileStream.Write(FlvEncoder.VideoFlvHeaderBuffer); | |||||
var totalPage = (h264NALULs.Count + 10 - 1) / 10; | |||||
for (var i = 0; i < totalPage; i++) | |||||
{ | |||||
var flv2 = encoder.CreateFlvFrame(h264NALULs.Skip(i * 10).Take(10).ToList()); | |||||
if (flv2.Length != 0) | |||||
{ | |||||
fileStream.Write(flv2); | |||||
} | |||||
} | |||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
@@ -14,7 +14,8 @@ | |||||
var player = document.getElementById('player'); | var player = document.getElementById('player'); | ||||
var flvPlayer = flvjs.createPlayer({ | var flvPlayer = flvjs.createPlayer({ | ||||
type: 'flv', | type: 'flv', | ||||
url: "jt1078_5.flv" | |||||
url: "ws://localhost:1818/jt1078live?token=" + Math.floor((Math.random() * 1000000) + 1) | |||||
//url: "jt1078_5.flv" | |||||
}); | }); | ||||
var width, height, flag; | var width, height, flag; | ||||
flvPlayer.attachMediaElement(player); | flvPlayer.attachMediaElement(player); | ||||
@@ -13,7 +13,7 @@ namespace JT1078.Flv | |||||
{ | { | ||||
public class FlvEncoder | public class FlvEncoder | ||||
{ | { | ||||
struct FlvFrameInfo | |||||
class FlvFrameInfo | |||||
{ | { | ||||
public uint PreviousTagSize { get; set;} | public uint PreviousTagSize { get; set;} | ||||
public uint LastFrameInterval { get; set; } | public uint LastFrameInterval { get; set; } | ||||
@@ -23,12 +23,14 @@ namespace JT1078.Flv | |||||
private static readonly ConcurrentDictionary<string, SPSInfo> VideoSPSDict; | private static readonly ConcurrentDictionary<string, SPSInfo> VideoSPSDict; | ||||
private static readonly Flv.H264.H264Decoder H264Decoder; | private static readonly Flv.H264.H264Decoder H264Decoder; | ||||
private static readonly ConcurrentDictionary<string, FlvFrameInfo> FlvFrameInfoDict; | private static readonly ConcurrentDictionary<string, FlvFrameInfo> FlvFrameInfoDict; | ||||
private static readonly ConcurrentDictionary<string, byte[]> FlvFirstFrameCache; | |||||
static FlvEncoder() | static FlvEncoder() | ||||
{ | { | ||||
FlvHeader VideoFlvHeader = new FlvHeader(true, false); | FlvHeader VideoFlvHeader = new FlvHeader(true, false); | ||||
VideoFlvHeaderBuffer = VideoFlvHeader.ToArray().ToArray(); | VideoFlvHeaderBuffer = VideoFlvHeader.ToArray().ToArray(); | ||||
VideoSPSDict = new ConcurrentDictionary<string, SPSInfo>(); | VideoSPSDict = new ConcurrentDictionary<string, SPSInfo>(); | ||||
FlvFrameInfoDict = new ConcurrentDictionary<string, FlvFrameInfo>(); | FlvFrameInfoDict = new ConcurrentDictionary<string, FlvFrameInfo>(); | ||||
FlvFirstFrameCache = new ConcurrentDictionary<string, byte[]>(); | |||||
H264Decoder = new Flv.H264.H264Decoder(); | H264Decoder = new Flv.H264.H264Decoder(); | ||||
} | } | ||||
@@ -174,17 +176,24 @@ namespace JT1078.Flv | |||||
{ | { | ||||
if(FlvFrameInfoDict.TryGetValue(key, out FlvFrameInfo flvFrameInfo)) | if(FlvFrameInfoDict.TryGetValue(key, out FlvFrameInfo flvFrameInfo)) | ||||
{ | { | ||||
CreateFlvKeyFrame(ref flvMessagePackWriter, key, sps.RawData, pps.RawData, spsInfo, flvFrameInfo.PreviousTagSize); | |||||
CreateFlvKeyFrame(ref flvMessagePackWriter, key, sps.RawData, pps.RawData, spsInfo, flvFrameInfo.PreviousTagSize); | |||||
FlvFirstFrameCache.TryRemove(key, out _); | |||||
FlvFirstFrameCache.TryAdd(key, flvMessagePackWriter.FlushAndGetArray()); | |||||
VideoSPSDict.TryUpdate(key, spsInfo, spsInfo); | VideoSPSDict.TryUpdate(key, spsInfo, spsInfo); | ||||
flvFrameInfo.LastFrameInterval = 0; | flvFrameInfo.LastFrameInterval = 0; | ||||
FlvFrameInfoDict.TryUpdate(key, flvFrameInfo, flvFrameInfo); | FlvFrameInfoDict.TryUpdate(key, flvFrameInfo, flvFrameInfo); | ||||
} | } | ||||
} | } | ||||
sps = null; | |||||
pps = null; | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
CreateFlvKeyFrame(ref flvMessagePackWriter, key, sps.RawData, pps.RawData, spsInfo, 0); | CreateFlvKeyFrame(ref flvMessagePackWriter, key, sps.RawData, pps.RawData, spsInfo, 0); | ||||
FlvFirstFrameCache.TryAdd(key, flvMessagePackWriter.FlushAndGetArray()); | |||||
VideoSPSDict.TryAdd(key, spsInfo); | VideoSPSDict.TryAdd(key, spsInfo); | ||||
sps = null; | |||||
pps = null; | |||||
} | } | ||||
} | } | ||||
//7 8 6 5 1 1 1 1 7 8 6 5 1 1 1 1 1 7 8 6 5 1 1 1 1 1 | //7 8 6 5 1 1 1 1 7 8 6 5 1 1 1 1 1 7 8 6 5 1 1 1 1 1 | ||||
@@ -225,5 +234,16 @@ namespace JT1078.Flv | |||||
FlvArrayPool.Return(buffer); | FlvArrayPool.Return(buffer); | ||||
} | } | ||||
} | } | ||||
public byte[] GetFlvFirstFrameByKey(string key) | |||||
{ | |||||
if(FlvFirstFrameCache.TryGetValue(key,out byte[] buffer)) | |||||
{ | |||||
return buffer; | |||||
} | |||||
else | |||||
{ | |||||
return null; | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -32,9 +32,21 @@ namespace JT808.Protocol.Extensions.WebApiTest | |||||
IJT808Config config = serviceProvider.GetRequiredService<IJT808Config>(); | IJT808Config config = serviceProvider.GetRequiredService<IJT808Config>(); | ||||
JT808Serializer JT808Serializer = config.GetSerializer(); | JT808Serializer JT808Serializer = config.GetSerializer(); | ||||
IJT808DotNettyWebApi JT808DotNettyWebApiClient = serviceProvider.GetRequiredService<IJT808DotNettyWebApi>(); | |||||
string terminalPhoneNo = ""; | string terminalPhoneNo = ""; | ||||
string serverIPAddress = "127.0.0.1"; | |||||
//创建子码流 | |||||
CreateSub(terminalPhoneNo, serverIPAddress, JT808Serializer, JT808DotNettyWebApiClient); | |||||
//创建主码流 | |||||
CreateMain(terminalPhoneNo, serverIPAddress, JT808Serializer, JT808DotNettyWebApiClient); | |||||
Console.ReadKey(); | |||||
} | |||||
public static void CreateSub(string terminalPhoneNo,string serverIPAddress,JT808Serializer JT808Serializer, IJT808DotNettyWebApi JT808DotNettyWebApiClient) | |||||
{ | |||||
JT808Package jT808Package = new JT808Package(); | JT808Package jT808Package = new JT808Package(); | ||||
JT808Header header = new JT808Header(); | JT808Header header = new JT808Header(); | ||||
header.MsgId = 0x9101; | header.MsgId = 0x9101; | ||||
@@ -42,10 +54,10 @@ namespace JT808.Protocol.Extensions.WebApiTest | |||||
header.TerminalPhoneNo = terminalPhoneNo; | header.TerminalPhoneNo = terminalPhoneNo; | ||||
jT808Package.Header = header; | jT808Package.Header = header; | ||||
JT808_0x9101 jT808_0X9101 = new JT808_0x9101(); | JT808_0x9101 jT808_0X9101 = new JT808_0x9101(); | ||||
jT808_0X9101.ServerIPAddress = "127.0.0.1"; | |||||
jT808_0X9101.ServerVideoChannelTcpPort = 1888; | |||||
jT808_0X9101.ServerIPAddress = serverIPAddress; | |||||
jT808_0X9101.ServerVideoChannelTcpPort = 1808; | |||||
jT808_0X9101.ServerVideoChannelUdpPort = 0; | jT808_0X9101.ServerVideoChannelUdpPort = 0; | ||||
jT808_0X9101.LogicalChannelNo = 1; | |||||
jT808_0X9101.LogicalChannelNo = 3; | |||||
jT808_0X9101.DataType = 1; | jT808_0X9101.DataType = 1; | ||||
jT808_0X9101.StreamType = 1; | jT808_0X9101.StreamType = 1; | ||||
jT808Package.Bodies = jT808_0X9101; | jT808Package.Bodies = jT808_0X9101; | ||||
@@ -53,39 +65,68 @@ namespace JT808.Protocol.Extensions.WebApiTest | |||||
var data = JT808Serializer.Serialize(jT808Package); | var data = JT808Serializer.Serialize(jT808Package); | ||||
Console.WriteLine(JsonConvert.SerializeObject(data.ToHexString())); | Console.WriteLine(JsonConvert.SerializeObject(data.ToHexString())); | ||||
IJT808DotNettyWebApi JT808DotNettyWebApiClient = serviceProvider.GetRequiredService<IJT808DotNettyWebApi>(); | |||||
var result = JT808DotNettyWebApiClient.UnificationTcpSend(new JT808UnificationSendRequestDto | var result = JT808DotNettyWebApiClient.UnificationTcpSend(new JT808UnificationSendRequestDto | ||||
{ | { | ||||
TerminalPhoneNo= terminalPhoneNo, | |||||
Data= data | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
Data = data | |||||
}).GetAwaiter().GetResult(); | |||||
Console.WriteLine(JsonConvert.SerializeObject(result)); | |||||
} | |||||
public static void CreateMain(string terminalPhoneNo, string serverIPAddress, JT808Serializer JT808Serializer, IJT808DotNettyWebApi JT808DotNettyWebApiClient) | |||||
{ | |||||
JT808Package jT808Package = new JT808Package(); | |||||
JT808Header header = new JT808Header(); | |||||
header.MsgId = 0x9101; | |||||
header.MsgNum = 2; | |||||
header.TerminalPhoneNo = terminalPhoneNo; | |||||
jT808Package.Header = header; | |||||
JT808_0x9101 jT808_0X9101 = new JT808_0x9101(); | |||||
jT808_0X9101.ServerIPAddress = serverIPAddress; | |||||
jT808_0X9101.ServerVideoChannelTcpPort = 1808; | |||||
jT808_0X9101.ServerVideoChannelUdpPort = 0; | |||||
jT808_0X9101.LogicalChannelNo = 3; | |||||
jT808_0X9101.DataType = 1; | |||||
jT808_0X9101.StreamType =0; | |||||
jT808Package.Bodies = jT808_0X9101; | |||||
var data = JT808Serializer.Serialize(jT808Package); | |||||
Console.WriteLine(JsonConvert.SerializeObject(data.ToHexString())); | |||||
var result = JT808DotNettyWebApiClient.UnificationTcpSend(new JT808UnificationSendRequestDto | |||||
{ | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
Data = data | |||||
}).GetAwaiter().GetResult(); | }).GetAwaiter().GetResult(); | ||||
Console.WriteLine(JsonConvert.SerializeObject(result)); | Console.WriteLine(JsonConvert.SerializeObject(result)); | ||||
} | |||||
//JT808Package jT808Package1 = new JT808Package(); | |||||
//JT808Header header1 = new JT808Header(); | |||||
//header1.MsgId = 0x9102; | |||||
//header1.MsgNum = 2; | |||||
//header1.TerminalPhoneNo = terminalPhoneNo; | |||||
//jT808Package1.Header = header; | |||||
//JT808_0x9102 jT808_0X9102 = new JT808_0x9102(); | |||||
//jT808_0X9102.LogicalChannelNo = 1; | |||||
//jT808_0X9102.ControlCmd = 1; | |||||
//jT808_0X9102.CloseAVData = 0; | |||||
//jT808_0X9102.SwitchStreamType = 0; | |||||
//jT808Package1.Bodies = jT808_0X9102; | |||||
//var data1 = JT808Serializer.Serialize(jT808Package1); | |||||
//Console.WriteLine(JsonConvert.SerializeObject(data1.ToHexString())); | |||||
//var result1 = JT808DotNettyWebApiClient.UnificationTcpSend(new JT808UnificationSendRequestDto | |||||
//{ | |||||
// TerminalPhoneNo = terminalPhoneNo, | |||||
// Data = data1 | |||||
//}).GetAwaiter().GetResult(); | |||||
//Console.WriteLine(JsonConvert.SerializeObject(result1)); | |||||
public static void Close(string terminalPhoneNo, JT808Serializer JT808Serializer, IJT808DotNettyWebApi JT808DotNettyWebApiClient) | |||||
{ | |||||
JT808Package jT808Package1 = new JT808Package(); | |||||
JT808Header header1 = new JT808Header(); | |||||
header1.MsgId = 0x9102; | |||||
header1.MsgNum = 3; | |||||
header1.TerminalPhoneNo = terminalPhoneNo; | |||||
jT808Package1.Header = header1; | |||||
JT808_0x9102 jT808_0X9102 = new JT808_0x9102(); | |||||
jT808_0X9102.LogicalChannelNo = 1; | |||||
jT808_0X9102.ControlCmd = 1; | |||||
jT808_0X9102.CloseAVData = 0; | |||||
jT808_0X9102.SwitchStreamType = 0; | |||||
jT808Package1.Bodies = jT808_0X9102; | |||||
var data1 = JT808Serializer.Serialize(jT808Package1); | |||||
Console.WriteLine(JsonConvert.SerializeObject(data1.ToHexString())); | |||||
Console.ReadKey(); | |||||
var result1 = JT808DotNettyWebApiClient.UnificationTcpSend(new JT808UnificationSendRequestDto | |||||
{ | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
Data = data1 | |||||
}).GetAwaiter().GetResult(); | |||||
Console.WriteLine(JsonConvert.SerializeObject(result1)); | |||||
} | } | ||||
} | } | ||||
} | } |