-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
313 lines (270 loc) · 11.5 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Net;
using System.Collections.Generic;
using System.Text.Json;
using System.IO;
using System.Text.Encodings.Web;
using System.Security.Cryptography;
using System.Text;
using System.Net.Sockets;
using System;
using System.Net.NetworkInformation;
namespace GrassIPTV
{
internal class Program
{
private static Process currentMpvProcess = null;
static void Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
#region 判断系统部分
string sys;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
sys = "win";
Console.WriteLine("当前环境是windows");
Run.RunCommand("winget install mpv --accept-source-agreements --silent --accept-package-agreements", sys);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Console.WriteLine("当前环境是Linux");
sys = "linux";
Run.RunCommand("sudo apt install mpv", sys);
}
else
{
Console.WriteLine("未知环境 程序退出");
return;
}
#endregion
#region 获取列表
string Vision = "Alpha0.0.2";
Console.WriteLine("启动IPTV主程序");
Console.WriteLine("版本:" + Vision);
//获取当前播放列表
string url = "https://raw.githubusercontent.com/suxuang/myIPTV/main/boxTV.m3u";
string localPath = "boxTV.m3u";
try
{
Console.WriteLine("正在使用github更新源");
using WebClient client = new();
client.DownloadFile(url, localPath);
}
catch (Exception)
{
Console.WriteLine("github失败 正在使用liubiligrass更新源");
url = "https://liubiligrass.com/GRASSIPTV/boxTV.m3u";
try
{
using (WebClient client = new())
{
client.DownloadFile(url, localPath);
}
}
catch (Exception)
{
Console.WriteLine("彻底失败 使用缓存源 能看多少看上天");
}
}
// 下载文件
// 解析m3u文件
var lines = File.ReadAllLines(localPath);
var channels = new List<Dictionary<string, string>>();
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith("#EXTINF"))
{
// 获取频道名称
var channelName = lines[i].Substring(lines[i].IndexOf(",") + 1);
// 获取频道URL
var channelUrl = lines[i + 1];
// 添加到频道列表
channels.Add(new Dictionary<string, string> { { channelName, channelUrl } });
}
}
// 创建JsonSerializerOptions对象
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
// 转换为json
var json = JsonSerializer.Serialize(channels, options);
//解析本地IP
string localIpAddress = GetLocalIPAddress().ToString();
Console.WriteLine("本机地址:" + localIpAddress);
// 输出json到文件
string list = "html/list.json";
File.WriteAllText(list, json);
#endregion
#region 启动监听
HttpListener listener = new HttpListener();
string urls = $"http://{localIpAddress}:2545/";
listener.Prefixes.Add(urls);
Console.WriteLine("开始监听");
Console.WriteLine(urls);
listener.Start();
#endregion
while (true)
{
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
#region 获取后端机IP
if (request.HttpMethod == "GET" && request.Url.AbsolutePath == "/ip")
{
// 返回IP地址
byte[] buffer = Encoding.UTF8.GetBytes(localIpAddress);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
}
#endregion
# region 频道接口
if (request.HttpMethod == "POST" && request.Url.AbsolutePath == "/get-channel-info")
{
// 读取你的 JSON 文件
var jsonf = File.ReadAllText("html/list.json");
// 将 JSON 文件的内容发送到前端
byte[] buffer = Encoding.UTF8.GetBytes(jsonf);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
#endregion
#region HTML主页面
if (request.HttpMethod == "GET" && request.Url.AbsolutePath == "/")
{
// 读取你的 HTML 文件
var html = File.ReadAllText("html/index.html");
// 将 HTML 文件的内容发送到前端
byte[] buffer = Encoding.UTF8.GetBytes(html);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
#endregion
#region CSS页面
if (request.HttpMethod == "GET" && request.Url.AbsolutePath.EndsWith(".css"))
{
// 获取 CSS 文件的路径
var cssFilePath = Path.Combine("html", request.Url.AbsolutePath.TrimStart('/'));
// 检查 CSS 文件是否存在
if (File.Exists(cssFilePath))
{
// 读取 CSS 文件
var css = File.ReadAllText(cssFilePath);
// 将 CSS 文件的内容发送到前端
byte[] buffer = Encoding.UTF8.GetBytes(css);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
else
{
// 如果 CSS 文件不存在,返回 404 错误
response.StatusCode = 404;
response.Close();
}
}
#endregion
#region 频道json
if (request.HttpMethod == "POST" && request.Url.AbsolutePath == "/get-channel-name")
{
// 读取请求的正文
using var reader = new StreamReader(request.InputStream, request.ContentEncoding);
var content = reader.ReadToEnd();
// 解析 JSON
var data = JsonSerializer.Deserialize<Dictionary<string, string>>(content);
// 获取频道名称
var channelName = data["channelName"];
// 解析你的 JSON 文件
var channelsa = JsonSerializer.Deserialize<List<Dictionary<string, string>>>(File.ReadAllText("html/list.json"));
// 查找与 channelName 对应的值
string channelUrl = null;
foreach (var channel in channelsa)
{
if (channel.ContainsKey(channelName))
{
channelUrl = channel[channelName];
break;
}
}
// 输出频道 URL
if (channelUrl != null)
{
Console.WriteLine(channelUrl);
// 如果当前有正在运行的mpv进程,结束它
if (currentMpvProcess != null)
{
if (!currentMpvProcess.HasExited)
{
// 使用命令行工具结束mpv进程
if (sys == "linux")
{
Run.RunCommand("pkill mpv", sys);
}
else if (sys == "win")
{
Run.RunCommand("taskkill /IM mpv.exe /F", sys);
}
System.Threading.Thread.Sleep(1000); // 等待1秒
}
currentMpvProcess = null;
}
// 启动新的mpv进程
currentMpvProcess = Run.RunCommand("mpv " + channelUrl, sys);
}
else
{
Console.WriteLine("频道未找到: " + channelName);
}
// 返回一个空的响应
response.StatusCode = 200;
response.Close();
}
#endregion
#region OPTIONS处理
if (request.HttpMethod == "OPTIONS")
{
// 添加 CORS 头
response.AddHeader("Access-Control-Allow-Origin", "*");
response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.AddHeader("Access-Control-Allow-Headers", "Content-Type");
response.StatusCode = 200;
response.Close();
}
#endregion
}
}
#region 静态模块:获取本地IP地址
static string GetLocalIPAddress()
{
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 &&
ni.NetworkInterfaceType != NetworkInterfaceType.Ethernet)
{
continue;
}
if (ni.OperationalStatus != OperationalStatus.Up)
{
continue;
}
foreach (var ip in ni.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
return ip.Address.ToString();
}
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
#endregion
}
}
}