返回提交历史
Added
g4f/Provider/needs_auth/Video.py
+149
-0
Modified
g4f/Provider/needs_auth/__init__.py
+1
-0
Modified
g4f/api/__init__.py
+4
-1
Modified
g4f/cookies.py
+2
-2
Modified
g4f/gui/server/backend_api.py
+8
-8
Modified
g4f/image/copy_images.py
+1
-1
Modified
g4f/providers/any_provider.py
+6
-1
XFEstudio/gpt4free
Add video provider
b7d1a03d
代码差异
7 个文件
+171
-13
@@ -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()
@@ -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
@@ -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:
@@ -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
@@ -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"]
@@ -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
))
@@ -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():