Spaces:
Running
Running
Speed up rewrite: background short-video generation; topic_post text-only Qwen (no image input)
Browse files
ai_ext.py
CHANGED
|
@@ -829,6 +829,33 @@ async def _generate_short_video(post, post_id: str, voice_id: str = None, speed:
|
|
| 829 |
print(f"[short video error] {e}")
|
| 830 |
return ""
|
| 831 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 832 |
# ===== MAKE POST =====
|
| 833 |
def make_post(title, text, image, source_url, kind, sources=None, images=None, voice=None, emotion=None):
|
| 834 |
# Auto-pick voice + emotion from the article topic when not provided
|
|
@@ -913,14 +940,12 @@ async def api_rewrite_share(request: Request):
|
|
| 913 |
images[0] if images else data.get("image", ""),
|
| 914 |
url, "rewrite", images=images)
|
| 915 |
|
| 916 |
-
#
|
| 917 |
-
|
| 918 |
-
if video_url:
|
| 919 |
-
post["video"] = video_url
|
| 920 |
-
|
| 921 |
posts = _load_wall()
|
| 922 |
posts.insert(0, post)
|
| 923 |
_save_wall(posts)
|
|
|
|
| 924 |
return JSONResponse({"post": post})
|
| 925 |
|
| 926 |
|
|
@@ -948,13 +973,10 @@ async def api_url_wall(request: Request):
|
|
| 948 |
images[0] if images else data.get("image", ""),
|
| 949 |
url, "url", images=images)
|
| 950 |
|
| 951 |
-
video_url = await _generate_short_video(post, post["id"])
|
| 952 |
-
if video_url:
|
| 953 |
-
post["video"] = video_url
|
| 954 |
-
|
| 955 |
posts = _load_wall()
|
| 956 |
posts.insert(0, post)
|
| 957 |
_save_wall(posts)
|
|
|
|
| 958 |
return JSONResponse({"post": post})
|
| 959 |
|
| 960 |
|
|
@@ -971,19 +993,20 @@ async def api_topic_post(request: Request):
|
|
| 971 |
|
| 972 |
image = pollinations_image_url(topic)
|
| 973 |
prompt = _build_topic_prompt(topic, ctx)
|
| 974 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 975 |
if not text:
|
| 976 |
return JSONResponse({"error": "Qwen2.5-VL chưa sẵn sàng: " + LAST_QWEN_ERROR}, status_code=503)
|
| 977 |
text = _clean_ai_output(text)
|
| 978 |
post = make_post(topic, text, image, "", "topic")
|
| 979 |
|
| 980 |
-
video_url = await _generate_short_video(post, post["id"])
|
| 981 |
-
if video_url:
|
| 982 |
-
post["video"] = video_url
|
| 983 |
-
|
| 984 |
posts = _load_wall()
|
| 985 |
posts.insert(0, post)
|
| 986 |
_save_wall(posts)
|
|
|
|
| 987 |
return JSONResponse({"post": post})
|
| 988 |
|
| 989 |
|
|
|
|
| 829 |
print(f"[short video error] {e}")
|
| 830 |
return ""
|
| 831 |
|
| 832 |
+
import threading as _threading
|
| 833 |
+
def _spawn_background_video(post):
|
| 834 |
+
"""Generate the short video in a BACKGROUND thread so the rewrite/topic endpoint
|
| 835 |
+
can return immediately. When done, persist the video URL onto the wall post.
|
| 836 |
+
This is the main fix for 'rewrite tu cac nguon tin qua lau' — the user gets the
|
| 837 |
+
text post instantly; the video appears shortly after (or via the 'Tao Video' button)."""
|
| 838 |
+
pid = post.get("id")
|
| 839 |
+
if not pid:
|
| 840 |
+
return
|
| 841 |
+
def _run():
|
| 842 |
+
try:
|
| 843 |
+
loop = asyncio.new_event_loop()
|
| 844 |
+
asyncio.set_event_loop(loop)
|
| 845 |
+
video_url = loop.run_until_complete(_generate_short_video(post, pid))
|
| 846 |
+
loop.close()
|
| 847 |
+
if video_url:
|
| 848 |
+
posts = _load_wall()
|
| 849 |
+
for i, p in enumerate(posts):
|
| 850 |
+
if str(p.get("id")) == str(pid):
|
| 851 |
+
posts[i]["video"] = video_url
|
| 852 |
+
break
|
| 853 |
+
_save_wall(posts)
|
| 854 |
+
print(f"[bg-video] done {pid} -> {video_url}")
|
| 855 |
+
except Exception as e:
|
| 856 |
+
print(f"[bg-video] error {pid}: {e}")
|
| 857 |
+
_threading.Thread(target=_run, daemon=True).start()
|
| 858 |
+
|
| 859 |
# ===== MAKE POST =====
|
| 860 |
def make_post(title, text, image, source_url, kind, sources=None, images=None, voice=None, emotion=None):
|
| 861 |
# Auto-pick voice + emotion from the article topic when not provided
|
|
|
|
| 940 |
images[0] if images else data.get("image", ""),
|
| 941 |
url, "rewrite", images=images)
|
| 942 |
|
| 943 |
+
# Save post and return IMMEDIATELY; generate the short video in the background
|
| 944 |
+
# (so rewrite is fast). Video appears on the wall when ready / via 'Tao Video' button.
|
|
|
|
|
|
|
|
|
|
| 945 |
posts = _load_wall()
|
| 946 |
posts.insert(0, post)
|
| 947 |
_save_wall(posts)
|
| 948 |
+
_spawn_background_video(post)
|
| 949 |
return JSONResponse({"post": post})
|
| 950 |
|
| 951 |
|
|
|
|
| 973 |
images[0] if images else data.get("image", ""),
|
| 974 |
url, "url", images=images)
|
| 975 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 976 |
posts = _load_wall()
|
| 977 |
posts.insert(0, post)
|
| 978 |
_save_wall(posts)
|
| 979 |
+
_spawn_background_video(post)
|
| 980 |
return JSONResponse({"post": post})
|
| 981 |
|
| 982 |
|
|
|
|
| 993 |
|
| 994 |
image = pollinations_image_url(topic)
|
| 995 |
prompt = _build_topic_prompt(topic, ctx)
|
| 996 |
+
# NOTE: do NOT pass the decorative pollinations image to the VL model — feeding an
|
| 997 |
+
# image makes Qwen2.5-VL much slower (it must download+process it) with no benefit for
|
| 998 |
+
# a text summary. We keep the image only for display on the post. This is a major
|
| 999 |
+
# speed-up for 'rewrite tong hop'. (Text-only inference is several times faster.)
|
| 1000 |
+
text = await qwen_generate(prompt, max_tokens=500)
|
| 1001 |
if not text:
|
| 1002 |
return JSONResponse({"error": "Qwen2.5-VL chưa sẵn sàng: " + LAST_QWEN_ERROR}, status_code=503)
|
| 1003 |
text = _clean_ai_output(text)
|
| 1004 |
post = make_post(topic, text, image, "", "topic")
|
| 1005 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1006 |
posts = _load_wall()
|
| 1007 |
posts.insert(0, post)
|
| 1008 |
_save_wall(posts)
|
| 1009 |
+
_spawn_background_video(post)
|
| 1010 |
return JSONResponse({"post": post})
|
| 1011 |
|
| 1012 |
|