160 lines
4.4 KiB
C#
160 lines
4.4 KiB
C#
using System.Diagnostics;
|
|
using PlaylistsNET.Content;
|
|
using PlaylistsNET.Models;
|
|
|
|
bool RunProgram(string progname, string args, string directory = null)
|
|
{
|
|
Process process = new Process();
|
|
process.StartInfo.FileName = progname;
|
|
process.StartInfo.Arguments = args;
|
|
process.StartInfo.UseShellExecute = false;
|
|
if (!string.IsNullOrEmpty(directory))
|
|
process.StartInfo.WorkingDirectory = directory;
|
|
Console.WriteLine("Starting {0} at {1}", progname, DateTime.Now);
|
|
process.Start();
|
|
process.WaitForExit();
|
|
return process.ExitCode == 0;
|
|
}
|
|
|
|
void EnsureFolderExists(DirectoryInfo directory)
|
|
{
|
|
if (directory.Exists)
|
|
return;
|
|
|
|
EnsureFolderExists(directory.Parent);
|
|
directory.Create();
|
|
directory.Refresh();
|
|
}
|
|
|
|
string GetChannelName(M3uPlaylistEntry entry)
|
|
{
|
|
if (entry.CustomProperties.ContainsKey("EXTINF"))
|
|
{
|
|
string extinf = entry.CustomProperties["EXTINF"];
|
|
string[] extInfArgs = extinf.Split(',');
|
|
string channelName = extInfArgs[extInfArgs.Length - 1];
|
|
channelName = CleanString(channelName);
|
|
return channelName;
|
|
}
|
|
foreach (KeyValuePair<string,string> can in entry.CustomProperties)
|
|
{
|
|
if (can.Key.StartsWith("EXTINF:-1"))
|
|
{
|
|
string fullname = can.ToString();
|
|
int offset = fullname.IndexOf("\",");
|
|
fullname = fullname.Substring(offset + 2);
|
|
fullname = fullname.Substring(0, fullname.Length - 1);
|
|
fullname = CleanString(fullname);
|
|
return fullname;
|
|
}
|
|
}
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
string CleanString(string channelName)
|
|
{
|
|
char[] invalidChars = Path.GetInvalidFileNameChars();
|
|
char[] buffer = channelName.ToCharArray();
|
|
for (int i = 0; i < buffer.Length; i++)
|
|
{
|
|
if (invalidChars.Contains(buffer[i]))
|
|
{
|
|
buffer[i] = '_';
|
|
}
|
|
if (buffer[i] > 126)
|
|
{
|
|
buffer[i] = '-';
|
|
}
|
|
if (buffer[i] == ';')
|
|
{
|
|
buffer[i] = '+';
|
|
}
|
|
}
|
|
return new string(buffer);
|
|
}
|
|
|
|
// See https://aka.ms/new-console-template for more information
|
|
Console.WriteLine("Hello, World!");
|
|
|
|
DirectoryInfo streamDir = new DirectoryInfo(Path.Combine("iptv\\streams"));
|
|
if (!streamDir.Exists)
|
|
{
|
|
if (!RunProgram("git", "clone https://github.com/iptv-org/iptv"))
|
|
{
|
|
Console.WriteLine("Failed to clone the git repository.");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RunProgram("git", "pull", "iptv");
|
|
}
|
|
|
|
streamDir.Refresh();
|
|
FileInfo csvName = new FileInfo(String.Format("{0}.csv", DateTime.Now.Ticks));
|
|
StringWriter csvBuilder = new StringWriter();
|
|
|
|
foreach (FileInfo m3uinfo in streamDir.GetFiles("*.m3u"))
|
|
{
|
|
M3uContent m3u = new M3uContent();
|
|
PlaylistsNET.Models.M3uPlaylist m3uPlaylist = m3u.GetFromString(File.ReadAllText(m3uinfo.FullName));
|
|
List<PlaylistsNET.Models.M3uPlaylistEntry> playlistEntries = m3uPlaylist.PlaylistEntries;
|
|
string countryName = Path.GetFileNameWithoutExtension(m3uinfo.Name);
|
|
foreach (M3uPlaylistEntry entry in playlistEntries)
|
|
{
|
|
string channelName = GetChannelName(entry);
|
|
string outputFileName = Path.Combine("output", countryName, String.Format("{0}.ts", channelName));
|
|
string outputFlagName = Path.Combine("output", countryName, String.Format("{0}.fail", channelName));
|
|
FileInfo outputFileInfo = new FileInfo(outputFileName);
|
|
if (!outputFileInfo.Exists)
|
|
{
|
|
if (File.Exists(outputFlagName))
|
|
continue;
|
|
EnsureFolderExists(outputFileInfo.Directory);
|
|
string tspArgs = String.Format("-v -I hls \"{0}\" -P until -s 60 -O file \"{1}\"", entry.Path, outputFileInfo.FullName);
|
|
if (!RunProgram("tsp", tspArgs))
|
|
{
|
|
File.WriteAllText(outputFlagName, "");
|
|
}
|
|
}
|
|
outputFileInfo.Refresh();
|
|
if (outputFileInfo.Exists)
|
|
{
|
|
uint[] pidStats = AnalyzeStream(outputFileInfo);
|
|
int activePids = pidStats.Count(x => x > 0);
|
|
string outputLine = String.Format("{0};{1};{2};", outputFileInfo.Directory.Name, channelName, activePids);
|
|
for (int i = 0; i < pidStats.Length; i++)
|
|
{
|
|
if (pidStats[i] > 0)
|
|
{
|
|
outputLine += String.Format("0x{0:X4};", i);
|
|
}
|
|
}
|
|
csvBuilder.WriteLine(outputLine);
|
|
Console.WriteLine(outputLine);
|
|
}
|
|
}
|
|
}
|
|
File.WriteAllText(csvName.FullName, csvBuilder.ToString());
|
|
|
|
uint[] AnalyzeStream(FileInfo outputFileInfo)
|
|
{
|
|
FileStream fileStream = outputFileInfo.OpenRead();
|
|
BufferedStream bufferedStream = new BufferedStream(fileStream, 192512);
|
|
byte[] packetBuffer = new byte[188];
|
|
uint[] result = new uint[0x2000];
|
|
while (true)
|
|
{
|
|
if (bufferedStream.Read(packetBuffer, 0, packetBuffer.Length) != packetBuffer.Length)
|
|
break;
|
|
if (packetBuffer[0] != 'G')
|
|
break;
|
|
int pid = packetBuffer[1] & 0x1f;
|
|
pid <<= 8;
|
|
pid += packetBuffer[2];
|
|
result[pid]++;
|
|
}
|
|
bufferedStream.Close();
|
|
fileStream.Close();
|
|
return result;
|
|
} |