izuemon commited on
Commit
50a73f4
·
verified ·
1 Parent(s): 7bc8d92

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -59
app.py CHANGED
@@ -3,9 +3,10 @@ import re
3
  import time
4
  import json
5
  import requests
6
- import subprocess
7
  from datetime import datetime, timezone
8
  from bs4 import BeautifulSoup
 
 
9
 
10
  # ===== Channel.io 設定 =====
11
  GET_URL = "https://desk-api.channel.io/desk/channels/200605/groups/519217/messages"
@@ -37,12 +38,6 @@ HEADERS_POST = {
37
  # ===== ssyoutube =====
38
  SSYOUTUBE_URL = "https://ssyoutube.online/yt-video-detail/"
39
 
40
- # ===== tflink =====
41
- TFLINK_UPLOAD_URL = "https://tflink.example/upload" # ここを実際のURLに置き換え
42
- TFLINK_API_KEY = os.getenv("TFLINK_API_KEY")
43
- if not TFLINK_API_KEY:
44
- raise RuntimeError("環境変数 TFLINK_API_KEY が設定されていません")
45
-
46
  # ===== Utils =====
47
  def parse_updated_at(value):
48
  if isinstance(value, (int, float)):
@@ -81,8 +76,8 @@ def fetch_download_links(youtube_url):
81
  results = []
82
  for btn in buttons:
83
  url = btn.get("data-url")
84
- quality = btn.get("data-quality")
85
- has_audio = btn.get("data-has-audio")
86
 
87
  if not url:
88
  continue
@@ -95,44 +90,36 @@ def fetch_download_links(youtube_url):
95
 
96
  return results
97
 
98
- # ===== ファイル操作 =====
99
  def download_file(url, filename):
100
- res = requests.get(url, stream=True)
101
- res.raise_for_status()
102
- with open(filename, "wb") as f:
103
- for chunk in res.iter_content(chunk_size=8192):
104
- f.write(chunk)
105
-
106
- # ===== ffmpeg 結合 =====
107
- def merge_video_audio(video_path, audio_path, output_path):
108
- cmd = [
109
- "ffmpeg", "-y",
110
- "-i", video_path,
111
- "-i", audio_path,
112
- "-c:v", "copy",
113
- "-c:a", "aac",
114
- output_path
115
- ]
116
- subprocess.run(cmd, check=True)
117
-
118
- # ===== tflink アップロード =====
119
- def upload_to_tflink(filepath):
120
- with open(filepath, "rb") as f:
121
- res = requests.post(
122
- TFLINK_UPLOAD_URL,
123
- headers={"Authorization": f"Bearer {TFLINK_API_KEY}"},
124
- files={"file": f},
125
- )
126
- res.raise_for_status()
127
- data = res.json()
128
- return data.get("url")
129
-
130
- # ===== Channel.io 送信 =====
131
  def send_to_channel(text):
132
  payload = {
133
  "requestId": f"desk-web-{int(time.time() * 1000)}",
134
  "blocks": [
135
- {"type": "text", "value": text}
 
 
 
136
  ],
137
  "buttons": None,
138
  "form": None,
@@ -149,11 +136,15 @@ def send_to_channel(text):
149
  )
150
  res.raise_for_status()
151
 
152
- # ===== Main =====
153
  def main():
154
  while True:
155
  try:
156
- res = requests.get(GET_URL, headers=HEADERS_GET, params=PARAMS, timeout=30)
 
 
 
 
 
157
  res.raise_for_status()
158
 
159
  messages = res.json().get("messages", [])
@@ -186,35 +177,39 @@ def main():
186
  continue
187
 
188
  youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
 
189
  items = fetch_download_links(youtube_url)
 
 
 
 
190
 
191
- video_items = [i for i in items if i['has_audio'] == 'false']
192
- audio_items = [i for i in items if i['has_audio'] == 'true' and i['quality'] == 'audio']
 
193
 
194
  if not video_items or not audio_items:
195
- print("必要な動画/音声が取得できませんでした")
196
  time.sleep(10)
197
  continue
198
 
199
- # 高画質の動画選択
200
- video_items.sort(key=lambda x: int(re.sub(r'[^0-9]', '', x['quality'])), reverse=True)
201
- video_url = video_items[0]['url']
202
- audio_url = audio_items[0]['url']
203
-
204
- video_file = "video.mp4"
205
- audio_file = "audio.m4a"
206
- output_file = "output.mp4"
207
 
208
- download_file(video_url, video_file)
209
- download_file(audio_url, audio_file)
 
210
 
211
  merge_video_audio(video_file, audio_file, output_file)
212
 
 
213
  tflink_url = upload_to_tflink(output_file)
214
 
215
- message_text = f"結合済み動画はこちら: {tflink_url}"
216
  send_to_channel(message_text)
217
- print("送信完了")
218
 
219
  except Exception as e:
220
  print("エラー:", e)
 
3
  import time
4
  import json
5
  import requests
 
6
  from datetime import datetime, timezone
7
  from bs4 import BeautifulSoup
8
+ import ffmpeg
9
+ from tflink import TFLinkClient
10
 
11
  # ===== Channel.io 設定 =====
12
  GET_URL = "https://desk-api.channel.io/desk/channels/200605/groups/519217/messages"
 
38
  # ===== ssyoutube =====
39
  SSYOUTUBE_URL = "https://ssyoutube.online/yt-video-detail/"
40
 
 
 
 
 
 
 
41
  # ===== Utils =====
42
  def parse_updated_at(value):
43
  if isinstance(value, (int, float)):
 
76
  results = []
77
  for btn in buttons:
78
  url = btn.get("data-url")
79
+ quality = btn.get("data-quality") # 例: 1080p / 720p / None
80
+ has_audio = btn.get("data-has-audio") # "true" / "false" / None
81
 
82
  if not url:
83
  continue
 
90
 
91
  return results
92
 
 
93
  def download_file(url, filename):
94
+ with requests.get(url, stream=True) as r:
95
+ r.raise_for_status()
96
+ with open(filename, 'wb') as f:
97
+ for chunk in r.iter_content(chunk_size=8192):
98
+ f.write(chunk)
99
+ return filename
100
+
101
+ def merge_video_audio(video_file, audio_file, output_file):
102
+ (
103
+ ffmpeg
104
+ .input(video_file)
105
+ .output(audio_file, output_file, vcodec='copy', acodec='aac', strict='experimental')
106
+ .run(overwrite_output=True)
107
+ )
108
+ return output_file
109
+
110
+ def upload_to_tflink(file_path):
111
+ client = TFLinkClient()
112
+ result = client.upload(file_path)
113
+ return result.download_link
114
+
 
 
 
 
 
 
 
 
 
 
115
  def send_to_channel(text):
116
  payload = {
117
  "requestId": f"desk-web-{int(time.time() * 1000)}",
118
  "blocks": [
119
+ {
120
+ "type": "text",
121
+ "value": text
122
+ }
123
  ],
124
  "buttons": None,
125
  "form": None,
 
136
  )
137
  res.raise_for_status()
138
 
 
139
  def main():
140
  while True:
141
  try:
142
+ res = requests.get(
143
+ GET_URL,
144
+ headers=HEADERS_GET,
145
+ params=PARAMS,
146
+ timeout=30,
147
+ )
148
  res.raise_for_status()
149
 
150
  messages = res.json().get("messages", [])
 
177
  continue
178
 
179
  youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
180
+
181
  items = fetch_download_links(youtube_url)
182
+ if not items:
183
+ print("ダウンロードリンクが取得できませんでした")
184
+ time.sleep(10)
185
+ continue
186
 
187
+ # ===== 最も高画質の動画と音声を選択 =====
188
+ video_items = [i for i in items if i["has_audio"] == "false"]
189
+ audio_items = [i for i in items if i["has_audio"] == "true" and i["quality"] == "audio"]
190
 
191
  if not video_items or not audio_items:
192
+ print("動画または音声が見つかりません")
193
  time.sleep(10)
194
  continue
195
 
196
+ # 解像度順にソートして最初取得
197
+ video_items.sort(key=lambda x: int(re.sub(r"\D", "", x["quality"] or "0")), reverse=True)
198
+ video_url = video_items[0]["url"]
199
+ audio_url = audio_items[0]["url"]
 
 
 
 
200
 
201
+ video_file = download_file(video_url, "video.mp4")
202
+ audio_file = download_file(audio_url, "audio.m4a")
203
+ output_file = "merged.mp4"
204
 
205
  merge_video_audio(video_file, audio_file, output_file)
206
 
207
+ # tflink にアップロード
208
  tflink_url = upload_to_tflink(output_file)
209
 
210
+ message_text = f"結合動画のダウンロード: {tflink_url}"
211
  send_to_channel(message_text)
212
+ print("送信完了:", tflink_url)
213
 
214
  except Exception as e:
215
  print("エラー:", e)