diff --git a/skyscraper8/HlsProxy.cs b/skyscraper8/HlsProxy.cs index 2d1a770..5f9bb96 100644 --- a/skyscraper8/HlsProxy.cs +++ b/skyscraper8/HlsProxy.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; @@ -18,6 +19,8 @@ namespace skyscraper8 _sourceDirectory = sourceDirectory; } + public bool DestructiveMode { get; set; } + public void Run() { if (!_sourceDirectory.Exists) @@ -61,6 +64,18 @@ namespace skyscraper8 process.StandardInput.BaseStream.Flush(); knownFiles.Add(fileInfos[i].Name); outputted = true; + if (DestructiveMode) + { + try + { + File.Delete(fileInfos[i].FullName); + logger.WarnFormat("Erased {0}", fileInfos[i].Name); + } + catch (Exception e) + { + logger.WarnFormat("Failed to Erase {0}", fileInfos[i].Name); + } + } break; } } diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index 01ee76d..a893481 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -39,7 +39,7 @@ namespace skyscraper5 class Program { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - private const int PUBLIC_RELEASE = 4; + private const int PUBLIC_RELEASE = 5; private static void IntegrationTest() { /*List ssdpDevices = SsdpClient.GetSsdpDevices(1000).ToList(); @@ -49,40 +49,11 @@ namespace skyscraper5 }*/ //"urn:ses-com:device:SatIPServer:1" - PluginManager pluginManager = PluginManager.GetInstance(); + /*PluginManager pluginManager = PluginManager.GetInstance(); StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance(); ObjectStorageFactory objectStorageFactory = storageConnectionManager.GetDefaultObjectStorageFactory(); - ObjectStorage objectStorage = objectStorageFactory.CreateObjectStorage(); - - SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, objectStorage); - Console.WriteLine(firstSatIpServer.GetIpAddress()); - - /*RtspClient rtspClient = new RtspClient("172.20.20.121", 554); - rtspClient.AutoReconnect = true; - RtspOptionsResponse options = rtspClient.GetOptions("/"); - string url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); - RtspDescribeResponse describe = rtspClient.GetDescribe(url); - SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); - - int rtcps = 0; - int rtps = 0; - - RtspSetupResponse setup = rtspClient.GetSetup(url); - setup.OnRtcpPacket += ((data, length) => - rtcps++); - setup.OnRtpPacket += (data, length) => - rtps++; - - RtspPlayResponse play = rtspClient.GetPlay(setup); - - Thread.Sleep(5000); - - rtspClient.GetTeardown(setup); - Console.WriteLine("{0} RTCPs",rtcps); - Console.WriteLine("{0} RTPs",rtps); - - Thread.Sleep(1000);*/ - + ObjectStorage objectStorage = objectStorageFactory.CreateObjectStorage();*/ + /*url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); describe = rtspClient.GetDescribe(url); sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); @@ -285,6 +256,22 @@ namespace skyscraper5 hlsproxy.Run(); return; } + + if (args[0].ToLowerInvariant().Equals("hlsproxy-destructive")) + { + DirectoryInfo di = new DirectoryInfo(args[1]); + HlsProxy hlsproxy = new HlsProxy(di); + hlsproxy.DestructiveMode = true; + hlsproxy.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("satip")) + { + QuickAndDirtySatIpClient qadsipc = new QuickAndDirtySatIpClient(args); + qadsipc.Run(); + return; + } } /*Passing passing = new Passing(); @@ -301,6 +288,7 @@ namespace skyscraper5 Console.WriteLine(); Console.WriteLine("Bonus feature:"); Console.WriteLine(".\\skyscraper8.exe hlsproxy \"C:\\path\\to\\hls\\files\\\" - to pipe a HLS stream from a local directory into VLC."); + Console.WriteLine(".\\skyscraper8.exe hlsproxy-destructive \"C:\\path\\to\\hls\\files\\\" - to pipe a HLS stream from a local directory into VLC and delete HLS segments afterwards. (be careful!)"); } private static void ProcessDirectory(DirectoryInfo di) diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index 35dcc33..faad090 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "skyscraper8": { "commandName": "Project", - "commandLineArgs": "\"Z:\\Persönliches\\Satellitescommunity\\incoming\"", + "commandLineArgs": "satip autodetect 1 V 11347 S2 22000", "remoteDebugEnabled": false }, "Container (Dockerfile)": { diff --git a/skyscraper8/QuickAndDirtySatIpClient.cs b/skyscraper8/QuickAndDirtySatIpClient.cs new file mode 100644 index 0000000..c9c6c0a --- /dev/null +++ b/skyscraper8/QuickAndDirtySatIpClient.cs @@ -0,0 +1,219 @@ +using log4net; +using skyscraper5.Skyscraper.IO.CrazycatStreamReader; +using skyscraper8.SatIp; +using skyscraper8.SatIp.RtspResponses; +using skyscraper8.SimpleServiceDiscoveryProtocol; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.Storage.Filesystem; +using skyscraper5.Skyscraper.Scraper.Storage.InMemory; +using skyscraper8.Skyscraper.Scraper.Storage; + +namespace skyscraper8 +{ + internal class QuickAndDirtySatIpClient + { + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + + public QuickAndDirtySatIpClient(string[] args) + { + if (args.Length == 1) + { + logger.Fatal("Hey, what's your SAT>IP Server's IP Address? You can also say \"autodetect\" here."); + return; + } + if (args[1].ToLowerInvariant().Contains("auto")) + { + ipAddress = AutodetectIPAddress(); + } + else + { + ipAddress = IPAddress.Parse(args[1]); + } + + if (args.Length == 2) + { + logger.Fatal("You didn't specify a DiSEqc setting. (Number between 1-4)"); + return; + } + diseqcNumber = Int32.Parse(args[2]); + + if (args.Length == 3) + { + logger.Fatal("You didn't specify a polarity. Use H or V."); + return; + } + polarity = args[3].ToUpperInvariant()[0]; + + if (args.Length == 4) + { + logger.Fatal("Please specify a frequency."); + return; + } + frequency = Int32.Parse(args[4]); + + if (args.Length == 5) + { + logger.Fatal("What DVB Standard do we have here? S or S2?"); + return; + } + isS2 = ParseDvbStandard(args[5]); + + if (args.Length == 6) + { + logger.Fatal("What's the symbol rate?"); + return; + } + symbolRate = Int32.Parse(args[6]); + } + + private IPAddress AutodetectIPAddress() + { + SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, null); + IPAddress ipAddress = firstSatIpServer.GetIpAddress(); + logger.InfoFormat("Found SAT>IP Server at {0}", ipAddress); + return ipAddress; + } + + private int symbolRate; + private bool isS2; + private int frequency; + private char polarity; + private int diseqcNumber; + private IPAddress ipAddress; + private RtspClient rtspClient; + public void Run() + { + rtspClient = new RtspClient(ipAddress, 554); + rtspClient.AutoReconnect = false; + Keepalive(); + DiSEqC_Opcode opcode = BuildDiseqcOpcode(); + string url = RtspClient.MakeUrl(opcode, frequency, isS2, symbolRate); + RtspDescribeResponse describe = rtspClient.GetDescribe(url); + SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); + + RtspSetupResponse setup = rtspClient.GetSetup(url); + setup.OnRtcpPacket += Setup_OnRtcpPacket; + setup.OnRtpPacket += Setup_OnRtpPacket; + + if (dataStorage == null) + dataStorage = new InMemoryScraperStorage(); + if (objectStorage == null) + objectStorage = new FilesystemStorage(new DirectoryInfo(".")); + context = new SkyscraperContext(new TsContext(), dataStorage, objectStorage); + context.EnableTimeout = true; + context.TimeoutSeconds = 10; + context.InitalizeFilterChain(); + + RtspPlayResponse play = rtspClient.GetPlay(setup); + + while (!context.IsAbortConditionMet()) + { + Thread.Sleep(2000); + Keepalive(url); + } + + rtspClient.GetTeardown(setup); + rtspClient.Dispose(); + } + + private byte[] buffer; + private ObjectStorage objectStorage; + private DataStorage dataStorage; + private SkyscraperContext context; + private void Setup_OnRtpPacket(byte[] data, int length) + { + if (buffer == null) + buffer = new byte[188]; + + for (int i = 12; i < length; i += 188) + { + Array.Clear(buffer); + Array.Copy(data, i, buffer, 0, 188); + context.IngestSinglePacket(buffer); + } + } + + private int rtcps; + private void Setup_OnRtcpPacket(byte[] data, int length) + { + //rtcps++; + } + + private DiSEqC_Opcode BuildDiseqcOpcode() + { + DiSEqC_Opcode opcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE; + switch (diseqcNumber) + { + case 1: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_A; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_A; + break; + case 2: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_A; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_B; + break; + case 3: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_B; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_A; + break; + case 4: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_B; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_B; + break; + default: + throw new ArgumentOutOfRangeException("Your DiSEqC position should be a number between 1 and 4."); + } + + switch (polarity) + { + case 'H': + opcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL; + break; + case 'V': + opcode |= DiSEqC_Opcode.DISEQC_VERTICAL; + break; + default: + throw new ArgumentException("The polarity should be H or V."); + } + + return opcode; + } + + private bool ParseDvbStandard(string standard) + { + standard = standard.ToUpperInvariant(); + if (standard.StartsWith("DVB")) + standard = standard.Substring(3); + if (standard.StartsWith("-")) + standard = standard.Substring(1); + + switch (standard) + { + case "S": + return false; + case "S2": + return true; + case "S2X": + return true; + default: + throw new ArgumentException(String.Format("I have no idea what kind of Standard {0} is supposed to be.", standard)); + } + } + + private void Keepalive(string url = "/") + { + RtspOptionsResponse options = rtspClient.GetOptions("/"); + if (options.RtspStatusCode != 200) + { + throw new RtspException(String.Format("Unexpected RTSP Status code. Wanted {0}, got {1}", 200, options.RtspStatusCode)); + } + } + } +} diff --git a/skyscraper8/SatIp/RtspClient.cs b/skyscraper8/SatIp/RtspClient.cs index 41cf7ed..64aef4e 100644 --- a/skyscraper8/SatIp/RtspClient.cs +++ b/skyscraper8/SatIp/RtspClient.cs @@ -20,9 +20,20 @@ namespace skyscraper8.SatIp public RtspClient(string ip, int port) { IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(ip), port); + ConstructStep2(ipEndPoint); + } + + public RtspClient(IPAddress ip, int port) + { + IPEndPoint ipEndPoint = new IPEndPoint(ip, port); + ConstructStep2(ipEndPoint); + } + + private void ConstructStep2(IPEndPoint ipEndPoint) + { this.TcpClient = new TcpClient(); this.TcpClient.Connect(ipEndPoint); - this.RootPath = string.Format("rtsp://{0}:{1}", ip, port); + this.RootPath = string.Format("rtsp://{0}:{1}", ipEndPoint.Address.ToString(), ipEndPoint.Port.ToString()); this.NetworkStream = TcpClient.GetStream(); this.BufferedStream = new BufferedStream(this.NetworkStream); this.StreamReader = new StreamReader(this.BufferedStream); diff --git a/skyscraper8/Skyscraper/Plugins/PluginManager.cs b/skyscraper8/Skyscraper/Plugins/PluginManager.cs index e76bfed..100d7d0 100644 --- a/skyscraper8/Skyscraper/Plugins/PluginManager.cs +++ b/skyscraper8/Skyscraper/Plugins/PluginManager.cs @@ -75,7 +75,7 @@ namespace skyscraper5.Skyscraper.Plugins } else { - logger.WarnFormat("{0} was not found. Create it using the UI!", iniFileInfo.FullName); + Debug.WriteLine(String.Format("{0} was not found. Create it using the UI!", iniFileInfo.FullName)); } } diff --git a/skyscraper8/bin/Debug/skyscraper5.ini b/skyscraper8/bin/Debug/skyscraper5.ini new file mode 100644 index 0000000..a06b98e --- /dev/null +++ b/skyscraper8/bin/Debug/skyscraper5.ini @@ -0,0 +1,22 @@ +[startup] +dataStorage=3 +objectStorage=1 + +[plugins] +postgresql=C:\devel\skyscraper8\DataTableStorages\skyscraper5.Data.PostgreSql\bin\Debug\net8.0\skyscraper5.Data.PostgreSql.dll +minio=C:\devel\skyscraper8\BlobStorages\skyscraper5.Data.Minio\bin\Debug\net8.0\skyscraper5.Data.Minio.dll +epgcollector=C:\devel\skyscraper8\PrivateDataSpecifiers\skyscraper8.EPGCollectorPort\bin\Debug\net8.0\skyscraper8.EPGCollectorPort.dll + +[objectStorage1] +Bucket=skyscraper5 +Secure=0 +SecretKey=12345678 +AccessKey=feyris-tan +Endpoint=172.20.20.3:9000 + +[dataStorage3] +Username=ft +Port=5432 +Password=welcometotheworld +Host=172.20.20.17 +Database=skyscraper5 \ No newline at end of file