11import threading
22import time
33import PySimpleGUI as sg
4-
4+ import textwrap
55import y2qq
66from m3u8_cache import server
77
88
99# start a local server
1010server .start_server ()
1111
12+ graphic_off = True
1213format_list = []
1314g_current_selected_format = 0
1415g_current_m3u8_url = ""
1516
17+ toggle_btn_off = b'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAED0lEQVRYCe1WTWwbRRR+M/vnv9hO7BjHpElMKSlpqBp6gRNHxAFVcKM3qgohQSqoqhQ45YAILUUVDRxAor2VAweohMSBG5ciodJUSVqa/iikaePEP4nj2Ovdnd1l3qqJksZGXscVPaylt7Oe/d6bb9/svO8BeD8vA14GvAx4GXiiM0DqsXv3xBcJU5IO+RXpLQvs5yzTijBmhurh3cyLorBGBVokQG9qVe0HgwiXLowdy9aKsY3g8PA5xYiQEUrsk93JTtjd1x3siIZBkSWQudUK4nZO1w3QuOWXV+HuP/fL85klAJuMCUX7zPj4MW1zvC0Ej4yMp/w++K2rM9b70sHBYCjo34x9bPelsgp/XJksZ7KFuwZjr3732YcL64ttEDw6cq5bVuCvgy/sje7rT0sI8PtkSHSEIRIKgCQKOAUGM6G4VoGlwiqoVd2Za9Vl8u87bGJqpqBqZOj86eEHGNch+M7otwHJNq4NDexJD+59RiCEQG8qzslFgN8ibpvZNsBifgXmFvJg459tiOYmOElzYvr2bbmkD509e1ylGEZk1Y+Ssfan18n1p7vgqVh9cuiDxJPxKPT3dfGXcN4Tp3dsg/27hUQs0qMGpRMYjLz38dcxS7Dm3nztlUAb38p0d4JnLozPGrbFfBFm79c8hA3H2AxcXSvDz7/+XtZE1kMN23hjV7LTRnKBh9/cZnAj94mOCOD32gi2EUw4FIRUMm6LGhyiik86nO5NBdGRpxYH14bbjYfJteN/OKR7UiFZVg5T27QHYu0RBxoONV9W8KQ7QVp0iXdE8fANUGZa0QAvfhhXlkQcmjJZbt631oIBnwKmacYoEJvwiuFgWncWnXAtuVBBEAoVVXWCaQZzxmYuut68b631KmoVBEHMUUrJjQLXRAQVSxUcmrKVHfjWWjC3XOT1FW5QrWpc5IJdQhDKVzOigEqS5dKHMVplnNOqrmsXqUSkn+YzWaHE9RW1FeXL7SKZXBFUrXW6jIV6YTEvMAUu0W/G3kcxPXP5ylQZs4fa6marcWvvZfJu36kuHjlc/nMSuXz+/ejxgqPFpuQ/xVude9eu39Jxu27OLvBGoMjrUN04zrNMbgVmOBZ96iPdPZmYntH5Ls76KuxL9NyoLA/brav7n382emDfHqeooXyhQmARVhSnAwNNMx5bu3V1+habun5nWdXhwJZ2C5mirTesyUR738sv7g88UQ0rEkTDlp+1wwe8Pf0klegUenYlgyg7bby75jUTITs2rhCAXXQ2vwxz84vlB0tZ0wL4NEcLX/04OrrltG1s8aOrHhk51SaK0us+n/K2xexBxljcsm1n6x/Fuv1PCWGiKOaoQCY1Vb9gWPov50+fdEqd21ge3suAlwEvA14G/ucM/AuppqNllLGPKwAAAABJRU5ErkJggg=='
18+ toggle_btn_on = b'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAD+UlEQVRYCe1XzW8bVRCffbvrtbP+2NhOD7GzLm1VoZaPhvwDnKBUKlVyqAQ3/gAkDlWgPeVQEUCtEOIP4AaHSI0CqBWCQyXOdQuRaEFOk3g3IMWO46+tvZ+PeZs6apq4ipON1MNafrvreTPzfvub92bGAOEnZCBkIGQgZOClZoDrh25y5pdjruleEiX+A+rCaQo05bpuvJ/+IHJCSJtwpAHA/e269g8W5RbuzF6o7OVjF8D3Pr4tSSkyjcqfptPDMDKSleW4DKIggIAD5Yf+Oo4DNg6jbUBlvWLUNutAwZu1GnDjzrcXzGcX2AHw/emFUV6Sfk0pqcKpEydkKSo9q3tkz91uF5aWlo1Gs/mYc+i7tz4//19vsW2AU9O381TiioVCQcnlRsWeQhD3bJyH1/MiFLICyBHiuzQsD1arDvypW7DR9nzZmq47q2W95prm+I9fXfqXCX2AF2d+GhI98Y8xVX0lnxvl2UQQg0csb78ag3NjEeD8lXZ7pRTgftmCu4864OGzrq+5ZU0rCa3m+NzXlzvoAoB3+M+SyWQuaHBTEzKMq/3BMbgM+FuFCDBd9kK5XI5PJBKqLSev+POTV29lKB8rT0yMD0WjUSYLZLxzNgZvIHODOHuATP72Vwc6nQ4Uiw8MUeBU4nHS5HA6TYMEl02wPRcZBJuv+ya+UCZOIBaLwfCwQi1Mc4QXhA+PjWRkXyOgC1uIhW5Qd8yG2TK7kSweLcRGKKVnMNExWWBDTQsH9qVmtmzjiThQDs4Qz/OUSGTwcLwIQTLW58i+yOjpXDLqn1tgmDzXzRCk9eDenjo9yhvBmlizrB3V5dDrNTuY0A7opdndStqmaQLPC1WCGfShYRgHdLe32UrV3ntiH9LliuNrsToNlD4kruN8v75eafnSgC6Luo2+B3fGKskilj5muV6pNhk2Qqg5v7lZ51nBZhNBjGrbxfI1+La5t2JCzfD8RF1HTBGJXyDzs1MblONulEqPDVYXgwDIfNx91IUVbAbY837GMur+/k/XZ75UWmJ77ou5mfM1/0x7vP1ls9XQdF2z9uNsPzosXPNFA5m0/EX72TBSiqsWzN8z/GZB08pWq9VeEZ+0bjKb7RTD2i1P4u6r+bwypo5tZUumEcDAmuC3W8ezIqSGfE6g/sTd1W5p5bKjaWubrmWd29Fu9TD0GlYlmTx+8tTJoZeqYe2BZC1/JEU+wQR5TVEUPptJy3Fs+Vkzgf8lemqHumP1AnYoMZSwsVEz6o26i/G9Lgitb+ZmLu/YZtshfn5FZDPBCcJFQRQ+8ih9DctOFvdLIKHH6uUQnq9yhFu0bec7znZ+xpAGmuqef5/wd8hAyEDIQMjAETHwP7nQl2WnYk4yAAAAAElFTkSuQmCC'
1619sg .theme ("DarkAmber" )
20+
21+
1722# 设置控件属性
1823update_button = sg .Button ("更新版本" , key = "check_update" , size = 10 )
19- auto_live_check = sg .Button ("挂机模式" , key = "-isLiveNow-" )
24+ auto_live_check = sg .Button ("挂机模式" , key = "-isLiveNow-" , size = 14 )
2025ff_text = sg .Text ("设置ffmpeg路径" )
2126ff_input = sg .Input ("" , key = "ff" , size = 4 )
2227port_text = sg .Text ("输入代理端口" )
2631)
2732save_button = sg .Button ("保存配置" , key = "save_yaml" , size = 14 )
2833read_button = sg .Button ("使用配置" , key = "read_yaml" , size = 14 )
29-
34+ switch_button = sg .Button ('' , image_data = toggle_btn_off , key = '-TOGGLE-GRAPHIC-' ,
35+ button_color = (sg .theme_background_color (), sg .theme_background_color ()), border_width = 0 )
36+ switch_text = sg .Text ('本地m3u8中转: ' )
3037url_text = sg .Text ("输入youtube链接" )
31- url_input = sg .InputText (key = "url" , size = 6 )
38+ url_input = sg .InputText (key = "url" , size = 25 )
3239
33- m3u8_button = sg .Button ("获取直播信息" , size = 9 )
40+ m3u8_button = sg .Button ("获取直播信息" , size = 14 )
3441
3542key_text = sg .Text ("输入直播密钥" )
3643key_input = sg .InputText (key = "key" , size = 20 )
4148output_Ml = sg .Multiline (
4249 key = "Output" , disabled = True , size = (50 , 17 ), autoscroll = True , reroute_cprint = True
4350)
44- start_button = sg .Button ("开始直播" , size = 14 )
51+ start_button = sg .Button ("开始直播" , key = '-start_button-' , size = 14 )
4552stop_button = sg .Button ("停止推流" , visible = False , size = 14 )
4653format_list_text = sg .Text ("选择分辨率" )
4754format_list_selector = sg .Combo (
4855 format_list , key = "-SELECTOR-" , readonly = True , enable_events = True , size = 20
4956)
5057tilte_text = sg .Text ("" , key = "-title-" )
5158main_tab = [
52- [url_text , url_input , m3u8_button ],
59+ [url_text , url_input ],
60+ [m3u8_button , switch_text , switch_button ],
5361 [format_list_text , format_list_selector ],
5462 [start_button , stop_button ],
5563 [auto_live_check ],
@@ -136,12 +144,6 @@ def windows_init(window: sg.Window):
136144 call_window_event_value_with_delay (window , "获取直播信息" )
137145
138146
139- def wrap (string ):
140- cut_result = [string [i : i + 35 ] for i in range (0 , len (string ), 35 )]
141- result = "\n " .join (cut_result )
142- return result
143-
144-
145147# ---windows init and event loop
146148try :
147149 window = sg .Window ("QQ频道转播" , layout , finalize = True )
@@ -158,6 +160,10 @@ def wrap(string):
158160 y2qq .set_proxy (values ["port" ])
159161 except :
160162 sg .Popup ("请输入端口数字" )
163+ elif event == '-TOGGLE-GRAPHIC-' :
164+ graphic_off = not graphic_off
165+ window ['-TOGGLE-GRAPHIC-' ].update (
166+ image_data = toggle_btn_off if graphic_off else toggle_btn_on )
161167 elif event == "获取直播信息" :
162168 # 开启新进程获取直播信息
163169 window .perform_long_operation (
@@ -176,7 +182,7 @@ def wrap(string):
176182 call_window_event_value_with_delay (
177183 window , "-SELECTOR-" , format_list [- 1 ]
178184 )
179- title = wrap (formats_raw ["title" ][:- 17 ])
185+ title = textwrap . fill (formats_raw ["title" ][:- 17 ], 35 )
180186 window ["-title-" ].update (title )
181187 except :
182188 pass
@@ -190,27 +196,53 @@ def wrap(string):
190196
191197 g_current_m3u8_url = formats [index ]["url" ]
192198 sg .cprint (f"当前选择:{ g_current_selected_format } " )
193- elif event == "开始直播" :
199+ elif event == "-start_button-" :
200+ # 判断是否开启本地转发
201+ if graphic_off == False :
202+ try :
203+ btn_save_config_yaml (values , should_pop_up = False )
204+
205+ # 开启新进程 用于持续打印推流情况
206+ window .perform_long_operation (
207+ lambda : y2qq .restream (
208+ g_current_m3u8_url ,
209+ formats_raw ["id" ],
210+ g_current_selected_format ,
211+ values ["ff" ],
212+ values ["live_server" ],
213+ values ["key" ],
214+ ),
215+ "-restream-" ,
216+ )
217+ window ["停止推流" ].update (visible = True )
218+ except Exception as e :
219+ sg .Popup ("推流失败,检查密钥和ffmpeg是否配置正确" )
220+ else :
221+ try :
222+ btn_save_config_yaml (values , should_pop_up = False )
223+ # 开启新进程 用于持续打印推流情况
224+ window .perform_long_operation (
225+ lambda : y2qq .restream_direct (
226+ g_current_m3u8_url ,
227+ values ["ff" ],
228+ values ["key" ],
229+ ),
230+ "-restream-" ,
231+ )
232+ window ["停止推流" ].update (visible = True )
233+ except Exception as e :
234+ sg .Popup ("推流失败,检查密钥和ffmpeg是否配置正确" )
235+ elif event == "-start_button-" :
194236 try :
195- btn_save_config_yaml (values , should_pop_up = False )
196-
197- # 开启新进程 用于持续打印推流情况
198237 window .perform_long_operation (
199- lambda : y2qq .restream (
200- g_current_m3u8_url ,
201- formats_raw ["id" ],
202- g_current_selected_format ,
203- values ["ff" ],
204- values ["live_server" ],
205- values ["key" ],
206- ),
207- "-restream-" ,
208- )
238+ lambda : y2qq .restream_direct (g_current_m3u8_url , values ['ff' ], values ['key' ]), '-restream_direct-' )
209239 window ["停止推流" ].update (visible = True )
210- except Exception as e :
211- sg .Popup (" 推流失败,检查密钥和ffmpeg是否配置正确" )
240+ except :
241+ sg .Popup (' 推流失败,检查m3u8、密钥和ffmpeg是否配置正确' )
212242 elif event == "-restream-" :
213243 pass
244+ elif event == "-restream_direct-" :
245+ pass
214246 elif event == "-isLiveNow-" :
215247 window .perform_long_operation (
216248 lambda : y2qq .check_live (values ["url" ]), "-check-"
0 commit comments