返回提交历史
Modified
g4f/Provider/YouTube.py
+26
-12
Modified
g4f/tools/run_tools.py
+4
-1
XFEstudio/gpt4free
Add YouTube provider
bfd1139e
代码差异
2 个文件
+30
-13
@@ -10,14 +10,16 @@ except ImportError:
10
10
11
11
from ..typing import AsyncResult, Messages
12
12
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
13
from ..providers.response import AudioResponse, VideoResponse
13
from ..providers.response import AudioResponse, VideoResponse, YouTube as YouTubeResponse
14
14
from ..image.copy_images import get_media_dir
15
15
from .helper import format_media_prompt
16
16
17
17
class YouTube(AsyncGeneratorProvider, ProviderModelMixin):
18
18
url = "https://youtube.com"
19
19
working = has_yt_dlp
20
use_nodriver = True
20
21
default_model = "search"
22
models = ["mp3", "1080p", "720p", "480p", "search"]
21
23
22
24
@classmethod
23
25
async def create_async_generator(
@@ -29,14 +31,17 @@ class YouTube(AsyncGeneratorProvider, ProviderModelMixin):
29
31
) -> AsyncResult:
30
32
prompt = format_media_prompt(messages, prompt)
31
33
provider = YouTubeProvider()
32
results = await provider.search(prompt, max_results=1)
34
results = await provider.search(prompt, max_results=5 if model == "search" else 1)
33
35
if results:
34
video_url = results[0]['url']
35
path = await provider.download(video_url, model="mp3", output_dir=get_media_dir())
36
if path.endswith('.mp3'):
37
yield AudioResponse(f"/media/{os.path.basename(path)}")
36
if model == "search":
37
yield YouTubeResponse([result["id"] for result in results])
38
38
else:
39
yield VideoResponse(f"/media/{os.path.basename(path)}", prompt)
39
video_url = results[0]['url']
40
path = await provider.download(video_url, model=model, output_dir=get_media_dir())
41
if path.endswith('.mp3'):
42
yield AudioResponse(f"/media/{os.path.basename(path)}")
43
else:
44
yield VideoResponse(f"/media/{os.path.basename(path)}", prompt)
40
45
41
46
class YouTubeProvider:
42
47
"""
@@ -72,7 +77,7 @@ class YouTubeProvider:
72
77
})
73
78
return results
74
79
75
async def download(self, video_url: str, model: str = "high-definition", output_dir: str = ".") -> str:
80
async def download(self, video_url: str, model: str = "720p", output_dir: str = ".") -> str:
76
81
"""
77
82
Download a YouTube video.
78
83
@@ -95,10 +100,19 @@ class YouTubeProvider:
95
100
'preferredquality': '192'
96
101
}]
97
102
})
98
elif model == "high-definition":
99
# Best video+audio
103
elif model == "1080p":
104
ydl_opts.update({
105
'format': 'bestvideo[height<=1080]+bestaudio/best[height<=1080]',
106
'merge_output_format': 'mp4',
107
})
108
elif model == "720p":
109
ydl_opts.update({
110
'format': 'bestvideo[height=720]+bestaudio/best[height=720]',
111
'merge_output_format': 'mp4',
112
})
113
elif model == "480p":
100
114
ydl_opts.update({
101
'format': 'bestvideo+bestaudio/best',
115
'format': 'bestvideo[height<=480]+bestaudio/best[height<=480]',
102
116
'merge_output_format': 'mp4',
103
117
})
104
118
else:
@@ -110,6 +110,7 @@ class ToolHandler:
110
110
111
111
function_name = tool.get("function", {}).get("name")
112
112
113
debug.log(f"Processing tool call: {function_name}")
113
114
if function_name == TOOL_NAMES["SEARCH"]:
114
115
messages, sources = await ToolHandler.process_search_tool(messages, tool)
115
116
@@ -234,6 +235,7 @@ async def async_iter_run_tools(
234
235
sources = None
235
236
web_search = kwargs.get('web_search')
236
237
if web_search:
238
debug.log(f"Performing web search with value: {web_search}")
237
239
messages, sources = await perform_web_search(messages, web_search)
238
240
239
241
# Get API key
@@ -280,6 +282,7 @@ def iter_run_tools(
280
282
sources = None
281
283
282
284
if web_search:
285
debug.log(f"Performing web search with value: {web_search}")
283
286
try:
284
287
messages = messages.copy()
285
288
search_query = web_search if isinstance(web_search, str) and web_search != "true" else None
@@ -299,7 +302,7 @@ def iter_run_tools(
299
302
for tool in tool_calls:
300
303
if tool.get("type") == "function":
301
304
function_name = tool.get("function", {}).get("name")
302
305
debug.log(f"Processing tool call: {function_name}")
303
306
if function_name == TOOL_NAMES["SEARCH"]:
304
307
tool["function"]["arguments"] = ToolHandler.validate_arguments(tool["function"])
305
308
messages[-1]["content"] = get_search_message(