From 3611742fcef229a14ecd33eff36ce9fa7947116f Mon Sep 17 00:00:00 2001 From: ZaMIk99 <33591593+ZaMIk99@users.noreply.github.com> Date: Sun, 6 Apr 2025 20:11:32 +0300 Subject: [PATCH] Add files via upload --- Program.cs | 196 ++++++++++++++++++++++++++++++++++++++++++++++++ radioCLI.csproj | 14 ++++ radioCLI.sln | 25 ++++++ 3 files changed, 235 insertions(+) create mode 100644 Program.cs create mode 100644 radioCLI.csproj create mode 100644 radioCLI.sln diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..e03ba10 --- /dev/null +++ b/Program.cs @@ -0,0 +1,196 @@ +using System.Net; +using System.Text; +using NAudio.Wave; + +class Program +{ + private static WaveOutEvent? outputDevice; + private static MediaFoundationReader? audioStream; + private static bool isPaused = false; + private static float volume = 0.5f; + private static bool isRunning = true; + private static string streamUrl = ""; + private static string currentTrack = "Неизвестно"; + + static void Main() + { + Console.Title = "Radio CLI"; + Console.CursorVisible = false; + Console.WindowHeight = 7; + Console.WindowWidth = 60; + + SelectStation(); + + Thread metadataThread = new Thread(GetStreamMetadata) { IsBackground = true }; + metadataThread.Start(); + + try + { + StartPlayback(); + + while (isRunning) + { + DisplayCompactUI(); + var key = Console.ReadKey(true).Key; + switch (key) + { + case ConsoleKey.P: + TogglePause(); + break; + case ConsoleKey.Add: + case ConsoleKey.OemPlus: + AdjustVolume(0.05f); + break; + case ConsoleKey.Subtract: + case ConsoleKey.OemMinus: + AdjustVolume(-0.05f); + break; + case ConsoleKey.Q: + isRunning = false; + break; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Ошибка: {ex.Message}"); + } + finally + { + StopPlayback(); + Console.CursorVisible = true; + Console.WriteLine("\nРадио остановлено. Нажмите любую клавишу..."); + Console.ReadKey(); + } + } + + static void SelectStation() + { + Console.Clear(); + Console.WriteLine("Выберите радиостанцию:"); + Console.WriteLine("1) DALA FM (http://178.88.167.62:8080/DALA_320)"); + Console.WriteLine("2) Руки Вверх! (https://stream03.pcradio.ru/Ruki_Vverh-med)"); + Console.WriteLine("3) Дорожное Радио (http://dorognoe.hostingradio.ru:8000/radio)"); + Console.WriteLine("4) Ввести свою ссылку"); + Console.Write("Введите номер (1-4): "); + + string choice = Console.ReadLine() ?? ""; + switch (choice) + { + case "1": + streamUrl = "http://178.88.167.62:8080/DALA_320"; + break; + case "2": + streamUrl = "https://stream03.pcradio.ru/Ruki_Vverh-med"; + break; + case "3": + streamUrl = "http://dorognoe.hostingradio.ru:8000/radio"; + break; + case "4": + Console.Write("Введите ссылку на поток: "); + streamUrl = Console.ReadLine() ?? ""; + break; + default: + Console.WriteLine("Некорректный ввод, попробуйте снова."); + SelectStation(); + break; + } + } + + static void StartPlayback() + { + try + { + audioStream = new MediaFoundationReader(streamUrl); + outputDevice = new WaveOutEvent(); + outputDevice.Init(audioStream); + outputDevice.Volume = volume; + outputDevice.Play(); + } + catch (Exception ex) + { + Console.WriteLine($"Ошибка воспроизведения: {ex.Message}"); + } + } + + static void DisplayCompactUI() + { + Console.Clear(); + Console.WriteLine("┌──────────────────────────────────────────────┐"); + Console.WriteLine("│ DALA FM - Народное радио │"); + Console.WriteLine("├──────────────────────────────────────────────┤"); + Console.WriteLine($"│ Статус: {(isPaused ? "Пауза" : "Играет").PadRight(8)} Громкость: {(int)(volume * 100)}% │"); + Console.WriteLine("├──────────────────────────────────────────────┤"); + Console.WriteLine($"│ Сейчас играет: {currentTrack.PadRight(30)} │"); + Console.WriteLine("├──────────────────────────────────────────────┤"); + Console.WriteLine("│ P:Пауза +/-:Громкость Q:Выход │"); + Console.WriteLine("└──────────────────────────────────────────────┘"); + } + + static void TogglePause() + { + if (outputDevice == null) return; + + if (isPaused) + { + outputDevice.Play(); + isPaused = false; + } + else + { + outputDevice.Pause(); + isPaused = true; + } + } + + static void AdjustVolume(float delta) + { + if (outputDevice == null) return; + + volume = Math.Clamp(volume + delta, 0f, 1f); + outputDevice.Volume = volume; + } + + static void StopPlayback() + { + outputDevice?.Stop(); + outputDevice?.Dispose(); + audioStream?.Dispose(); + } + + static void GetStreamMetadata() + { + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(streamUrl); + request.Headers.Add("Icy-MetaData", "1"); + request.Timeout = 5000; + + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + using (Stream stream = response.GetResponseStream()) + { + if (stream == null) return; + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0 && isRunning) + { + string responseString = Encoding.UTF8.GetString(buffer, 0, bytesRead); + if (responseString.Contains("StreamTitle='")) + { + int start = responseString.IndexOf("StreamTitle='") + 13; + int end = responseString.IndexOf("';", start); + if (end > start) + { + currentTrack = responseString[start..end]; + } + } + Thread.Sleep(2000); + } + } + } + catch (Exception) + { + currentTrack = "Не удалось получить метаданные"; + } + } +} diff --git a/radioCLI.csproj b/radioCLI.csproj new file mode 100644 index 0000000..37ffb63 --- /dev/null +++ b/radioCLI.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/radioCLI.sln b/radioCLI.sln new file mode 100644 index 0000000..612099b --- /dev/null +++ b/radioCLI.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35913.81 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "radioCLI", "radioCLI.csproj", "{1654A016-7E88-4028-920D-188F335B89EE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1654A016-7E88-4028-920D-188F335B89EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1654A016-7E88-4028-920D-188F335B89EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1654A016-7E88-4028-920D-188F335B89EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1654A016-7E88-4028-920D-188F335B89EE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {52EA7637-C651-4E8F-8017-BC60427F208A} + EndGlobalSection +EndGlobal