Spaces:
Running
Running
Update watcher.py
Browse files- watcher.py +88 -34
watcher.py
CHANGED
|
@@ -229,6 +229,50 @@ def send_to_channel(text):
|
|
| 229 |
)
|
| 230 |
res.raise_for_status()
|
| 231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
# ===== Main =====
|
| 233 |
def main():
|
| 234 |
processed_messages = set() # 処理済みメッセージを追跡
|
|
@@ -279,48 +323,58 @@ def main():
|
|
| 279 |
youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
|
| 280 |
items, nonce = fetch_download_links(youtube_url)
|
| 281 |
|
| 282 |
-
if not
|
| 283 |
-
print("
|
| 284 |
time.sleep(10)
|
| 285 |
continue
|
| 286 |
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
time.sleep(10)
|
| 291 |
-
continue
|
| 292 |
-
|
| 293 |
-
# 画質情報を取得
|
| 294 |
-
quality_match = re.match(r"(\d+)p", video_item["quality"])
|
| 295 |
-
if not quality_match:
|
| 296 |
-
print("画質情報の取得に失敗しました")
|
| 297 |
-
time.sleep(10)
|
| 298 |
-
continue
|
| 299 |
-
|
| 300 |
-
quality = quality_match.group(1)
|
| 301 |
-
|
| 302 |
-
# 動画タイトル(簡易版 - 実際にはYouTubeから取得する方が良い)
|
| 303 |
-
video_title = f"youtube_video_{youtube_id}"
|
| 304 |
|
| 305 |
-
#
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
audio_item
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
|
| 320 |
# 処理済みとしてマーク
|
| 321 |
processed_messages.add(latest_msg.get("id"))
|
| 322 |
|
| 323 |
-
print("
|
| 324 |
|
| 325 |
except Exception as e:
|
| 326 |
print("エラー:", e)
|
|
|
|
| 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() # 処理済みメッセージを追跡
|
|
|
|
| 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)
|