Spaces:
Running
Running
video return
Browse files
gemini.py
CHANGED
|
@@ -31,6 +31,7 @@ from linebot.v3.webhooks import (
|
|
| 31 |
)
|
| 32 |
|
| 33 |
from PIL import Image
|
|
|
|
| 34 |
|
| 35 |
# === 初始化 Google Gemini ===
|
| 36 |
GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
|
|
@@ -194,7 +195,7 @@ def handle_image_message(event):
|
|
| 194 |
response = client.models.generate_content(
|
| 195 |
model="gemini-2.0-flash",
|
| 196 |
config=types.GenerateContentConfig(
|
| 197 |
-
system_instruction="
|
| 198 |
response_modalities=["TEXT"],
|
| 199 |
tools=[google_search_tool],
|
| 200 |
),
|
|
@@ -215,4 +216,52 @@ def handle_image_message(event):
|
|
| 215 |
TextMessage(text=response.text),
|
| 216 |
],
|
| 217 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
)
|
|
|
|
| 31 |
)
|
| 32 |
|
| 33 |
from PIL import Image
|
| 34 |
+
from linebot.v3.webhooks import VideoMessageContent
|
| 35 |
|
| 36 |
# === 初始化 Google Gemini ===
|
| 37 |
GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
|
|
|
|
| 195 |
response = client.models.generate_content(
|
| 196 |
model="gemini-2.0-flash",
|
| 197 |
config=types.GenerateContentConfig(
|
| 198 |
+
system_instruction="你是一個資深的面相命理師,如果有人上手掌的照片,就幫他解釋手相,如果上傳正面臉部的照片,就幫他解釋面相,照片要先去背,如果是一般的照片,就正常說明照片不用算命,請用繁體中文回答",
|
| 199 |
response_modalities=["TEXT"],
|
| 200 |
tools=[google_search_tool],
|
| 201 |
),
|
|
|
|
| 216 |
TextMessage(text=response.text),
|
| 217 |
],
|
| 218 |
)
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
# === 處理影片訊息 ===
|
| 222 |
+
|
| 223 |
+
@handler.add(MessageEvent, message=VideoMessageContent)
|
| 224 |
+
def handle_video_message(event):
|
| 225 |
+
# 下載影片內容
|
| 226 |
+
with ApiClient(configuration) as api_client:
|
| 227 |
+
blob_api = MessagingApiBlob(api_client)
|
| 228 |
+
content = blob_api.get_message_content(message_id=event.message.id)
|
| 229 |
+
|
| 230 |
+
# 儲存影片到本地
|
| 231 |
+
with tempfile.NamedTemporaryFile(
|
| 232 |
+
dir=static_tmp_path, suffix=".mp4", delete=False
|
| 233 |
+
) as tf:
|
| 234 |
+
tf.write(content)
|
| 235 |
+
filename = os.path.basename(tf.name)
|
| 236 |
+
|
| 237 |
+
video_url = f"https://{base_url}/images/{filename}"
|
| 238 |
+
app.logger.info(f"Video URL: {video_url}")
|
| 239 |
+
|
| 240 |
+
# 影片說明
|
| 241 |
+
try:
|
| 242 |
+
response = client.models.generate_content(
|
| 243 |
+
model="gemini-2.0-flash",
|
| 244 |
+
config=types.GenerateContentConfig(
|
| 245 |
+
system_instruction="你是一個專業的影片解說員,請用繁體中文簡要說明這段影片的內容。",
|
| 246 |
+
response_modalities=["TEXT"],
|
| 247 |
+
tools=[google_search_tool],
|
| 248 |
+
),
|
| 249 |
+
contents=[{"mime_type": "video/mp4", "data": content}, "用繁體中文描述這段影片"],
|
| 250 |
+
)
|
| 251 |
+
description = response.text
|
| 252 |
+
except Exception as e:
|
| 253 |
+
app.logger.error(f"Gemini API error (video): {e}")
|
| 254 |
+
description = "抱歉,無法解釋這段影片內容。"
|
| 255 |
+
|
| 256 |
+
# 回傳影片連結與說明
|
| 257 |
+
with ApiClient(configuration) as api_client:
|
| 258 |
+
line_bot_api = MessagingApi(api_client)
|
| 259 |
+
line_bot_api.reply_message(
|
| 260 |
+
ReplyMessageRequest(
|
| 261 |
+
reply_token=event.reply_token,
|
| 262 |
+
messages=[
|
| 263 |
+
TextMessage(text=f"影片連結:{video_url}"),
|
| 264 |
+
TextMessage(text=description),
|
| 265 |
+
],
|
| 266 |
+
)
|
| 267 |
)
|