dragonxd1 commited on
Commit
a65da15
·
verified ·
1 Parent(s): fdb3ab8

Upload youtube (2).py

Browse files
Files changed (1) hide show
  1. DragMusic/platforms/youtube (2).py +325 -0
DragMusic/platforms/youtube (2).py ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import asyncio
3
+ import os
4
+ import re
5
+ import json
6
+ import httpx # Make sure to import httpx
7
+ from typing import Union
8
+ import yt_dlp
9
+ from pyrogram.enums import MessageEntityType
10
+ from pyrogram.types import Message
11
+ from youtubesearchpython.__future__ import VideosSearch
12
+ from DragMusic.utils.database import is_on_off
13
+ from DragMusic.utils.formatters import time_to_seconds
14
+ async def shell_cmd(cmd):
15
+ proc = await asyncio.create_subprocess_shell(
16
+ cmd,
17
+ stdout=asyncio.subprocess.PIPE,
18
+ stderr=asyncio.subprocess.PIPE,
19
+ )
20
+ out, errorz = await proc.communicate()
21
+ if errorz:
22
+ if "unavailable videos are hidden" in (errorz.decode("utf-8")).lower():
23
+ return out.decode("utf-8")
24
+ else:
25
+ return errorz.decode("utf-8")
26
+ return out.decode("utf-8")
27
+ class YouTubeAPI:
28
+ def __init__(self):
29
+ self.base = "https://www.youtube.com/watch?v="
30
+ self.regex = r"(?:youtube\.com|youtu\.be)"
31
+ self.status = "https://www.youtube.com/oembed?url="
32
+ self.listbase = "https://youtube.com/playlist?list="
33
+ self.reg = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
34
+ async def exists(self, link: str, videoid: Union[bool, str] = None):
35
+ if videoid:
36
+ link = self.base + link
37
+ if re.search(self.regex, link):
38
+ return True
39
+ else:
40
+ return False
41
+ async def url(self, message_1: Message) -> Union[str, None]:
42
+ messages = [message_1]
43
+ if message_1.reply_to_message:
44
+ messages.append(message_1.reply_to_message)
45
+ text = ""
46
+ offset = None
47
+ length = None
48
+ for message in messages:
49
+ if offset:
50
+ break
51
+ if message.entities:
52
+ for entity in message.entities:
53
+ if entity.type == MessageEntityType.URL:
54
+ text = message.text or message.caption
55
+ offset, length = entity.offset, entity.length
56
+ break
57
+ elif message.caption_entities:
58
+ for entity in message.caption_entities:
59
+ if entity.type == MessageEntityType.TEXT_LINK:
60
+ return entity.url
61
+ if offset in (None,):
62
+ return None
63
+ return text[offset : offset + length]
64
+ async def details(self, link: str, videoid: Union[bool, str] = None):
65
+ if videoid:
66
+ link = self.base + link
67
+ if "&" in link:
68
+ link = link.split("&")[0]
69
+ results = VideosSearch(link, limit=1)
70
+ for result in (await results.next())["result"]:
71
+ title = result["title"]
72
+ duration_min = result["duration"]
73
+ thumbnail = result["thumbnails"][0]["url"].split("?")[0]
74
+ vidid = result["id"]
75
+ if str(duration_min) == "None":
76
+ duration_sec = 0
77
+ else:
78
+ duration_sec = int(time_to_seconds(duration_min))
79
+ return title, duration_min, duration_sec, thumbnail, vidid
80
+ async def title(self, link: str, videoid: Union[bool, str] = None):
81
+ if videoid:
82
+ link = self.base + link
83
+ if "&" in link:
84
+ link = link.split("&")[0]
85
+ results = VideosSearch(link, limit=1)
86
+ for result in (await results.next())["result"]:
87
+ title = result["title"]
88
+ return title
89
+ async def duration(self, link: str, videoid: Union[bool, str] = None):
90
+ if videoid:
91
+ link = self.base + link
92
+ if "&" in link:
93
+ link = link.split("&")[0]
94
+ results = VideosSearch(link, limit=1)
95
+ for result in (await results.next())["result"]:
96
+ duration = result["duration"]
97
+ return duration
98
+ async def thumbnail(self, link: str, videoid: Union[bool, str] = None):
99
+ if videoid:
100
+ link = self.base + link
101
+ if "&" in link:
102
+ link = link.split("&")[0]
103
+ results = VideosSearch(link, limit=1)
104
+ for result in (await results.next())["result"]:
105
+ thumbnail = result["thumbnails"][0]["url"].split("?")[0]
106
+ return thumbnail
107
+ async def video(self, link: str, videoid: Union[bool, str] = None):
108
+ if videoid:
109
+ link = self.base + link
110
+ if "&" in link:
111
+ link = link.split("&")[0]
112
+ proc = await asyncio.create_subprocess_exec(
113
+ "yt-dlp",
114
+ "-g",
115
+ "-f",
116
+ "best[height<=?720][width<=?1280]",
117
+ f"{link}",
118
+ stdout=asyncio.subprocess.PIPE,
119
+ stderr=asyncio.subprocess.PIPE,
120
+ )
121
+ stdout, stderr = await proc.communicate()
122
+ if stdout:
123
+ return 1, stdout.decode().split("\n")[0]
124
+ else:
125
+ return 0, stderr.decode()
126
+ async def playlist(self, link, limit, user_id, videoid: Union[bool, str] = None):
127
+ if videoid:
128
+ link = self.listbase + link
129
+ if "&" in link:
130
+ link = link.split("&")[0]
131
+ playlist = await shell_cmd(
132
+ f"yt-dlp -i --get-id --flat-playlist --playlist-end {limit} --skip-download {link}"
133
+ )
134
+ try:
135
+ result = playlist.split("\n")
136
+ for key in result:
137
+ if key == "":
138
+ result.remove(key)
139
+ except:
140
+ result = []
141
+ return result
142
+ async def track(self, link: str, videoid: Union[bool, str] = None):
143
+ if videoid:
144
+ link = self.base + link
145
+ if "&" in link:
146
+ link = link.split("&")[0]
147
+ results = VideosSearch(link, limit=1)
148
+ for result in (await results.next())["result"]:
149
+ title = result["title"]
150
+ duration_min = result["duration"]
151
+ vidid = result["id"]
152
+ yturl = result["link"]
153
+ thumbnail = result["thumbnails"][0]["url"].split("?")[0]
154
+ track_details = {
155
+ "title": title,
156
+ "link": yturl,
157
+ "vidid": vidid,
158
+ "duration_min": duration_min,
159
+ "thumb": thumbnail,
160
+ }
161
+ return track_details, vidid
162
+ async def formats(self, link: str, videoid: Union[bool, str] = None):
163
+ if videoid:
164
+ link = self.base + link
165
+ if "&" in link:
166
+ link = link.split("&")[0]
167
+ ytdl_opts = {"quiet": True}
168
+ ydl = yt_dlp.YoutubeDL(ytdl_opts)
169
+ with ydl:
170
+ formats_available = []
171
+ r = ydl.extract_info(link, download=False)
172
+ for format in r["formats"]:
173
+ try:
174
+ str(format["format"])
175
+ except:
176
+ continue
177
+ if not "dash" in str(format["format"]).lower():
178
+ try:
179
+ format["format"]
180
+ format["filesize"]
181
+ format["format_id"]
182
+ format["ext"]
183
+ format["format_note"]
184
+ except:
185
+ continue
186
+ formats_available.append(
187
+ {
188
+ "format": format["format"],
189
+ "filesize": format["filesize"],
190
+ "format_id": format["format_id"],
191
+ "ext": format["ext"],
192
+ "format_note": format["format_note"],
193
+ "yturl": link,
194
+ }
195
+ )
196
+ return formats_available, link
197
+ async def slider(
198
+ self,
199
+ link: str,
200
+ query_type: int,
201
+ videoid: Union[bool, str] = None,
202
+ ):
203
+ if videoid:
204
+ link = self.base + link
205
+ if "&" in link:
206
+ link = link.split("&")[0]
207
+ a = VideosSearch(link, limit=10)
208
+ result = (await a.next()).get("result")
209
+ title = result[query_type]["title"]
210
+ duration_min = result[query_type]["duration"]
211
+ vidid = result[query_type]["id"]
212
+ thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0]
213
+ return title, duration_min, thumbnail, vidid
214
+ async def get_video_info_from_bitflow(self, url: str, video: bool):
215
+ api_url = "https://bitflow.in/api/youtube"
216
+ params = {
217
+ "query": url,
218
+ "format": "video" if video else "audio",
219
+ "download": True,
220
+ "api_key": "1spiderkey2"
221
+ }
222
+
223
+ async with httpx.AsyncClient() as client:
224
+ response = await client.get(api_url, params=params, timeout=150)
225
+ if response.status_code == 200:
226
+ return response.json()
227
+ else:
228
+ return {"status": "error", "message": "Failed to fetch data from Bitflow API."}
229
+ async def download(
230
+ self,
231
+ link: str,
232
+ mystic,
233
+ video: Union[bool, str] = None,
234
+ videoid: Union[bool, str] = None,
235
+ songaudio: Union[bool, str] = None,
236
+ songvideo: Union[bool, str] = None,
237
+ format_id: Union[bool, str] = None,
238
+ title: Union[bool, str] = None,
239
+ ) -> str:
240
+ if videoid:
241
+ link = self.base + link
242
+ if "&" in link:
243
+ link = link.split("&")[0]
244
+ loop = asyncio.get_running_loop()
245
+ bitflow_info = await self.get_video_info_from_bitflow(link, video)
246
+ def audio_dl(bitflow_info):
247
+ xyz = os.path.join("downloads", f"{bitflow_info['videoid']}.{bitflow_info['ext']}")
248
+ ydl_optssx = {
249
+ "format": "bestaudio/best",
250
+ "outtmpl": xyz,
251
+ "geo_bypass": True,
252
+ "nocheckcertificate": True,
253
+ "quiet": True,
254
+ "no_warnings": True,
255
+ }
256
+ x = yt_dlp.YoutubeDL(ydl_optssx)
257
+ if os.path.exists(xyz):
258
+ return xyz
259
+ x.download([bitflow_info['url']])
260
+ return xyz
261
+ def video_dl(bitflow_info):
262
+ xyz = os.path.join("downloads", f"{bitflow_info['videoid']}.{bitflow_info['ext']}")
263
+ ydl_optssx = {
264
+ "format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])",
265
+ "outtmpl": xyz,
266
+ "geo_bypass": True,
267
+ "nocheckcertificate": True,
268
+ "quiet": True,
269
+ "no_warnings": True,
270
+ }
271
+ x = yt_dlp.YoutubeDL(ydl_optssx)
272
+ if os.path.exists(xyz):
273
+ return xyz
274
+ x.download([bitflow_info['url']])
275
+ return xyz
276
+ def song_video_dl():
277
+ formats = f"{format_id}+140"
278
+ fpath = f"downloads/{title}"
279
+ ydl_optssx = {
280
+ "format": formats,
281
+ "outtmpl": fpath,
282
+ "geo_bypass": True,
283
+ "nocheckcertificate": True,
284
+ "quiet": True,
285
+ "no_warnings": True,
286
+ "prefer_ffmpeg": True,
287
+ "merge_output_format": "mp4",
288
+ }
289
+ x = yt_dlp.YoutubeDL(ydl_optssx)
290
+ x.download([link])
291
+ def song_audio_dl():
292
+ fpath = f"downloads/{title}.%(ext)s"
293
+ ydl_optssx = {
294
+ "format": format_id,
295
+ "outtmpl": fpath,
296
+ "geo_bypass": True,
297
+ "nocheckcertificate": True,
298
+ "quiet": True,
299
+ "no_warnings": True,
300
+ "prefer_ffmpeg": True,
301
+ "postprocessors": [
302
+ {
303
+ "key": "FFmpegExtractAudio",
304
+ "preferredcodec": "mp3",
305
+ "preferredquality": "192",
306
+ }
307
+ ],
308
+ }
309
+ x = yt_dlp.YoutubeDL(ydl_optssx)
310
+ x.download([link])
311
+ if songvideo:
312
+ await loop.run_in_executor(None, song_video_dl)
313
+ fpath = f"downloads/{title}.mp4"
314
+ return fpath
315
+ elif songaudio:
316
+ await loop.run_in_executor(None, song_audio_dl)
317
+ fpath = f"downloads/{title}.mp3"
318
+ return fpath
319
+ elif video:
320
+ direct = True
321
+ downloaded_file = await loop.run_in_executor(None, video_dl, bitflow_info)
322
+ else:
323
+ direct = True
324
+ downloaded_file = await loop.run_in_executor(None, audio_dl, bitflow_info)
325
+ return downloaded_file, direct