izuemon commited on
Commit
d3eee05
·
verified ·
1 Parent(s): 0a64d30

Update watcher.py

Browse files
Files changed (1) hide show
  1. watcher.py +70 -16
watcher.py CHANGED
@@ -3,6 +3,7 @@ import re
3
  import time
4
  import json
5
  import requests
 
6
  from datetime import datetime, timezone
7
 
8
  # ===== Channel.io 設定 =====
@@ -32,9 +33,6 @@ HEADERS_POST = {
32
  "x-account": X_ACCOUNT,
33
  }
34
 
35
- # ===== Vidfly API =====
36
- VIDFLY_API = "https://api.vidfly.ai/api/media/youtube/download?url="
37
-
38
  # ===== Utils =====
39
  def parse_updated_at(value):
40
  if isinstance(value, (int, float)):
@@ -59,21 +57,77 @@ def extract_youtube_id(text):
59
  return m.group(1)
60
  return None
61
 
62
- def build_links(items):
63
- lines = []
64
- for item in items:
65
- url = item.get("url")
66
- ext = item.get("ext")
67
- height = item.get("height")
68
- media_type = item.get("type")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  if not url or not ext or not height:
71
  continue
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  label_type = "動画" if ext in ("mp4", "webm") else "音声"
74
  audio_suffix = " (音声付き)" if media_type == "video_with_audio" else ""
75
 
76
- line = f'<link type="url" value="{url}">{label_type}{audio_suffix} {height}p</link>'
 
 
 
 
77
  lines.append(line)
78
 
79
  return "\n".join(lines)
@@ -98,7 +152,7 @@ def send_to_channel(text):
98
  POST_URL,
99
  headers=HEADERS_POST,
100
  data=json.dumps(payload),
101
- timeout=30
102
  )
103
  res.raise_for_status()
104
 
@@ -146,17 +200,17 @@ def main():
146
  continue
147
 
148
  youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
149
- vidfly_res = requests.get(VIDFLY_API + youtube_url, timeout=30)
150
- vidfly_res.raise_for_status()
151
 
152
- items = vidfly_res.json().get("data", {}).get("items", [])
 
153
  if not items:
154
- print("Vidflyitems が空です")
155
  time.sleep(10)
156
  continue
157
 
158
  message_text = build_links(items)
159
  send_to_channel(message_text)
 
160
  print("送信完了")
161
 
162
  except Exception as e:
 
3
  import time
4
  import json
5
  import requests
6
+ import subprocess
7
  from datetime import datetime, timezone
8
 
9
  # ===== Channel.io 設定 =====
 
33
  "x-account": X_ACCOUNT,
34
  }
35
 
 
 
 
36
  # ===== Utils =====
37
  def parse_updated_at(value):
38
  if isinstance(value, (int, float)):
 
57
  return m.group(1)
58
  return None
59
 
60
+ # ===== yt-dlp =====
61
+ def fetch_formats_with_ytdlp(youtube_url):
62
+ """
63
+ yt-dlp を使って動画フォーマット一覧を取得
64
+ """
65
+ cmd = [
66
+ "yt-dlp",
67
+ "-j",
68
+ "--no-playlist",
69
+ youtube_url,
70
+ ]
71
+
72
+ proc = subprocess.run(
73
+ cmd,
74
+ stdout=subprocess.PIPE,
75
+ stderr=subprocess.PIPE,
76
+ text=True,
77
+ )
78
+
79
+ if proc.returncode != 0:
80
+ raise RuntimeError(proc.stderr)
81
+
82
+ info = json.loads(proc.stdout)
83
+ formats = info.get("formats", [])
84
+
85
+ items = []
86
+ for f in formats:
87
+ url = f.get("url")
88
+ ext = f.get("ext")
89
+ height = f.get("height")
90
+ vcodec = f.get("vcodec")
91
+ acodec = f.get("acodec")
92
 
93
  if not url or not ext or not height:
94
  continue
95
 
96
+ media_type = (
97
+ "video_with_audio"
98
+ if vcodec != "none" and acodec != "none"
99
+ else "video"
100
+ )
101
+
102
+ items.append({
103
+ "url": url,
104
+ "ext": ext,
105
+ "height": height,
106
+ "type": media_type,
107
+ })
108
+
109
+ return items
110
+
111
+ def build_links(items):
112
+ lines = []
113
+
114
+ # 高画質順に並び替え
115
+ items = sorted(items, key=lambda x: x["height"], reverse=True)
116
+
117
+ for item in items:
118
+ url = item["url"]
119
+ ext = item["ext"]
120
+ height = item["height"]
121
+ media_type = item["type"]
122
+
123
  label_type = "動画" if ext in ("mp4", "webm") else "音声"
124
  audio_suffix = " (音声付き)" if media_type == "video_with_audio" else ""
125
 
126
+ line = (
127
+ f'<link type="url" value="{url}">'
128
+ f'{label_type}{audio_suffix} {height}p'
129
+ f'</link>'
130
+ )
131
  lines.append(line)
132
 
133
  return "\n".join(lines)
 
152
  POST_URL,
153
  headers=HEADERS_POST,
154
  data=json.dumps(payload),
155
+ timeout=30,
156
  )
157
  res.raise_for_status()
158
 
 
200
  continue
201
 
202
  youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
 
 
203
 
204
+ # ===== yt-dlp URL 取得 =====
205
+ items = fetch_formats_with_ytdlp(youtube_url)
206
  if not items:
207
+ print("yt-dlpformats が空です")
208
  time.sleep(10)
209
  continue
210
 
211
  message_text = build_links(items)
212
  send_to_channel(message_text)
213
+
214
  print("送信完了")
215
 
216
  except Exception as e: