Read M3U8 Files from disk.
This commit is contained in:
parent
ef86554f9a
commit
0f5ad93c24
@ -31,6 +31,16 @@ namespace skyscraper5.Docsis.MacManagement
|
|||||||
positionFor1516 = ms.Position;
|
positionFor1516 = ms.Position;
|
||||||
byte type = ms.ReadUInt8();
|
byte type = ms.ReadUInt8();
|
||||||
byte length = ms.ReadUInt8();
|
byte length = ms.ReadUInt8();
|
||||||
|
if (length > ms.GetAvailableBytes())
|
||||||
|
{
|
||||||
|
Valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
Valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
byte[] v = ms.ReadBytes(length);
|
byte[] v = ms.ReadBytes(length);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -38,6 +48,11 @@ namespace skyscraper5.Docsis.MacManagement
|
|||||||
//reserved
|
//reserved
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
if (length < 4)
|
||||||
|
{
|
||||||
|
Valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
(v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
|
(v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
|
||||||
TimingAdjust = BitConverter.ToUInt32(v, 0);
|
TimingAdjust = BitConverter.ToUInt32(v, 0);
|
||||||
break;
|
break;
|
||||||
@ -45,7 +60,12 @@ namespace skyscraper5.Docsis.MacManagement
|
|||||||
PowerLevelAdjust = v[0];
|
PowerLevelAdjust = v[0];
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
(v[0], v[1]) = (v[1], v[0]);
|
if (length < 2)
|
||||||
|
{
|
||||||
|
Valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(v[0], v[1]) = (v[1], v[0]);
|
||||||
OffsetFrequencyAdjust = BitConverter.ToUInt16(v, 0);
|
OffsetFrequencyAdjust = BitConverter.ToUInt16(v, 0);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
@ -55,6 +75,11 @@ namespace skyscraper5.Docsis.MacManagement
|
|||||||
RangingStatus = (RangingStatusEnum)v[0];
|
RangingStatus = (RangingStatusEnum)v[0];
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
if (length < 4)
|
||||||
|
{
|
||||||
|
Valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
(v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
|
(v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
|
||||||
DownstreamFrequencyOverride = BitConverter.ToUInt32(v, 0);
|
DownstreamFrequencyOverride = BitConverter.ToUInt32(v, 0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -30,6 +30,7 @@ using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
|||||||
using skyscraper5.src.Sophtainer;
|
using skyscraper5.src.Sophtainer;
|
||||||
using skyscraper5.T2MI;
|
using skyscraper5.T2MI;
|
||||||
using skyscraper5.src.Mpeg2.PacketFilter;
|
using skyscraper5.src.Mpeg2.PacketFilter;
|
||||||
|
using skyscraper8.Skyscraper.IO;
|
||||||
|
|
||||||
namespace skyscraper5
|
namespace skyscraper5
|
||||||
{
|
{
|
||||||
@ -55,6 +56,14 @@ namespace skyscraper5
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args[0].ToLowerInvariant().EndsWith(".m3u8"))
|
||||||
|
{
|
||||||
|
M3U8Stream m3U8Stream = new M3U8Stream(args[0]);
|
||||||
|
SkyscraperContext skyscraperContext = new SkyscraperContext(new TsContext());
|
||||||
|
skyscraperContext.InitalizeFilterChain();
|
||||||
|
skyscraperContext.IngestFromStream(m3U8Stream);
|
||||||
|
}
|
||||||
|
|
||||||
if (args[0].Equals("aactest"))
|
if (args[0].Equals("aactest"))
|
||||||
{
|
{
|
||||||
new AacTestProgram().Run();
|
new AacTestProgram().Run();
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"skyscraper8": {
|
"skyscraper8": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "cscan \"tcp://172.20.20.202:6970\"",
|
"commandLineArgs": "\"D:\\DocsisDemo\\docsis.m3u8\"",
|
||||||
"remoteDebugEnabled": false
|
"remoteDebugEnabled": false
|
||||||
},
|
},
|
||||||
"Container (Dockerfile)": {
|
"Container (Dockerfile)": {
|
||||||
|
|||||||
55
skyscraper8/Skyscraper/IO/EmptyStream.cs
Normal file
55
skyscraper8/Skyscraper/IO/EmptyStream.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.IO
|
||||||
|
{
|
||||||
|
internal class EmptyStream : Stream
|
||||||
|
{
|
||||||
|
public override bool CanRead => true;
|
||||||
|
|
||||||
|
public override bool CanSeek => true;
|
||||||
|
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
|
||||||
|
public override long Length => 0;
|
||||||
|
|
||||||
|
public override long Position {
|
||||||
|
get => 0;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
if (offset != 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(offset));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
if (value != 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
202
skyscraper8/Skyscraper/IO/M3U8Stream.cs
Normal file
202
skyscraper8/Skyscraper/IO/M3U8Stream.cs
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.IO
|
||||||
|
{
|
||||||
|
internal class M3U8Stream : Stream
|
||||||
|
{
|
||||||
|
public M3U8Stream(string source)
|
||||||
|
{
|
||||||
|
this.segmentIndex = 0;
|
||||||
|
this.segmentNames = new string[0];
|
||||||
|
this.source = source;
|
||||||
|
this.finishedSegments = new List<string>();
|
||||||
|
this.innerStream = new EmptyStream();
|
||||||
|
this.sourceRoot = GetRoot(source);
|
||||||
|
|
||||||
|
if (source.StartsWith("http://") || source.StartsWith("https://"))
|
||||||
|
{
|
||||||
|
webClient = new HttpClient();
|
||||||
|
webClient.BaseAddress = new Uri(sourceRoot);
|
||||||
|
}
|
||||||
|
else if (File.Exists(source))
|
||||||
|
{
|
||||||
|
this.rootDirectory = new DirectoryInfo(sourceRoot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int segmentIndex;
|
||||||
|
private string[] segmentNames;
|
||||||
|
private string source;
|
||||||
|
private List<string> finishedSegments;
|
||||||
|
private Stream innerStream;
|
||||||
|
private string sourceRoot;
|
||||||
|
|
||||||
|
private HttpClient webClient;
|
||||||
|
private DirectoryInfo rootDirectory;
|
||||||
|
|
||||||
|
private string GetRoot(string source)
|
||||||
|
{
|
||||||
|
if (source.StartsWith("http://") || source.StartsWith("https://"))
|
||||||
|
{
|
||||||
|
while (!source.EndsWith("/"))
|
||||||
|
{
|
||||||
|
source = source.Substring(0, source.Length - 1);
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
else if (File.Exists(source))
|
||||||
|
{
|
||||||
|
FileInfo fi = new FileInfo(source);
|
||||||
|
DirectoryInfo di = fi.Directory;
|
||||||
|
return di.FullName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream GetSegmentStream(string segmentName)
|
||||||
|
{
|
||||||
|
Console.WriteLine("open segment {0}", segmentName);
|
||||||
|
if (source.StartsWith("http://") || source.StartsWith("https://"))
|
||||||
|
{
|
||||||
|
return webClient.GetStreamAsync(segmentName).Result;
|
||||||
|
}
|
||||||
|
else if (File.Exists(source))
|
||||||
|
{
|
||||||
|
string partFileName = Path.Combine(rootDirectory.FullName, segmentName);
|
||||||
|
FileInfo fi = new FileInfo(partFileName);
|
||||||
|
return fi.OpenRead();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ReloadSegmentList()
|
||||||
|
{
|
||||||
|
string[] newLines;
|
||||||
|
if (source.StartsWith("http://") || source.StartsWith("https://"))
|
||||||
|
{
|
||||||
|
byte[] result = webClient.GetByteArrayAsync(source).Result;
|
||||||
|
MemoryStream ms = new MemoryStream(result, false);
|
||||||
|
StreamReader streamReader = new StreamReader(ms);
|
||||||
|
List<string> lines = new List<string>();
|
||||||
|
while (!streamReader.EndOfStream)
|
||||||
|
{
|
||||||
|
lines.Add(streamReader.ReadLine());
|
||||||
|
}
|
||||||
|
streamReader.Close();
|
||||||
|
ms.Close();
|
||||||
|
newLines = lines.ToArray();
|
||||||
|
}
|
||||||
|
else if (File.Exists(source))
|
||||||
|
{
|
||||||
|
newLines = File.ReadAllLines(source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newLines.Length != segmentNames.Length)
|
||||||
|
{
|
||||||
|
segmentNames = newLines;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Math.Min(newLines.Length, segmentNames.Length); i++)
|
||||||
|
{
|
||||||
|
if (!segmentNames[i].Equals(newLines[i]))
|
||||||
|
{
|
||||||
|
segmentNames = newLines;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetNextSegment()
|
||||||
|
{
|
||||||
|
for (int i = segmentIndex; i < segmentNames.Length; i++)
|
||||||
|
{
|
||||||
|
if (segmentNames[i].StartsWith("#"))
|
||||||
|
continue;
|
||||||
|
if (finishedSegments.Contains(segmentNames[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this.segmentIndex = i;
|
||||||
|
this.finishedSegments.Add(segmentNames[i]);
|
||||||
|
this.innerStream = GetSegmentStream(segmentNames[i]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ReloadSegmentList())
|
||||||
|
{
|
||||||
|
return GetNextSegment();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanRead => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override bool CanSeek => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override bool CanWrite => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override long Length => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
int readResult = innerStream.Read(buffer, offset, count);
|
||||||
|
if (readResult == 0)
|
||||||
|
{
|
||||||
|
if (!GetNextSegment())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
offset += readResult;
|
||||||
|
count -= readResult;
|
||||||
|
result += readResult;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -679,7 +679,7 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
|||||||
public int? GetCurrentLocationId()
|
public int? GetCurrentLocationId()
|
||||||
{
|
{
|
||||||
if (!File.Exists("docsis_location.txt"))
|
if (!File.Exists("docsis_location.txt"))
|
||||||
return null;
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string readAllText = File.ReadAllText("docsis_location.txt");
|
string readAllText = File.ReadAllText("docsis_location.txt");
|
||||||
@ -1212,7 +1212,10 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
|||||||
|
|
||||||
public long DnsCountA()
|
public long DnsCountA()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (dnsRecords == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return dnsRecords.Count(x => x.RecordType.Item1 == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DnsIpToName(IPAddress source)
|
public string DnsIpToName(IPAddress source)
|
||||||
@ -1225,9 +1228,13 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HashSet<DnsRecord> dnsRecords;
|
||||||
public void RememberDnsRecord(DnsRecord record)
|
public void RememberDnsRecord(DnsRecord record)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (dnsRecords == null)
|
||||||
|
dnsRecords = new HashSet<DnsRecord>();
|
||||||
|
|
||||||
|
dnsRecords.Add(record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user