izuemon commited on
Commit
523da2d
·
verified ·
1 Parent(s): ccdf8b7

Update watcher.py

Browse files
Files changed (1) hide show
  1. watcher.py +88 -94
watcher.py CHANGED
@@ -2,9 +2,6 @@ import os
2
  import re
3
  import time
4
  import json
5
- import shutil
6
- import tempfile
7
- import subprocess
8
  import requests
9
  from datetime import datetime, timezone
10
  from bs4 import BeautifulSoup
@@ -58,6 +55,18 @@ def extract_youtube_id(text):
58
  return m.group(1)
59
  return None
60
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  # ===== ssyoutube HTML 解析 =====
62
  def fetch_download_links(youtube_url):
63
  res = requests.post(
@@ -98,21 +107,28 @@ def fetch_download_links(youtube_url):
98
  # ===== 最高画質映像 + 音声を選択 =====
99
  def select_best_video_and_audio(items):
100
  video_items = []
101
- audio_item = None
102
 
103
  for item in items:
104
  if item["quality"] == "audio":
105
- audio_item = item
106
  elif item["has_audio"] == "false":
107
  m = re.match(r"(\d+)p", item["quality"])
108
  if m:
109
  video_items.append((int(m.group(1)), item))
110
 
111
- if not video_items or not audio_item:
112
  return None, None
113
 
 
114
  video_items.sort(key=lambda x: x[0], reverse=True)
115
- return video_items[0][1], audio_item
 
 
 
 
 
 
116
 
117
  # ===== ssyoutube サーバー側結合 =====
118
  def merge_video_on_server(video_url, audio_url, video_id, quality, video_title, nonce):
@@ -229,50 +245,6 @@ def send_to_channel(text):
229
  )
230
  res.raise_for_status()
231
 
232
- # ===== ダウンロードリンクを整理して表示 =====
233
- def format_download_links(items):
234
- """
235
- ダウンロードリンクを整理してフォーマットする
236
- """
237
- # 画質順にソート
238
- video_items = []
239
- audio_items = []
240
-
241
- for item in items:
242
- if item["quality"] == "audio":
243
- audio_items.append(item)
244
- else:
245
- m = re.match(r"(\d+)p", item["quality"])
246
- if m:
247
- video_items.append((int(m.group(1)), item))
248
-
249
- # 画質の高い順にソート
250
- video_items.sort(key=lambda x: x[0], reverse=True)
251
-
252
- # メッセージ作成
253
- lines = ["📥 利用可能なダウンロードリンク:"]
254
-
255
- # 映像リンク(音声付き)
256
- video_with_audio = [item for item in items if item.get("has_audio") == "true" and item["quality"] != "audio"]
257
- if video_with_audio:
258
- lines.append("\n🎬 映像+音声(単一ファイル):")
259
- for item in video_with_audio:
260
- lines.append(f" • {item['quality']}: {item['url']}")
261
-
262
- # 映像のみリンク
263
- if video_items:
264
- lines.append("\n📹 映像のみ(高画質):")
265
- for quality, item in video_items:
266
- lines.append(f" • {item['quality']}: {item['url']}")
267
-
268
- # 音声のみリンク
269
- if audio_items:
270
- lines.append("\n🎵 音声のみ:")
271
- for item in audio_items:
272
- lines.append(f" • {item['quality']}: {item['url']}")
273
-
274
- return "\n".join(lines)
275
-
276
  # ===== Main =====
277
  def main():
278
  processed_messages = set() # 処理済みメッセージを追跡
@@ -321,60 +293,82 @@ def main():
321
  continue
322
 
323
  youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
 
 
 
 
324
  items, nonce = fetch_download_links(youtube_url)
325
 
326
- if not items:
327
- print("ダウンロードリンクが見つかりません")
328
  time.sleep(10)
329
  continue
330
 
331
- # 1. すべてのダウンロードリンクを送信
332
- download_links_message = format_download_links(items)
333
- send_to_channel(download_links_message)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
- # 2. 最高画質の映像と音声を結合(オプション)
336
- if nonce:
337
- video_item, audio_item = select_best_video_and_audio(items)
 
 
 
 
 
 
338
 
339
- if video_item and audio_item:
340
- # 画質情報を取得
341
- quality_match = re.match(r"(\d+)p", video_item["quality"])
342
- if quality_match:
343
- quality = quality_match.group(1)
344
-
345
- # 動画タイトル(簡易版)
346
- video_title = f"youtube_video_{youtube_id}"
347
-
348
- # 結合処理開始メッセージを送信
349
- send_to_channel(f"🔄 最高画質({quality}p)の動画と音声を結合中... しばらくお待ちください。")
350
-
351
- try:
352
- # サーバー側で結合
353
- print(f"サーバー側での結合を開始します: {youtube_id} {quality}p")
354
- merged_url = merge_video_on_server(
355
- video_item["url"],
356
- audio_item["url"],
357
- youtube_id,
358
- quality,
359
- video_title,
360
- nonce
361
- )
362
-
363
- # 結合済み動画のリンクを送信
364
- merged_message = f" 結合完了!最高画質({quality}p)の動画:\n{merged_url}"
365
- send_to_channel(merged_message)
366
-
367
- print("結合完了:", merged_url)
368
-
369
- except Exception as merge_error:
370
- error_message = f"⚠️ 結合処理中にエラーが発生しました: {str(merge_error)}"
371
- send_to_channel(error_message)
372
- print("結合エラー:", merge_error)
373
 
374
  # 処理済みとしてマーク
375
  processed_messages.add(latest_msg.get("id"))
376
 
377
- print(f"処理完了: {youtube_id}")
378
 
379
  except Exception as e:
380
  print("エラー:", e)
 
2
  import re
3
  import time
4
  import json
 
 
 
5
  import requests
6
  from datetime import datetime, timezone
7
  from bs4 import BeautifulSoup
 
55
  return m.group(1)
56
  return None
57
 
58
+ def get_video_title(youtube_url):
59
+ """YouTube動画のタイトルを取得する簡易的な関数"""
60
+ try:
61
+ res = requests.get(youtube_url, timeout=10)
62
+ soup = BeautifulSoup(res.text, "lxml")
63
+ title_tag = soup.find("meta", property="og:title")
64
+ if title_tag:
65
+ return title_tag.get("content", "").replace(" - YouTube", "")
66
+ except:
67
+ pass
68
+ return "YouTube動画"
69
+
70
  # ===== ssyoutube HTML 解析 =====
71
  def fetch_download_links(youtube_url):
72
  res = requests.post(
 
107
  # ===== 最高画質映像 + 音声を選択 =====
108
  def select_best_video_and_audio(items):
109
  video_items = []
110
+ audio_items = []
111
 
112
  for item in items:
113
  if item["quality"] == "audio":
114
+ audio_items.append(item)
115
  elif item["has_audio"] == "false":
116
  m = re.match(r"(\d+)p", item["quality"])
117
  if m:
118
  video_items.append((int(m.group(1)), item))
119
 
120
+ if not video_items or not audio_items:
121
  return None, None
122
 
123
+ # 最高画質の動画を選択
124
  video_items.sort(key=lambda x: x[0], reverse=True)
125
+ best_video = video_items[0][1]
126
+
127
+ # 最高音質の音声を選択(例: 128kbps > 64kbps)
128
+ # 実際の音声品質情報に基づいて選択する場合は要修正
129
+ best_audio = audio_items[0] if audio_items else None
130
+
131
+ return best_video, best_audio
132
 
133
  # ===== ssyoutube サーバー側結合 =====
134
  def merge_video_on_server(video_url, audio_url, video_id, quality, video_title, nonce):
 
245
  )
246
  res.raise_for_status()
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  # ===== Main =====
249
  def main():
250
  processed_messages = set() # 処理済みメッセージを追跡
 
293
  continue
294
 
295
  youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
296
+
297
+ # 動画タイトルを取得
298
+ video_title = get_video_title(youtube_url)
299
+
300
  items, nonce = fetch_download_links(youtube_url)
301
 
302
+ if not nonce:
303
+ print("nonceの取得に失敗しました")
304
  time.sleep(10)
305
  continue
306
 
307
+ # すべてのダウンロードリンクを収集
308
+ video_items = []
309
+ audio_items = []
310
+ all_items = []
311
+
312
+ for item in items:
313
+ all_items.append(item)
314
+ if item["quality"] == "audio":
315
+ audio_items.append(item)
316
+ elif item["has_audio"] == "false":
317
+ video_items.append(item)
318
+
319
+ # 最高画質の動画と音声を選択
320
+ best_video, best_audio = select_best_video_and_audio(items)
321
+
322
+ # メッセージを構築
323
+ message_lines = []
324
+ message_lines.append(f"**{video_title}**\n")
325
+ message_lines.append("**ダウンロードリンク:**")
326
 
327
+ # すべての動画リンクを追加
328
+ for item in all_items:
329
+ quality = item["quality"]
330
+ if item["quality"] == "audio":
331
+ quality_display = "音声"
332
+ elif item["has_audio"] == "true":
333
+ quality_display = f"{quality} (音声付き)"
334
+ else:
335
+ quality_display = f"{quality} (映像のみ)"
336
 
337
+ message_lines.append(f"• {quality_display}: {item['url']}")
338
+
339
+ # 最高画質の結合動画を作成
340
+ if best_video and best_audio and nonce:
341
+ message_lines.append("\n **最高画質結合動画 (処理中):**")
342
+
343
+ # 画質情報を取得
344
+ quality_match = re.match(r"(\d+)p", best_video["quality"])
345
+ if quality_match:
346
+ quality = quality_match.group(1)
347
+
348
+ # サーバー側で結合
349
+ print(f"サーバー側での結合を開始します: {youtube_id} {quality}p")
350
+ try:
351
+ merged_url = merge_video_on_server(
352
+ best_video["url"],
353
+ best_audio["url"],
354
+ youtube_id,
355
+ quality,
356
+ video_title,
357
+ nonce
358
+ )
359
+ message_lines.append(f"{quality}p 結合済み動画: {merged_url}")
360
+ except Exception as e:
361
+ print(f"結合処理エラー: {e}")
362
+ message_lines.append(f"結合処理に失敗: {str(e)}")
363
+
364
+ # メッセージを送信
365
+ message = "\n".join(message_lines)
366
+ send_to_channel(message)
 
 
 
 
367
 
368
  # 処理済みとしてマーク
369
  processed_messages.add(latest_msg.get("id"))
370
 
371
+ print(f"送信完了: {youtube_id}")
372
 
373
  except Exception as e:
374
  print("エラー:", e)