hls-viewcount/Program.cs

68 lines
1.9 KiB
C#

using System.Globalization;
using System.Text.RegularExpressions;
List<User> users = new();
while (Console.In.ReadLine() is { } entry) {
if (!entry.Contains("\"cdn.chaos.stream\" \"GET /hls/"))
continue;
if (!entry.Contains(".ts HTTP"))
continue;
var match = Regex.Match(entry, "^\\[(.*?)\\].*?GET \\/hls\\/(.+?)-(\\d+)\\.ts HTTP\\/\\d\\.\\d\" 200");
if (!match.Success)
continue;
var timestamp = match.Groups[1].Value;
var streamkey = match.Groups[2].Value;
var fragmentId = match.Groups[3].Value;
if (users.All(p => p.Streamkey != streamkey))
users.Add(new User(streamkey));
var user = users.First(p => p.Streamkey == streamkey);
if (user.Fragments.All(p => p.Id != fragmentId))
user.Fragments.Add(new Fragment(timestamp, fragmentId));
else
user.Fragments.First(p => p.Id == fragmentId).Count++;
UpdateScreen();
}
void UpdateScreen() {
var output = new List<(string streamkey, int count)>();
foreach (var user in users.OrderBy(p => p.Streamkey)) {
user.Fragments.RemoveAll(p => p.Time < DateTime.Now - TimeSpan.FromMinutes(1));
if (user.Fragments.Any())
output.Add((user.Streamkey, user.Fragments.TakeLast(6).First().Count));
}
var paddingOffset = users.Select(p => p.Streamkey).Aggregate("", (max, cur) => max.Length > cur.Length ? max : cur).Length;
Console.Clear();
Console.WriteLine($"Viewcount as of {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
foreach (var item in output) {
Console.WriteLine($"{item.streamkey.PadRight(paddingOffset)} - {item.count}");
}
}
internal class User {
public List<Fragment> Fragments = new();
public string Streamkey;
public User(string streamkey) {
Streamkey = streamkey;
}
}
internal class Fragment {
public string Id;
public DateTime Time;
public int Count = 1;
public Fragment(string timestamp, string id) {
Time = DateTime.ParseExact(timestamp, "dd/MMM/yyyy:HH:mm:ss K", DateTimeFormatInfo.InvariantInfo);
Id = id;
}
}