Skip to content

Instantly share code, notes, and snippets.

@creuserr
Last active June 1, 2024 05:32
Show Gist options
  • Save creuserr/02fb1127961632120304c1302f47c583 to your computer and use it in GitHub Desktop.
Save creuserr/02fb1127961632120304c1302f47c583 to your computer and use it in GitHub Desktop.
cloudcre: audio api template

Usage

https://your-deployment.vercel.app/<YT-ID>/<Filename>.mp3

Where <YT-ID> is the youtube video ID, and <Filename> is the default name of the file.

<Filename> can be anything because the purpose of this is to customize the audio's default filename when downloading.

Note that .mp3 is required.

Rewrites

If you are using vercel, use this as vercel.json:

{
  "version": 2,
  "builds": [{
    "src": "download.py",
    "use": "@vercel/python"
  }],
  "rewrites": [{
    "source": "/(.*)",
    "destination": "/download.py"
  }]
}

If not, you should follow this rewrite rule:

  • Everything (/(.*)) should be redirected to the python script.
from pytube import YouTube
from http.server import BaseHTTPRequestHandler
from pytube.cipher import get_throttling_function_code
import re, mock
# THIS IS A PATCH TO A BUG
# DO NOT REMOVE
def patched_throttling_plan(js: str):
raw_code = get_throttling_function_code(js)
transform_start = r"try{"
plan_regex = re.compile(transform_start)
match = plan_regex.search(raw_code)
transform_plan_raw = js
step_start = r"c\[(\d+)\]\(c\[(\d+)\](,c(\[(\d+)\]))?\)"
step_regex = re.compile(step_start)
matches = step_regex.findall(transform_plan_raw)
transform_steps = []
for match in matches:
if match[4] != '':
transform_steps.append((match[0],match[1],match[4]))
else:
transform_steps.append((match[0],match[1]))
return transform_steps
class handler(BaseHTTPRequestHandler):
def do_GET(self):
if len(self.path) < 2:
return self.end('400 Bad Request: Incomplete Parameter', 400)
if self.path == '/favicon.ico':
self.send_response(302)
self.send_header('Location', 'https://m.youtube.com/favicon.ico')
return self.end_headers()
ytid = None
try:
ytid = self.path.split('/')[1]
except:
return self.end('400 Bad Request: Invalid Parameter', 400)
try:
with mock.patch('pytube.cipher.get_throttling_plan', patched_throttling_plan):
video = YouTube('https://youtu.be/' + ytid)
# If you are using a paid plan, you can use the highest quality with:
# stream = video.streams.filter(only_audio=True)[-1]
stream = video.streams.filter(only_audio=True).first()
stream.download(filename='output.mp3', output_path='/tmp/')
self.send_response(200)
self.send_header('Content-type', 'audio/mp3')
self.end_headers()
with open('/tmp/output.mp3', 'rb') as f:
self.wfile.write(f.read())
return f.close()
except Exception as e:
if('regex_search' in str(e)):
return self.end('400 Bad Request: Invalid Parameter', 400)
if('unavailable' in str(e)):
return self.end('404 Not Found: Unavailable', 404)
return self.end('500 Internal Error: ' + str(e), 500)
def end(self, text, status):
self.send_response(status)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(text.encode('utf-8'))
pytube==15.0.0
mock==5.1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment