forked from manbearwiz/youtube-dl-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
youtube-dl-server.py
120 lines (89 loc) · 3.27 KB
/
youtube-dl-server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from __future__ import unicode_literals
import json
import os
import subprocess
from queue import Queue
from bottle import route, run, Bottle, request, static_file
from threading import Thread
import youtube_dl
from pathlib import Path
from collections import ChainMap
app = Bottle()
app_defaults = {
'YDL_FORMAT': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]',
'YDL_EXTRACT_AUDIO_FORMAT': None,
'YDL_EXTRACT_AUDIO_QUALITY': '192',
'YDL_RECODE_VIDEO_FORMAT': None,
'YDL_OUTPUT_TEMPLATE': '/youtube-dl/%(title)s [%(id)s].%(ext)s',
'YDL_ARCHIVE_FILE': None,
'YDL_SERVER_HOST': '0.0.0.0',
'YDL_SERVER_PORT': 8080,
}
@app.route('/youtube-dl')
def dl_queue_list():
return static_file('index.html', root='./')
@app.route('/youtube-dl/static/:filename#.*#')
def server_static(filename):
return static_file(filename, root='./static')
@app.route('/youtube-dl/q', method='GET')
def q_size():
return {"success": True, "size": json.dumps(list(dl_q.queue))}
@app.route('/youtube-dl/q', method='POST')
def q_put():
url = request.forms.get("url")
options = {
'format': request.forms.get("format")
}
if not url:
return {"success": False, "error": "/q called without a 'url' query param"}
dl_q.put((url, options))
print("Added url " + url + " to the download queue")
return {"success": True, "url": url, "options": options}
def dl_worker():
while not done:
url, options = dl_q.get()
download(url, options)
dl_q.task_done()
def get_ydl_options(request_options):
request_vars = {
'YDL_EXTRACT_AUDIO_FORMAT': None,
'YDL_RECODE_VIDEO_FORMAT': None,
}
requested_format = request_options.get('format', 'bestvideo')
if requested_format in ['aac', 'flac', 'mp3', 'm4a', 'opus', 'vorbis', 'wav']:
request_vars['YDL_EXTRACT_AUDIO_FORMAT'] = requested_format
elif requested_format == 'bestaudio':
request_vars['YDL_EXTRACT_AUDIO_FORMAT'] = 'best'
elif requested_format in ['mp4', 'flv', 'webm', 'ogg', 'mkv', 'avi']:
request_vars['YDL_RECODE_VIDEO_FORMAT'] = requested_format
ydl_vars = ChainMap(request_vars, os.environ, app_defaults)
postprocessors = []
if(ydl_vars['YDL_EXTRACT_AUDIO_FORMAT']):
postprocessors.append({
'key': 'FFmpegExtractAudio',
'preferredcodec': ydl_vars['YDL_EXTRACT_AUDIO_FORMAT'],
'preferredquality': ydl_vars['YDL_EXTRACT_AUDIO_QUALITY'],
})
if(ydl_vars['YDL_RECODE_VIDEO_FORMAT']):
postprocessors.append({
'key': 'FFmpegVideoConvertor',
'preferedformat': ydl_vars['YDL_RECODE_VIDEO_FORMAT'],
})
return {
'format': ydl_vars['YDL_FORMAT'],
'postprocessors': postprocessors,
'outtmpl': ydl_vars['YDL_OUTPUT_TEMPLATE'],
'download_archive': ydl_vars['YDL_ARCHIVE_FILE']
}
def download(url, request_options):
with youtube_dl.YoutubeDL(get_ydl_options(request_options)) as ydl:
ydl.download([url])
dl_q = Queue()
done = False
dl_thread = Thread(target=dl_worker)
dl_thread.start()
print("Started download thread")
app_vars = ChainMap(os.environ, app_defaults)
app.run(host=app_vars['YDL_SERVER_HOST'], port=app_vars['YDL_SERVER_PORT'], debug=True)
done = True
dl_thread.join()