Added options for SAT>IP Multicast Playout and building a date-ordered TS list to CSV.
This commit is contained in:
parent
8de4b56c6f
commit
03f194bd34
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"skyscraper8": {
|
"skyscraper8": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "satip-playout auto 1 V 12597 S2 45000 6970",
|
"commandLineArgs": "rotation-catalogue F:\\\\ F:\\\\rotate-us.csv",
|
||||||
"remoteDebugEnabled": false
|
"remoteDebugEnabled": false
|
||||||
},
|
},
|
||||||
"Container (Dockerfile)": {
|
"Container (Dockerfile)": {
|
||||||
|
|||||||
@ -1,79 +1,79 @@
|
|||||||
using log4net;
|
using log4net;
|
||||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
using skyscraper8.SatIp;
|
using skyscraper8.SatIp;
|
||||||
using skyscraper8.SatIp.RtspResponses;
|
using skyscraper8.SatIp.RtspResponses;
|
||||||
using skyscraper8.SimpleServiceDiscoveryProtocol;
|
using skyscraper8.SimpleServiceDiscoveryProtocol;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using skyscraper5.Mpeg2;
|
using skyscraper5.Mpeg2;
|
||||||
using skyscraper5.Skyscraper.Scraper;
|
using skyscraper5.Skyscraper.Scraper;
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage.Filesystem;
|
using skyscraper5.Skyscraper.Scraper.Storage.Filesystem;
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
|
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
|
||||||
using skyscraper8.Skyscraper.Scraper.Storage;
|
using skyscraper8.Skyscraper.Scraper.Storage;
|
||||||
|
|
||||||
namespace skyscraper8
|
namespace skyscraper8
|
||||||
{
|
{
|
||||||
internal class QuickAndDirtySatIpClient
|
internal class QuickAndDirtySatIpClient
|
||||||
{
|
{
|
||||||
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
||||||
private const bool ENABLE_TS_WRITER = true;
|
private const bool ENABLE_TS_WRITER = true;
|
||||||
|
|
||||||
public QuickAndDirtySatIpClient(string[] args)
|
public QuickAndDirtySatIpClient(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length == 1)
|
if (args.Length == 1)
|
||||||
{
|
{
|
||||||
logger.Fatal("Hey, what's your SAT>IP Server's IP Address? You can also say \"autodetect\" here.");
|
logger.Fatal("Hey, what's your SAT>IP Server's IP Address? You can also say \"autodetect\" here.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args[1].ToLowerInvariant().Contains("auto"))
|
if (args[1].ToLowerInvariant().Contains("auto"))
|
||||||
{
|
{
|
||||||
ipAddress = AutodetectIPAddress();
|
ipAddress = AutodetectIPAddress();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ipAddress = IPAddress.Parse(args[1]);
|
ipAddress = IPAddress.Parse(args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.Length == 2)
|
if (args.Length == 2)
|
||||||
{
|
{
|
||||||
logger.Fatal("You didn't specify a DiSEqc setting. (Number between 1-4)");
|
logger.Fatal("You didn't specify a DiSEqc setting. (Number between 1-4)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
diseqcNumber = Int32.Parse(args[2]);
|
diseqcNumber = Int32.Parse(args[2]);
|
||||||
|
|
||||||
if (args.Length == 3)
|
if (args.Length == 3)
|
||||||
{
|
{
|
||||||
logger.Fatal("You didn't specify a polarity. Use H or V.");
|
logger.Fatal("You didn't specify a polarity. Use H or V.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
polarity = args[3].ToUpperInvariant()[0];
|
polarity = args[3].ToUpperInvariant()[0];
|
||||||
|
|
||||||
if (args.Length == 4)
|
if (args.Length == 4)
|
||||||
{
|
{
|
||||||
logger.Fatal("Please specify a frequency.");
|
logger.Fatal("Please specify a frequency.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
frequency = Int32.Parse(args[4]);
|
frequency = Int32.Parse(args[4]);
|
||||||
|
|
||||||
if (args.Length == 5)
|
if (args.Length == 5)
|
||||||
{
|
{
|
||||||
logger.Fatal("What DVB Standard do we have here? S or S2?");
|
logger.Fatal("What DVB Standard do we have here? S or S2?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isS2 = ParseDvbStandard(args[5]);
|
isS2 = ParseDvbStandard(args[5]);
|
||||||
|
|
||||||
if (args.Length == 6)
|
if (args.Length == 6)
|
||||||
{
|
{
|
||||||
logger.Fatal("What's the symbol rate?");
|
logger.Fatal("What's the symbol rate?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
symbolRate = Int32.Parse(args[6]);
|
symbolRate = Int32.Parse(args[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPlayoutMode(string[] args)
|
public void SetPlayoutMode(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length == 7)
|
if (args.Length == 7)
|
||||||
@ -83,66 +83,79 @@ namespace skyscraper8
|
|||||||
}
|
}
|
||||||
destinationPort = int.Parse(args[7]);
|
destinationPort = int.Parse(args[7]);
|
||||||
playoutMode = true;
|
playoutMode = true;
|
||||||
}
|
if (args.Length == 10)
|
||||||
|
{
|
||||||
private IPAddress AutodetectIPAddress()
|
if (args[8].ToLowerInvariant().Equals("multicast"))
|
||||||
{
|
{
|
||||||
SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, null);
|
destinationIp = IPAddress.Parse(args[9]);
|
||||||
if (firstSatIpServer == null)
|
multicastMode = true;
|
||||||
{
|
}
|
||||||
logger.WarnFormat("Didn't find any SAT>IP servers.");
|
else
|
||||||
return null;
|
{
|
||||||
}
|
logger.FatalFormat("Don't know what {0} means.", args[8]);
|
||||||
IPAddress ipAddress = firstSatIpServer.GetIpAddress();
|
return;
|
||||||
logger.InfoFormat("Found SAT>IP Server at {0}", ipAddress);
|
}
|
||||||
return ipAddress;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int symbolRate;
|
private IPAddress AutodetectIPAddress()
|
||||||
private bool isS2;
|
{
|
||||||
private int frequency;
|
SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, null);
|
||||||
private char polarity;
|
if (firstSatIpServer == null)
|
||||||
private int diseqcNumber;
|
{
|
||||||
private IPAddress ipAddress;
|
logger.WarnFormat("Didn't find any SAT>IP servers.");
|
||||||
private RtspClient rtspClient;
|
return null;
|
||||||
public void Run()
|
}
|
||||||
{
|
IPAddress ipAddress = firstSatIpServer.GetIpAddress();
|
||||||
rtspClient = new RtspClient(ipAddress, 554);
|
logger.InfoFormat("Found SAT>IP Server at {0}", ipAddress);
|
||||||
rtspClient.AutoReconnect = false;
|
return ipAddress;
|
||||||
Keepalive();
|
}
|
||||||
DiSEqC_Opcode opcode = BuildDiseqcOpcode();
|
|
||||||
string url = RtspClient.MakeUrl(opcode, frequency, isS2, symbolRate, null, false);
|
private int symbolRate;
|
||||||
RtspDescribeResponse describe = rtspClient.GetDescribe(url);
|
private bool isS2;
|
||||||
SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol();
|
private int frequency;
|
||||||
|
private char polarity;
|
||||||
packetQueue = new Queue<byte[]>();
|
private int diseqcNumber;
|
||||||
RtspSetupResponse setup = rtspClient.GetSetup(url, destinationPort);
|
private IPAddress ipAddress;
|
||||||
if (setup.RtspStatusCode == 404)
|
private RtspClient rtspClient;
|
||||||
{
|
public void Run()
|
||||||
logger.Fatal("Your SAT>IP server doesn't have a tuner available that can talk to the requested frequency.");
|
{
|
||||||
return;
|
rtspClient = new RtspClient(ipAddress, 554);
|
||||||
}
|
rtspClient.AutoReconnect = false;
|
||||||
setup.OnRtcpPacket += Setup_OnRtcpPacket;
|
Keepalive();
|
||||||
setup.OnRtpPacket += Setup_OnRtpPacket;
|
DiSEqC_Opcode opcode = BuildDiseqcOpcode();
|
||||||
|
string url = RtspClient.MakeUrl(opcode, frequency, isS2, symbolRate, null, false);
|
||||||
if (dataStorage == null)
|
RtspDescribeResponse describe = rtspClient.GetDescribe(url);
|
||||||
dataStorage = new InMemoryScraperStorage();
|
SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol();
|
||||||
if (objectStorage == null)
|
|
||||||
objectStorage = new FilesystemStorage(new DirectoryInfo("."));
|
packetQueue = new Queue<byte[]>();
|
||||||
|
RtspSetupResponse setup = rtspClient.GetSetup(url, destinationPort, multicastMode, destinationIp);
|
||||||
|
if (setup.RtspStatusCode == 404)
|
||||||
|
{
|
||||||
|
logger.Fatal("Your SAT>IP server doesn't have a tuner available that can talk to the requested frequency.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setup.OnRtcpPacket += Setup_OnRtcpPacket;
|
||||||
|
setup.OnRtpPacket += Setup_OnRtpPacket;
|
||||||
|
|
||||||
|
if (dataStorage == null)
|
||||||
|
dataStorage = new InMemoryScraperStorage();
|
||||||
|
if (objectStorage == null)
|
||||||
|
objectStorage = new FilesystemStorage(new DirectoryInfo("."));
|
||||||
if (!playoutMode)
|
if (!playoutMode)
|
||||||
{
|
{
|
||||||
context = new SkyscraperContext(new TsContext(), dataStorage, objectStorage);
|
context = new SkyscraperContext(new TsContext(), dataStorage, objectStorage);
|
||||||
context.EnableTimeout = true;
|
context.EnableTimeout = true;
|
||||||
context.TimeoutSeconds = 60;
|
context.TimeoutSeconds = 60;
|
||||||
context.InitalizeFilterChain();
|
context.InitalizeFilterChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
RtspPlayResponse play = rtspClient.GetPlay(setup);
|
RtspPlayResponse play = rtspClient.GetPlay(setup);
|
||||||
DateTime lastTimestamp = DateTime.Now;
|
DateTime lastTimestamp = DateTime.Now;
|
||||||
bool initMessagePrinted = false;
|
bool initMessagePrinted = false;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (playoutMode)
|
if (playoutMode)
|
||||||
{
|
{
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
@ -152,8 +165,8 @@ namespace skyscraper8
|
|||||||
logger.InfoFormat("Began SAT>IP playout to port {0}", destinationPort);
|
logger.InfoFormat("Began SAT>IP playout to port {0}", destinationPort);
|
||||||
initMessagePrinted = true;
|
initMessagePrinted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (packetQueue.Count >= 1)
|
if (packetQueue.Count >= 1)
|
||||||
{
|
{
|
||||||
@ -181,135 +194,136 @@ namespace skyscraper8
|
|||||||
{
|
{
|
||||||
Keepalive(url);
|
Keepalive(url);
|
||||||
lastTimestamp = DateTime.Now;
|
lastTimestamp = DateTime.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtspClient.GetTeardown(setup);
|
rtspClient.GetTeardown(setup);
|
||||||
rtspClient.Dispose();
|
rtspClient.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileStream fs;
|
private FileStream fs;
|
||||||
private uint stuffingBytes;
|
private uint stuffingBytes;
|
||||||
private Queue<byte[]> packetQueue;
|
private Queue<byte[]> packetQueue;
|
||||||
private ObjectStorage objectStorage;
|
private ObjectStorage objectStorage;
|
||||||
private DataStorage dataStorage;
|
private DataStorage dataStorage;
|
||||||
private SkyscraperContext context;
|
private SkyscraperContext context;
|
||||||
private void Setup_OnRtpPacket(byte[] data, int length)
|
private void Setup_OnRtpPacket(byte[] data, int length)
|
||||||
{
|
{
|
||||||
for (int i = 12; i < length; i += 1)
|
for (int i = 12; i < length; i += 1)
|
||||||
{
|
{
|
||||||
if (data[i] == 'G')
|
if (data[i] == 'G')
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[188];
|
byte[] buffer = new byte[188];
|
||||||
Array.Copy(data, i, buffer, 0, 188);
|
Array.Copy(data, i, buffer, 0, 188);
|
||||||
lock (packetQueue)
|
lock (packetQueue)
|
||||||
{
|
{
|
||||||
packetQueue.Enqueue(buffer);
|
packetQueue.Enqueue(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
DumpPacket(buffer);
|
DumpPacket(buffer);
|
||||||
i += 187;
|
i += 187;
|
||||||
}
|
}
|
||||||
else if (data[i] == 0xff)
|
else if (data[i] == 0xff)
|
||||||
{
|
{
|
||||||
stuffingBytes++;
|
stuffingBytes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DumpPacket(byte[] buffer)
|
private void DumpPacket(byte[] buffer)
|
||||||
{
|
{
|
||||||
if (!ENABLE_TS_WRITER)
|
if (!ENABLE_TS_WRITER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fs == null)
|
if (fs == null)
|
||||||
{
|
{
|
||||||
string fname = String.Format("{0}.ts", DateTime.Now.Ticks);
|
string fname = String.Format("{0}.ts", DateTime.Now.Ticks);
|
||||||
fs = File.OpenWrite(fname);
|
fs = File.OpenWrite(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.Write(buffer, 0, buffer.Length);
|
fs.Write(buffer, 0, buffer.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int rtcps;
|
private int rtcps;
|
||||||
private IPAddress destinationIp;
|
private IPAddress destinationIp;
|
||||||
private int destinationPort;
|
private int destinationPort;
|
||||||
private bool playoutMode;
|
private bool playoutMode;
|
||||||
|
private bool multicastMode;
|
||||||
|
|
||||||
private void Setup_OnRtcpPacket(byte[] data, int length)
|
private void Setup_OnRtcpPacket(byte[] data, int length)
|
||||||
{
|
{
|
||||||
//rtcps++;
|
//rtcps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiSEqC_Opcode BuildDiseqcOpcode()
|
private DiSEqC_Opcode BuildDiseqcOpcode()
|
||||||
{
|
{
|
||||||
DiSEqC_Opcode opcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE;
|
DiSEqC_Opcode opcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE;
|
||||||
switch (diseqcNumber)
|
switch (diseqcNumber)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
opcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
opcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
opcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
opcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
opcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
opcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
opcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
opcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException("Your DiSEqC position should be a number between 1 and 4.");
|
throw new ArgumentOutOfRangeException("Your DiSEqC position should be a number between 1 and 4.");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (polarity)
|
switch (polarity)
|
||||||
{
|
{
|
||||||
case 'H':
|
case 'H':
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL;
|
opcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
opcode |= DiSEqC_Opcode.DISEQC_VERTICAL;
|
opcode |= DiSEqC_Opcode.DISEQC_VERTICAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("The polarity should be H or V.");
|
throw new ArgumentException("The polarity should be H or V.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return opcode;
|
return opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ParseDvbStandard(string standard)
|
private bool ParseDvbStandard(string standard)
|
||||||
{
|
{
|
||||||
standard = standard.ToUpperInvariant();
|
standard = standard.ToUpperInvariant();
|
||||||
if (standard.StartsWith("DVB"))
|
if (standard.StartsWith("DVB"))
|
||||||
standard = standard.Substring(3);
|
standard = standard.Substring(3);
|
||||||
if (standard.StartsWith("-"))
|
if (standard.StartsWith("-"))
|
||||||
standard = standard.Substring(1);
|
standard = standard.Substring(1);
|
||||||
|
|
||||||
switch (standard)
|
switch (standard)
|
||||||
{
|
{
|
||||||
case "S":
|
case "S":
|
||||||
return false;
|
return false;
|
||||||
case "S2":
|
case "S2":
|
||||||
return true;
|
return true;
|
||||||
case "S2X":
|
case "S2X":
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException(String.Format("I have no idea what kind of Standard {0} is supposed to be.", standard));
|
throw new ArgumentException(String.Format("I have no idea what kind of Standard {0} is supposed to be.", standard));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Keepalive(string url = "/")
|
private void Keepalive(string url = "/")
|
||||||
{
|
{
|
||||||
RtspOptionsResponse options = rtspClient.GetOptions("/");
|
RtspOptionsResponse options = rtspClient.GetOptions("/");
|
||||||
if (options.RtspStatusCode != 200)
|
if (options.RtspStatusCode != 200)
|
||||||
{
|
{
|
||||||
throw new RtspException(String.Format("Unexpected RTSP Status code. Wanted {0}, got {1}", 200, options.RtspStatusCode));
|
throw new RtspException(String.Format("Unexpected RTSP Status code. Wanted {0}, got {1}", 200, options.RtspStatusCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,7 +99,7 @@ namespace skyscraper8.SatIp
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RtspSetupResponse GetSetup(string url, int destinationPort = 0)
|
public RtspSetupResponse GetSetup(string url, int destinationPort = 0, bool multicastMode = false, IPAddress multicastIp = null)
|
||||||
{
|
{
|
||||||
RtspSetupRequest request = new RtspSetupRequest();
|
RtspSetupRequest request = new RtspSetupRequest();
|
||||||
request.RequestPath = url;
|
request.RequestPath = url;
|
||||||
@ -123,7 +123,14 @@ namespace skyscraper8.SatIp
|
|||||||
rtcpSocket.Bind(new IPEndPoint(ListenIp, 0));
|
rtcpSocket.Bind(new IPEndPoint(ListenIp, 0));
|
||||||
int rtcpPort = GetPortFromEndPoint(rtcpSocket.LocalEndPoint);
|
int rtcpPort = GetPortFromEndPoint(rtcpSocket.LocalEndPoint);
|
||||||
|
|
||||||
request.SetRtpAvpUnicast(rtpPort, rtcpPort);
|
if (multicastMode && multicastIp != null)
|
||||||
|
{
|
||||||
|
request.SetRtpAvpMulticast(multicastIp, rtpPort, rtcpPort);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.SetRtpAvpUnicast(rtpPort, rtcpPort);
|
||||||
|
}
|
||||||
|
|
||||||
RtspResponseHeader response = GetResponse(request.ListHeaders(RootPath));
|
RtspResponseHeader response = GetResponse(request.ListHeaders(RootPath));
|
||||||
RtspSetupResponse setupResponse = new RtspSetupResponse(response);
|
RtspSetupResponse setupResponse = new RtspSetupResponse(response);
|
||||||
|
|||||||
@ -1,57 +1,63 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
namespace skyscraper8.SatIp.RtspRequests
|
|
||||||
{
|
namespace skyscraper8.SatIp.RtspRequests
|
||||||
internal class RtspSetupRequest : RtspRequest
|
{
|
||||||
{
|
internal class RtspSetupRequest : RtspRequest
|
||||||
public RtspSetupRequest() : base("SETUP")
|
{
|
||||||
{
|
public RtspSetupRequest() : base("SETUP")
|
||||||
}
|
{
|
||||||
|
}
|
||||||
public uint CSeq
|
|
||||||
{
|
public uint CSeq
|
||||||
set
|
{
|
||||||
{
|
set
|
||||||
base.args["CSeq"] = Convert.ToString(value);
|
{
|
||||||
}
|
base.args["CSeq"] = Convert.ToString(value);
|
||||||
get
|
}
|
||||||
{
|
get
|
||||||
return uint.Parse(base.args["CSeq"]);
|
{
|
||||||
}
|
return uint.Parse(base.args["CSeq"]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public string UserAgent
|
|
||||||
{
|
public string UserAgent
|
||||||
set
|
{
|
||||||
{
|
set
|
||||||
base.args["User-Agent"] = value;
|
{
|
||||||
}
|
base.args["User-Agent"] = value;
|
||||||
get
|
}
|
||||||
{
|
get
|
||||||
return base.args["User-Agent"];
|
{
|
||||||
}
|
return base.args["User-Agent"];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public string Transport
|
|
||||||
{
|
public string Transport
|
||||||
set
|
{
|
||||||
{
|
set
|
||||||
base.args["Transport"] = value;
|
{
|
||||||
}
|
base.args["Transport"] = value;
|
||||||
get
|
}
|
||||||
{
|
get
|
||||||
return base.args["Transport"];
|
{
|
||||||
}
|
return base.args["Transport"];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public void SetRtpAvpUnicast(int rtpPort, int rtcpPort)
|
|
||||||
{
|
public void SetRtpAvpUnicast(int rtpPort, int rtcpPort)
|
||||||
Transport = String.Format("RTP/AVP;unicast;client_port={0}-{1}", rtpPort, rtcpPort);
|
{
|
||||||
}
|
Transport = String.Format("RTP/AVP;unicast;client_port={0}-{1}", rtpPort, rtcpPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public void SetRtpAvpMulticast(IPAddress targetIp, int rtpPort, int rtcpPort)
|
||||||
|
{
|
||||||
|
Transport = String.Format("RTP/AVP;multicast;destination={2};port={0}-{1}", rtpPort, rtcpPort, targetIp.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace skyscraper5.Skyscraper.IO.TunerInterface
|
|||||||
{
|
{
|
||||||
[SkyscraperPlugin]
|
[SkyscraperPlugin]
|
||||||
[TunerFactoryId(2,"skyscraper5 Remote Stream Reader")]
|
[TunerFactoryId(2,"skyscraper5 Remote Stream Reader")]
|
||||||
internal class RemoteStreamReaderTunerFactory : ITunerFactory
|
public class RemoteStreamReaderTunerFactory : ITunerFactory
|
||||||
{
|
{
|
||||||
public string Hostname { get; set; }
|
public string Hostname { get; set; }
|
||||||
|
|
||||||
|
|||||||
112
skyscraper8/Skyscraper/TsRotationToCsv.cs
Normal file
112
skyscraper8/Skyscraper/TsRotationToCsv.cs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
using log4net;
|
||||||
|
using log4net.Repository.Hierarchy;
|
||||||
|
using skyscraper5.Docsis.MacManagement;
|
||||||
|
using skyscraper5.Skyscraper;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper
|
||||||
|
{
|
||||||
|
internal class TsRotationToCsv
|
||||||
|
{
|
||||||
|
public DirectoryInfo SourceDir { get; set; }
|
||||||
|
public FileInfo DestinationCsv { get; set; }
|
||||||
|
|
||||||
|
private List<FileInfo> files;
|
||||||
|
private ILog logger;
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
logger = LogManager.GetLogger(typeof(TsRotationToCsv));
|
||||||
|
files = new List<FileInfo>();
|
||||||
|
ScrapeDirectory(SourceDir);
|
||||||
|
files.Sort(new FileInfoComparerByDate(logger));
|
||||||
|
DumpCsv();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DumpCsv()
|
||||||
|
{
|
||||||
|
StreamWriter sw = new StreamWriter(DestinationCsv.FullName);
|
||||||
|
foreach (FileInfo file in files)
|
||||||
|
{
|
||||||
|
sw.WriteLine(String.Format("\"{0}\";{1};{2}", file.FullName, file.Length, file.LastWriteTime));
|
||||||
|
}
|
||||||
|
sw.Flush();
|
||||||
|
sw.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ScrapeDirectory(DirectoryInfo di)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (FileSystemInfo fsi in di.GetFileSystemInfos())
|
||||||
|
{
|
||||||
|
switch (fsi)
|
||||||
|
{
|
||||||
|
case FileInfo fi:
|
||||||
|
if (fi.Extension.ToLowerInvariant().Equals(".ts"))
|
||||||
|
{
|
||||||
|
files.Add(fi);
|
||||||
|
if (files.Count % 100 == 0)
|
||||||
|
logger.InfoFormat("Listed {0} files.", files.Count);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DirectoryInfo subdirectory:
|
||||||
|
ScrapeDirectory(subdirectory);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(di.GetType().Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.WarnFormat(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FileInfoComparerByDate : Comparer<FileInfo>
|
||||||
|
{
|
||||||
|
private ILog logger;
|
||||||
|
private int ups, downs, stands;
|
||||||
|
|
||||||
|
public FileInfoComparerByDate(ILog logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Compare(FileInfo? x, FileInfo? y)
|
||||||
|
{
|
||||||
|
long xTime = x.LastWriteTime.ToUnixTime();
|
||||||
|
long yTime = y.LastWriteTime.ToUnixTime();
|
||||||
|
|
||||||
|
int ops;
|
||||||
|
int v = xTime.CompareTo(yTime);
|
||||||
|
switch(v)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
ups++;
|
||||||
|
ops = ups;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
stands++;
|
||||||
|
ops = stands;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
downs++;
|
||||||
|
ops = downs;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(v.ToString());
|
||||||
|
}
|
||||||
|
if (ops % 1000 == 0)
|
||||||
|
{
|
||||||
|
logger.InfoFormat("Sort progress: {0} up, {1} down, {2} stand.", ups, downs, stands);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user