diff --git a/skyscraper8/Isdb/IsdbException.cs b/skyscraper8/Isdb/IsdbException.cs new file mode 100644 index 0000000..f1f3f7f --- /dev/null +++ b/skyscraper8/Isdb/IsdbException.cs @@ -0,0 +1,18 @@ +using skyscraper5; + +namespace skyscraper8.Isdb; + +public class IsdbException : SkyscraperException +{ + public IsdbException() + { + } + + public IsdbException(string message) : base(message) + { + } + + public IsdbException(string message, Exception inner) : base(message, inner) + { + } +} \ No newline at end of file diff --git a/skyscraper8/Isdb/Matenro.cs b/skyscraper8/Isdb/Matenro.cs index 5fa2c99..2fd4fd4 100644 --- a/skyscraper8/Isdb/Matenro.cs +++ b/skyscraper8/Isdb/Matenro.cs @@ -26,6 +26,7 @@ public class Matenro : IPatEventHandler, ICatEventHandler, IBatEventHandler, ISd private ILog logger; private ushort? _transportStreamId; + private ushort? _networkId; private ushort? _networkPid; private LitParser _litParser; private ErtParser _ertParser; @@ -167,11 +168,65 @@ public class Matenro : IPatEventHandler, ICatEventHandler, IBatEventHandler, ISd throw new NotImplementedException(); } + private List storedPmts; public void PmtEvent(IsdbPmt result, int sourcePid) { + long hash = result.PcrPid; + hash <<= 16; + hash += result.ProgramNumber; + if (_networkId.HasValue && _transportStreamId.HasValue) + { + if (storedPmts == null) + storedPmts = new List(); + if (!storedPmts.Contains(hash)) + { + bool inserted = false; + if (DataStorage.TestForIsdbPmt(_networkId.Value, _transportStreamId.Value, result.ProgramNumber)) + { + DataStorage.InsertIsdbPmt(_networkId.Value, _transportStreamId.Value, result); + inserted = true; + } + storedPmts.Add(hash); + logger.InfoFormat("Got PMT on PID 0x{0:X4}. Program Number #{1}, PCR PID {2}, {3} streams. {4}", sourcePid,result.ProgramNumber,result.PcrPid,result.Streams.Count, inserted ? "(Added to database)" : ""); + } + } + + foreach (IsdbPmtStream pmtStream in result.Streams) + { + StreamType streamType = DetectStreamType(pmtStream); + switch (streamType) + { + case StreamType.Video: + continue; + case StreamType.Audio: + continue; + default: + throw new NotImplementedException(String.Format("Could not figure out what to do with a {0} stream. It would be great if you could share a sample of this stream, so I can try to implement this.", streamType)); + } + } throw new NotImplementedException(); } + private StreamType DetectStreamType(IsdbPmtStream pmtStream) + { + if (pmtStream.StreamType == PmtStreamType.AvcVideoStream) + return StreamType.Video; + if (pmtStream.StreamType == PmtStreamType.Iso14496_3Audio) + return StreamType.Audio; + if (pmtStream.StreamType == PmtStreamType.Iso13818_1PesPackets && pmtStream.DataComponent != null) + { + switch (pmtStream.DataComponent.DataComponentId) + { + case 0x0012: + return StreamType.IsdbSubtitles; + default: + throw new IsdbException(String.Format("Unknown ISDB Data Component 0x{0:X4}", pmtStream.DataComponent.DataComponentId)); + } + } + + throw new IsdbException(String.Format("Could not detect stream type for PID 0x{0:X4}. It would be great if you could share a sample of this stream, so I can try to implement this.", pmtStream.ElementaryPid)); + } + public void PmtError(IsdbPmtErrors esInfoLengthLongerThanBuffer, int pmtPid, ushort programNumber) { throw new NotImplementedException(); diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index be5a906..7c429f3 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -3693,6 +3693,15 @@ namespace skyscraper5.Skyscraper.Scraper } _matenro = new Matenro(DvbContext, DataStorage, ObjectStorage, UiJunction, LogEvent); + if (this.CurrentNetworkId.HasValue) + { + _matenro.SetNetworkId((ushort)this.CurrentNetworkId.Value); + } + + if (this.CurrentTransportStreamId.HasValue) + { + _matenro.SetTransportStreamId((ushort)this.CurrentTransportStreamId.Value); + } } else { diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index 31dada9..da60bf5 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -29,6 +29,7 @@ using skyscraper5.src.InteractionChannel.Model2; using skyscraper8.Atsc.A331.Schema; using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model2; +using skyscraper8.Isdb.Tables; namespace skyscraper8.Skyscraper.Scraper.Storage { @@ -211,5 +212,8 @@ namespace skyscraper8.Skyscraper.Scraper.Storage /// A row of a HELD table /// true if the service was added or was changed bool UpsertAtsc3Held(HTMLEntryPackageType htmlEntryPackageType); + + bool TestForIsdbPmt(ushort networkPid, ushort transportStreamId, ushort resultProgramNumber); + void InsertIsdbPmt(ushort networkPid, ushort transportStreamId, IsdbPmt result); } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index 40ea810..6897cc8 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -47,6 +47,7 @@ using System.Net.NetworkInformation; using System.Text; using System.Text.RegularExpressions; using skyscraper8.Atsc.A331.Schema; +using skyscraper8.Isdb.Tables; using skyscraper8.Skyscraper.Scraper.Storage.Tar; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; @@ -1794,6 +1795,23 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem throw new NotImplementedException(); } + public bool TestForIsdbPmt(ushort networkId, ushort transportStreamId, ushort resultProgramNumber) + { + string combine = Path.Combine(rootDirectory.FullName, "ISDB-PMT", networkId.ToString(), transportStreamId.ToString(), String.Format("{0}.json", resultProgramNumber)); + FileInfo fi = new FileInfo(combine); + return fi.Exists; + } + + public void InsertIsdbPmt(ushort networkId, ushort transportStreamId, IsdbPmt result) + { + string combine = Path.Combine(rootDirectory.FullName, "ISDB-PMT", networkId.ToString(), transportStreamId.ToString(), String.Format("{0}.json", result.ProgramNumber)); + FileInfo fi = new FileInfo(combine); + if (fi.Exists) + return; + EnsureDirectoryExists(fi.Directory); + File.WriteAllText(fi.FullName, JsonConvert.SerializeObject(result, Formatting.Indented, jsonSerializerSettings)); + } + public RfSpectrumData GetRfSpectrum(Guid jobGuid) { string filename = Path.Combine(rootDirectory.FullName, "rf", jobGuid.ToString() + ".rf"); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs index 14d5a11..1ef3a54 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs @@ -41,6 +41,7 @@ using skyscraper8.Ietf.FLUTE; using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model2; using skyscraper8.InteractionChannel.Model2.Descriptors; +using skyscraper8.Isdb.Tables; using skyscraper8.Skyscraper.Scraper.Storage; using skyscraper8.Skyscraper.Scraper.Storage.Utilities; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; @@ -1922,5 +1923,33 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory return true; } } + + private Dictionary _isdbPmts; + public bool TestForIsdbPmt(ushort networkPid, ushort transportStreamId, ushort resultProgramNumber) + { + if (_isdbPmts == null) + return false; + + long result = networkPid; + result <<= 16; + result |= transportStreamId; + result <<= 16; + result |= resultProgramNumber; + return _isdbPmts.ContainsKey(result); + } + + public void InsertIsdbPmt(ushort networkPid, ushort transportStreamId, IsdbPmt result) + { + long key = networkPid; + key <<= 16; + key |= transportStreamId; + key <<= 16; + key |= result.ProgramNumber; + + if (_isdbPmts == null) + _isdbPmts = new Dictionary(); + + _isdbPmts.Add(key, result); + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamType.cs b/skyscraper8/Skyscraper/Scraper/StreamType.cs index b59dce4..2bb0426 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamType.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamType.cs @@ -32,6 +32,7 @@ namespace skyscraper5.Skyscraper.Scraper Id3, SisFramingAndTiming, SisDaughterSiteAdapterConfiguration, - SisPsiTables + SisPsiTables, + IsdbSubtitles } }