Skip to content

Commit

Permalink
Reading SDT, PAT
Browse files Browse the repository at this point in the history
  • Loading branch information
nilaoda committed Nov 13, 2021
1 parent 1afadb7 commit 32b1d4b
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
85 changes: 84 additions & 1 deletion RtspRecorder/RTSPClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ internal class RTSPClient
public string OutName { get; set; }
public int RecDurLimit { get; set; } = 0;
private TcpClient client;
private string title = "";
private string programId = "";
private string serviceProvider = "";
private string serviceName = "";

private RTSPClient()
{
Expand Down Expand Up @@ -62,6 +66,14 @@ private void LogResp(object text)
Console.WriteLine();
}

private void LogTsInfo(object text)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(text);
Console.ResetColor();
Console.WriteLine();
}

public void Connect()
{
if (client != null && client.Connected)
Expand Down Expand Up @@ -96,7 +108,7 @@ private void StartTimer()
var size = Util.FormatFileSize(streamSize);
if (streamSize != streamSizeLast)
{
if (!StdOut) Console.Write("\rReceiving... [" + Util.FormatTime(recCount) + $"] [{size}]" + "".PadRight(6));
if (!StdOut) Console.Write("\rReceiving... " + (string.IsNullOrEmpty(this.title) ? "" : $"[{this.title}] ") + "[" + Util.FormatTime(recCount) + $"] [{size}]" + "".PadRight(6));
streamSizeLast = streamSize;
}
else
Expand Down Expand Up @@ -136,6 +148,10 @@ public void DoWork()
{
this.url = Regex.Match(resp2str, "Content-Base: (.*)").Groups[1].Value.Trim();
}
if (Regex.IsMatch(resp2str, "s=(.*)"))
{
this.title = Regex.Match(resp2str, "s=(.*)").Groups[1].Value.Trim();
}


//3.SETUP
Expand Down Expand Up @@ -184,6 +200,7 @@ public void DoWork()
* | $ | id | Length |
* -------------------
*/
var infoBuffer = new List<byte>(188 * 5000); //5000个分包中解析信息,没有就算了
while (true && !stopFlag)
{
if (reader.ReadByte() == 0x24) //遇到4字节头
Expand All @@ -196,6 +213,20 @@ public void DoWork()
Array.Reverse(arr);
int length = BitConverter.ToUInt16(arr, 0);
var data = reader.ReadBytes(length); //TS data
if (infoBuffer.Count < 188 * 5000)
{
infoBuffer.AddRange(data);
}
else if (this.programId == "")
{
this.ParseTsInfo(infoBuffer.ToArray()); //Parse Info
var info = $"Program {this.programId}"
+ ((!string.IsNullOrEmpty(this.serviceName) || !string.IsNullOrEmpty(this.serviceProvider)) ? "\r\n Metadata:" : "")
+ (!string.IsNullOrEmpty(this.serviceName) ? $"\r\n service_name : {this.serviceName}" : "")
+ (!string.IsNullOrEmpty(this.serviceProvider) ? $"\r\n service_provider: {this.serviceProvider}" : "");
if (this.programId != "") LogTsInfo(info);
else infoBuffer.Clear();
}
bufferWriter.Write(data);
streamSize += data.Length;
}
Expand All @@ -204,6 +235,58 @@ public void DoWork()
bufferWriter.Flush();
}

/// <summary>
/// Parsing SDT and PAT
// Reference: https://en.wikipedia.org/wiki/MPEG_transport_stream
// https://en.wikipedia.org/wiki/Service_Description_Table
// https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.03.01_60/en_300468v010301p.pdf
/// </summary>
private void ParseTsInfo(byte[] data)
{
UInt16 ConvertToUint16(IEnumerable<byte> bytes)
{
if (BitConverter.IsLittleEndian)
bytes = bytes.Reverse();
return BitConverter.ToUInt16(bytes.ToArray());
}

for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0x47 && (i + 188) < data.Length && data[i + 188] == 0x47)
{
var tsData = data.Skip(i).Take(188);
var tsHeaderInt = BitConverter.ToUInt32(BitConverter.IsLittleEndian ? tsData.Take(4).Reverse().ToArray() : tsData.Take(4).ToArray(), 0);
var pid = (tsHeaderInt & 0x1fff00) >> 8;
var tsPayload = tsData.Skip(4);
//PAT
if (pid == 0x0000)
{
this.programId = ConvertToUint16(tsPayload.Skip(9).Take(2)).ToString();
}
//SDT, BAT, ST
else if (pid == 0x0011)
{
var tableId = (int)tsPayload.Skip(1).First();
//Current TS Info
if (tableId == 0x42)
{
var sectionLength = ConvertToUint16(tsPayload.Skip(2).Take(2)) & 0xfff;
var sectionData = tsPayload.Skip(4).Take(sectionLength);
var dscripData = sectionData.Skip(8);
var descriptorsLoopLength = (ConvertToUint16(dscripData.Skip(3).Take(2))) & 0xfff;
var descriptorsData = dscripData.Skip(5).Take(descriptorsLoopLength);
var serviceProviderLength = (int)descriptorsData.Skip(3).First();
this.serviceProvider = Encoding.UTF8.GetString(descriptorsData.Skip(4).Take(serviceProviderLength).ToArray());
var serviceNameLength = (int)descriptorsData.Skip(4 + serviceProviderLength).First();
this.serviceName = Encoding.UTF8.GetString(descriptorsData.Skip(5 + serviceProviderLength).Take(serviceNameLength).ToArray());
}
}
if (this.programId != "" && (this.serviceName != "" || this.serviceProvider != ""))
break;
}
}
}

public void Close()
{
if (client.Connected)
Expand Down
2 changes: 1 addition & 1 deletion RtspRecorder/RtspRecorder.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>1.1.0</Version>
<Version>1.2.0</Version>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down

0 comments on commit 32b1d4b

Please sign in to comment.