XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Add video provider

b7d1a03d
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

7 个文件 +171 -13
Added g4f/Provider/needs_auth/Video.py +149 -0
@@ -0,0 +1,149 @@
1 from __future__ import annotations
2
3 import asyncio
4 import random
5 from aiohttp import ClientSession, ClientTimeout
6
7 from urllib.parse import quote, quote_plus
8 from aiohttp import ClientSession
9
10 from ...typing import Messages, AsyncResult
11 from ...providers.response import VideoResponse
12 from ...requests import get_nodriver, nodriver
13 from ...errors import MissingRequirementsError
14 from ..base_provider import AsyncGeneratorProvider
15 from ..helper import format_media_prompt
16 from ... import debug
17
18 browser = None
19 stop_browser = None
20
21 class RequestConfig:
22 urls: list[str] = []
23 headers: dict = {}
24
25 class Video(AsyncGeneratorProvider):
26 urls = [
27 "https://sora.chatgpt.com/explore",
28 #"https://aistudio.google.com/generate-video"
29 ]
30 api_url = "http:/bore.pub:40346/backend-api/v2/create"
31 search_url = "http://bore.pub:40346/search/video+{prompt}"
32 drive_url = "https://www.googleapis.com/drive/v3/"
33
34 needs_auth = True
35 working = True
36
37 browser = None
38 stop_browser = None
39
40 @classmethod
41 async def create_async_generator(
42 cls,
43 model: str,
44 messages: Messages,
45 proxy: str = None,
46 prompt: str = None,
47 **kwargs
48 ) -> AsyncResult:
49 prompt = format_media_prompt(messages, prompt)
50 global browser, stop_browser
51 try:
52 if browser is None:
53 browser, stop_browser = await get_nodriver(proxy=proxy, user_data_dir="gemini")
54 except Exception as e:
55 debug.error(f"Error getting nodriver:", e)
56 async with ClientSession() as session:
57 async with session.get(cls.search_url.format(prompt=quote_plus(prompt)), timeout=ClientTimeout(total=10)) as response:
58 if response.status == 200:
59 if response.headers.get("content-type", "text/plain").startswith("text/pain"):
60 data = (await response.text()).split("\n")
61 yield VideoResponse(data, prompt)
62 return
63 yield VideoResponse(str(response.url), prompt)
64 return
65 async with session.post(cls.api_url.format(prompt=quote(prompt)), timeout=ClientTimeout(total=10)) as response:
66 if response.status != 200:
67 debug.error(f"Failed to connect to Video API: {response.status}")
68 else:
69 yield VideoResponse(str(response.url), prompt)
70 return
71 raise MissingRequirementsError("Video provider requires a browser to be installed.")
72 RequestConfig.urls = []
73 try:
74 page = await browser.get(random.choice(cls.urls))
75 await asyncio.sleep(3)
76 await page.select("textarea", 240)
77 def on_request(event: nodriver.cdp.network.RequestWillBeSent, page=None):
78 if "mp4" in event.request.url:
79 RequestConfig.headers = {}
80 for key, value in event.request.headers.items():
81 RequestConfig.headers[key.lower()] = value
82 RequestConfig.urls.append(event.request.url)
83 elif event.request.url.startswith(cls.drive_url):
84 RequestConfig.headers = {}
85 for key, value in event.request.headers.items():
86 RequestConfig.headers[key.lower()] = value
87 RequestConfig.urls.append(event.request.url)
88 await page.send(nodriver.cdp.network.enable())
89 page.add_handler(nodriver.cdp.network.RequestWillBeSent, on_request)
90
91 try:
92 button = await page.find("Image")
93 if button:
94 await button.click()
95 else:
96 debug.error("No 'Image' button found.")
97 button = await page.find("Video")
98 if button:
99 await button.click()
100 else:
101 debug.error("No 'Video' button found.")
102 except Exception as e:
103 debug.error(f"Error clicking button:", e)
104 debug.log(f"Using prompt: {prompt}")
105 textarea = await page.select("textarea", 180)
106 await textarea.send_keys(prompt)
107 # try:
108 # button = await page.select('button[type="submit"]', 5)
109 # if button:
110 # await button.click()
111 # finally:
112 try:
113 button = await page.find("Create")
114 if button:
115 await button.click()
116 except Exception as e:
117 debug.error(f"Error clicking 'Create' button:", e)
118 try:
119 button = await page.find("Activity")
120 if button:
121 await button.click()
122 except Exception as e:
123 debug.error(f"Error clicking 'Activity' button:", e)
124 try:
125 await asyncio.sleep(5)
126 button = await page.find("Queued", timeout=30)
127 if button:
128 await button.click()
129 except Exception as e:
130 debug.error(f"Error clicking 'Queued' button:", e)
131 debug.log(f"Waiting for Video URL...")
132 for idx in range(600):
133 await asyncio.sleep(1)
134 if RequestConfig.urls:
135 await asyncio.sleep(2)
136 RequestConfig.urls = list(set(RequestConfig.urls))
137 debug.log(f"Video URL: {RequestConfig.urls}")
138 yield VideoResponse(RequestConfig.urls, prompt, {
139 "headers": {"authorization": RequestConfig.headers.get("authorization")} if RequestConfig.headers.get("authorization") else {}
140 })
141 RequestConfig.urls = []
142 break
143 if idx == 599:
144 raise RuntimeError("Failed to get Video URL")
145 except Exception as e:
146 stop_browser()
147 raise e
148 await page.close()
149 stop_browser()
Modified g4f/Provider/needs_auth/__init__.py +1 -0
@@ -31,5 +31,6 @@ from .Reka import Reka
31 31 from .Replicate import Replicate
32 32 from .ThebApi import ThebApi
33 33 from .WhiteRabbitNeo import WhiteRabbitNeo
34 from .Video import Video
34 35 from .xAI import xAI
35 36 from .You import You
Modified g4f/api/__init__.py +4 -1
@@ -647,7 +647,10 @@ class Api:
647 647 @self.app.post("/v1/upload_cookies", responses={
648 648 HTTP_200_OK: {"model": List[FileResponseModel]},
649 649 })
650 def upload_cookies(files: List[UploadFile]):
650 def upload_cookies(
651 files: List[UploadFile],
652 credentials: Annotated[HTTPAuthorizationCredentials, Depends(Api.security)] = None
653 ):
651 654 response_data = []
652 655 if not AppConfig.ignore_cookie_files:
653 656 for file in files:
Modified g4f/cookies.py +2 -2
@@ -33,8 +33,8 @@ try:
33 33 return [] if not os.path.exists(cookie_file) else chrome(cookie_file, domain_name)
34 34
35 35 browsers = [
36 g4f,
37 chrome, chromium, firefox, opera, opera_gx,
36 g4f, firefox,
37 chrome, chromium, opera, opera_gx,
38 38 brave, edge, vivaldi,
39 39 ]
40 40 has_browser_cookie3 = True
Modified g4f/gui/server/backend_api.py +8 -8
@@ -256,13 +256,13 @@ class Backend_Api(Api):
256 256 if len(buffer.get_list()) == 1:
257 257 if not cache_id:
258 258 return buffer.get_list()[0]
259 return asyncio.run(copy_media(
260 buffer.get_list(),
261 buffer.get("cookies"),
262 buffer.get("headers"),
263 None,
264 request.args.get("prompt")
265 )).pop()
259 return "\n".join(asyncio.run(copy_media(
260 buffer.get_list(),
261 buffer.get("cookies"),
262 buffer.get("headers"),
263 None,
264 request.args.get("prompt")
265 )))
266 266 elif isinstance(buffer, AudioResponse):
267 267 return buffer.data
268 268 def iter_response():
@@ -303,7 +303,7 @@ class Backend_Api(Api):
303 303 finally:
304 304 if not cache_id:
305 305 os.remove(os.path.join(media_dir, filename))
306 elif response.startswith("https://") or response.startswith("http://"):
306 elif "\n" not in response and response.startswith("https://") or response.startswith("http://"):
307 307 return redirect(response)
308 308 if do_filter:
309 309 is_true_filter = do_filter.lower() in ["true", "1"]
Modified g4f/image/copy_images.py +1 -1
@@ -96,7 +96,7 @@ def get_filename(tags: list[str], alt: str, extension: str, image: str) -> str:
96 96 tags = f"{'+'.join([str(tag) for tag in tags if tag])}+" if tags else ""
97 97 return "".join((
98 98 f"{int(time.time())}_",
99 f"{secure_filename(tags or "" + alt)}_",
99 f"{secure_filename(tags + alt)}_" if alt else secure_filename(tags),
100 100 hashlib.sha256(image.encode()).hexdigest()[:16],
101 101 extension
102 102 ))
Modified g4f/providers/any_provider.py +6 -1
@@ -12,7 +12,7 @@ from ..Provider import __map__
12 12 from ..Provider import Cloudflare, Gemini, Grok, DeepSeekAPI, PerplexityLabs, LambdaChat, PollinationsAI, PuterJS
13 13 from ..Provider import Microsoft_Phi_4_Multimodal, DeepInfraChat, Blackbox, OIVSCodeSer2, OIVSCodeSer0501, TeachAnything
14 14 from ..Provider import Together, WeWordle, Yqcloud, Chatai, Free2GPT, ARTA, ImageLabs, LegacyLMArena, LMArenaBeta
15 from ..Provider import EdgeTTS, gTTS, MarkItDown, OpenAIFM
15 from ..Provider import EdgeTTS, gTTS, MarkItDown, OpenAIFM, Video
16 16 from ..Provider import HarProvider, HuggingFace, HuggingFaceMedia
17 17 from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
18 18 from .. import Provider
@@ -271,6 +271,9 @@ class AnyProvider(AsyncGeneratorProvider, ProviderModelMixin):
271 271 if count > cls.models_count.get(model, 0):
272 272 cls.models_count.update({model: count})
273 273
274 cls.video_models.append("video")
275 all_models.extend("video")
276
274 277 # Deduplicate and store
275 278 cls.models_storage[ignored_key] = list(dict.fromkeys([model if model else cls.default_model for model in all_models]))
276 279
@@ -342,6 +345,8 @@ class AnyProvider(AsyncGeneratorProvider, ProviderModelMixin):
342 345 except Exception as e:
343 346 debug.error(f"Error getting models for provider {provider.__name__}:", e)
344 347 continue
348 if model == "video":
349 providers.append(Video)
345 350 if model and provider == PuterJS:
346 351 providers.append(provider)
347 352 elif not model or model in provider_models or provider.model_aliases and model in provider.model_aliases or model in provider.model_aliases.values():