using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using OpenQA.Selenium; using OpenQA.Selenium.Firefox; using OpenQA.Selenium.Interactions; using OpenQA.Selenium.Support.UI; namespace Test_Merge { public class F1TVEmulator { public const string COOKIE_HOST = ".formula1.com"; public const string PYTHON_COOKIE_RETRIEVAL_FILENAME = "recoverCookiesCSV.py"; public const string GECKODRIVER_FILENAME = @"geckodriver-v0.27.0-win32\geckodriver.exe"; //BE CAREFULL IF YOU CHANGE IT HERE YOU NEED TO CHANGE IT IN THE PYTHON SCRIPT TOO public const string COOKIES_CSV_FILENAME = "cookies.csv"; private FirefoxDriver Driver; private bool _ready; private string _grandPrixUrl; public string GrandPrixUrl { get => _grandPrixUrl; private set => _grandPrixUrl = value; } public bool Ready { get => _ready; set => _ready = value; } public F1TVEmulator(string grandPrixUrl) { GrandPrixUrl = grandPrixUrl; Ready = false; } private void StartCookieRecovering() { string scriptPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), PYTHON_COOKIE_RETRIEVAL_FILENAME); Process process = new Process(); process.StartInfo.FileName = "python.exe"; process.StartInfo.Arguments = scriptPath; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.Start(); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); } public async Task Start() { //SETUP //Those values can be changed to alter the way that the selenium driver looks and behaves in general Ready = false; string loginCookieName = "login"; string loginSessionCookieName = "login-session"; string loginCookieValue = GetCookie(COOKIE_HOST, loginCookieName); string loginSessionValue = GetCookie(COOKIE_HOST, loginSessionCookieName); int windowWidth = 1920; int windowHeight = 1080; var service = FirefoxDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory + GECKODRIVER_FILENAME); service.Host = "127.0.0.1"; service.Port = 5555; FirefoxOptions options = new FirefoxOptions(); options.SetPreference("media.peerconnection.enabled", false); //FirefoxProfile profile = new FirefoxProfile(); //profile.SetPreference("layout.css.devPixelsPerPx", "2.0"); //options.Profile = profile; FirefoxProfile profile = new FirefoxProfile(); profile.SetPreference("media.navigator.video.default_width", 1920); profile.SetPreference("media.navigator.video.default_height", 1080); options.Profile = profile; options.AddArgument("--window-size=" + windowWidth + "," + windowHeight + ""); options.AddArgument("--disable-web-security"); options.AddArgument("--same-site-none-secure"); options.AcceptInsecureCertificates = true; //Headless part options.AddArgument("--headless"); options.AddArgument("--silent-launch"); options.AddArgument("--no-startup-window"); //ACTUAL STARTUP try { Driver = new FirefoxDriver(service, options); } catch { //Could not start the driver, could be because an other instance is running. make sure its closed before re attempting return 101; } var loginCookie = new Cookie(loginCookieName, loginCookieValue, COOKIE_HOST, "/", DateTime.Now.AddDays(5)); var loginSessionCookie = new Cookie(loginSessionCookieName, loginSessionValue, COOKIE_HOST, "/", DateTime.Now.AddDays(5)); Actions actions = new Actions(Driver); Driver.Navigate().GoToUrl("https://f1tv.formula1.com/"); //TEST //Driver.Manage().Window.Position = new Point(0, 0); //Driver.Manage().Window.Size = new Size(1920, 1080); Screenshot screenshot = ((ITakesScreenshot)Driver).GetScreenshot(); screenshot.SaveAsFile(@"C:\Users\Moi\Desktop\imgDump\Decode\FirstTest.png", ScreenshotImageFormat.Png); //TEST Driver.Manage().Cookies.AddCookie(loginCookie); Driver.Manage().Cookies.AddCookie(loginSessionCookie); try { Driver.Navigate().GoToUrl(GrandPrixUrl); } catch { //The url is not a valid url Driver.Dispose(); return 103; } //Waits for the page to fully load Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(30); //Removes the cookie prompt try { IWebElement conscentButton = Driver.FindElement(By.Id("truste-consent-button")); conscentButton.Click(); } catch { Driver.Dispose(); return 104; } //Again waits for the page to fully load (when you accept cookies it takes a little time for the page to load) //Cannot use The timeout because the feed loading is not really loading so there is not event or anything Thread.Sleep(5000); //Switches to the Data channel try { IWebElement dataChannelButton = Driver.FindElement(By.ClassName("data-button")); dataChannelButton.Click(); } catch { //If the data button does not exists its because the user is not connected Driver.Dispose(); return 102; } //Open settings // Press the space key, this should make the setting button visible // It does not matter if the feed is paused because when changing channel it autoplays actions.SendKeys(OpenQA.Selenium.Keys.Space).Perform(); Thread.Sleep(1000); //Clicks on the settings Icon try { IWebElement settingsButton = Driver.FindElement(By.ClassName("bmpui-ui-settingstogglebutton")); settingsButton.Click(); IWebElement selectElement = Driver.FindElement(By.ClassName("bmpui-ui-videoqualityselectbox")); SelectElement select = new SelectElement(selectElement); IWebElement selectOption = selectElement.FindElement(By.CssSelector("option[value^='1080_']")); selectOption.Click(); } catch { //Sometimes it can crash because it could not get the options to show up in time. When it happens just retry Driver.Dispose(); return 105; } //Makes the feed fullscreen WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10)); IWebElement fullScreenButton = Driver.FindElement(By.ClassName("bmpui-ui-fullscreentogglebutton")); fullScreenButton.Click(); //STARTUP FINISHED READY TO SCREENSHOT Ready = true; return 0; } public void Stop() { Ready = false; Driver.Dispose(); } public Bitmap Screenshot() { //bitmovinplayer-video-slave-embeddedPlayer Bitmap result = new Bitmap(100, 100); if (Ready) { /* Screenshot scrsht = ((ITakesScreenshot)Driver).GetScreenshot(); // Get the raw bytes of the screenshot */ //Driver.Manage().Window.Position = new Point(0, 0); //Driver.Manage().Window.Size = new Size(1920, 1080); IWebElement element = Driver.FindElement(By.Id("bitmovinplayer-video-slave-embeddedPlayer")); Screenshot scrsht = ((ITakesScreenshot)element).GetScreenshot(); byte[] screenshotBytes = Convert.FromBase64String(scrsht.AsBase64EncodedString); // Create a new MemoryStream from the bytes MemoryStream stream = new MemoryStream(screenshotBytes); // Create a new Bitmap object from the MemoryStream result = new Bitmap(stream); } result.Save(@"C:\Users\Moi\Desktop\imgDump\Decode\Test.png"); return result; } public string GetCookie(string host, string name) { StartCookieRecovering(); string value = ""; List cookies = new List(); using (var reader = new StreamReader(COOKIES_CSV_FILENAME)) { // Read the header row and validate column order string header = reader.ReadLine(); string[] expectedColumns = { "host_key", "name", "value", "path", "expires_utc", "is_secure", "is_httponly" }; string[] actualColumns = header.Split(','); for (int i = 0; i < expectedColumns.Length; i++) { if (expectedColumns[i] != actualColumns[i]) { throw new InvalidOperationException($"Expected column '{expectedColumns[i]}' at index {i} but found '{actualColumns[i]}'"); } } // Read each data row and parse values into a Cookie object while (!reader.EndOfStream) { string line = reader.ReadLine(); string[] fields = line.Split(','); string hostname = fields[0]; string cookieName = fields[1]; if (hostname == host && cookieName == name) { value = fields[2]; } } } return value; } } }