python3 PyQt5界面开发:YouTube-dl Mac版GUI实用下载工具

最近因需求自行开发了一个基于YouTube-dl的下载界面,其中可提供下载最好质量的音频、视频文件,并且实现了添加代理的需求。

以下为现今的半完成品代码:

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
import youtube_dl
from PyQt5 import *
class Stream(QtCore.QObject):
newText = QtCore.pyqtSignal(str)
# def flush(self):
# sys.setrecursionlimit(10000)
# ys.stdout.write(text)
# sys.stdout.flush()
def write(self, text):
self.newText.emit(str(text))
class ThreadWorker(QThread):
newText = pyqtSignal()
def __init__(self, parent=None):
super(ThreadWorker, self).__init__(parent)
self.working = True
def __del__(self):
self.working = False
self.wait()
# def run(self):
# Up = YouTube_dl_MacGUI()
# self.sys.stdout = Stream(newText=Up.onUpdateText)
#
def run(self):
while self.working == True:
"""
下载音乐/音频
"""
Youtube_UI = YouTube_dl_MacGUI()
proxy = Youtube_UI.add_proxy().proxy
ydl_opts = {
'format': '140',
'proxy': proxy,
'writesubtitles': 'Yes',
'allsubtitles': 'Yes'
}
try:
start = time.time()
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([Youtube_UI.YouTube_URL_Line.text()])
except:
print("Sorry,your proxy can't use! or URL format error!")
end = time.time()
return "use time:<{0}>".format(end - start)
self.newText.emit()
class Worker(QRunnable):
newText = pyqtSignal(str)
@pyqtSlot()
def run(self):
self.newText.emit()
class YouTube_dl_MacGUI(QWidget):
# proxy = 'socks5://127.0.0.1:1080' # default proxy
def __init__(self):
super().__init__()
self.initUI()
# self.threadpool = QThreadPool()
# worker = Worker()
# self.threadpool.start()
# 自定义输出流
# sys.stdout = Stream(newText=self.onUpdateText)
# self.MyThread = ThreadWorker()
# self.MyThread.start()
# sys.stdout = self.MyThread.newText.connect(self.onUpdateText)
# MyThread.start()
def Working(self):
"""
线程启动
"""
self.MyThread = ThreadWorker()
self.MyThread.start()
def add_proxy(self, proxy):
"""
添加代理之用,默认显示为'socks5://127.0.0.1:1080'
"""
self.proxy = proxy
try:
print("Current Proxy:<{0}>".format(self.proxy))
except:
print("Sorry,your proxy can't use!")
def down_Music(self, url):
"""
下载音乐/音频
"""
ydl_opts = {
'format': '140',
'proxy': self.proxy,
'writesubtitles': 'Yes',
'allsubtitles': 'Yes'
}
try:
# start = time.time()
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
except:
print("Sorry,your proxy can't use! or URL format error!")
# end = time.time()
# return "use time:<{0}>".format(end - start)
def down_Video(self, url):
"""
下载视频
"""
ydl_opts = {
'proxy': self.proxy,
'writesubtitles': 'Yes',
'allsubtitles': 'Yes'
}
try:
start = time.time()
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
return ydl.download([url])
except:
print("Sorry,your proxy can't use! or URL format error!")
end = time.time()
return "use time:<{0}>".format(end - start)
def initUI(self):
self.combo = QComboBox(self)
self.combo.addItems(['Download Music/Audio', 'Download Video'])
# combo.addItem('Download Video')
self.combo.activated[str].connect(self.Sele_Format)
self.Proxy_Label = QLabel('Proxy:', self)
self.YouTube_URL_Label = QLabel('URL:', self)
self.Proxy_Line = QLineEdit(self)
self.Proxy_Line.setPlaceholderText("e.g.:socks5://127.0.0.1:1080")
self.Proxy_Line.setToolTip("socks4/5://ip:port")
self.YouTube_URL_Line = QLineEdit(self)
self.YouTube_URL_Line.setPlaceholderText("e.g.:https://www.youtube.com/watch?v=ZSM3w1v-A_Y")
self.YouTube_URL_Line.setToolTip("YouTube URL")
# 设置按钮及其快捷键
# MyThread = Thread()
# MyThread.newText.connect(self.onUpdateText)
# MyThread.start()
self.Apply_Button = QPushButton('Apply', self)
self.Apply_Button.setToolTip("Apply Proxy")
self.Start_Button = QPushButton('Start Donwload', self)
self.Start_Button.setToolTip("return")
# self.Start_Button.clicked.connect(lambda :self.MyThread.start())
self.Clear_Button = QPushButton('Clear', self)
self.Clear_Button.setToolTip("esc")
self.Quit_Button = QPushButton('Quit', self)
self.Quit_Button.setToolTip("command+q")
# self.Quit_Button.clicked.connect(lambda :self.MyThread.terminate())
self.Start_Button.setShortcut('return')
self.Clear_Button.setShortcut('esc')
self.Quit_Button.setShortcut('command+q')
self.Quit_Button.clicked.connect(QCoreApplication.instance().quit)
# self.result = QTextBrowser()
self.result = QTextEdit(self, readOnly=True)
self.result.moveCursor(QTextCursor.Start)
self.result.ensureCursorVisible()
self.result.setLineWrapColumnOrWidth(500)
self.result.setLineWrapMode(QTextEdit.FixedPixelWidth)
self.result.setFixedWidth(600)
self.result.setFixedHeight(400)
self.result.setGeometry(200, 200, 200, 200) # 非必要
# 布局设置
grip = QGridLayout()
grip.setSpacing(7)
grip.addWidget(self.Proxy_Label, 1, 0)
grip.addWidget(self.Proxy_Line, 2, 0)
grip.addWidget(self.Apply_Button, 2, 1)
grip.addWidget(self.YouTube_URL_Label, 3, 0)
grip.addWidget(self.YouTube_URL_Line, 4, 0)
grip.addWidget(self.Clear_Button, 4, 1)
grip.addWidget(self.combo, 5, 0)
grip.addWidget(self.Start_Button, 5, 1)
grip.addWidget(self.result, 6, 0)
grip.addWidget(self.Quit_Button, 7, 1)
self.setLayout(grip)
self.Quit_Button.move(100, 100) # 非必要
self.setGeometry(500, 300, 600, 500)
self.setWindowTitle('Mac Youtube-dl Downloader')
self.setWindowIcon(QIcon('YouTubedl.ico'))
self.Clear_Button.clicked.connect(self.Clear_URL_Result)
self.Apply_Button.clicked.connect(self.Apply_Proxy)
self.Start_Button.clicked.connect(self.Sele_Format)
self.show()
def onUpdateText(self, text):
cursor = self.result.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(text)
# QApplication.processEvents()
# time.sleep(1)
self.result.setTextCursor(cursor)
self.result.ensureCursorVisible()
def __del__(self):
sys.stdout = sys.__stdout__
def Clear_URL_Result(self):
"""
清空URL列表以及结果显示处
"""
self.YouTube_URL_Line.setText("")
self.result.setText("")
def Apply_Proxy(self):
"""
应用代理信息
"""
# self.MyThread = ThreadWorker()
# self.MyThread.start()
# sys.stdout = self.MyThread.newText.connect(self.onUpdateText)
return self.add_proxy(self.Proxy_Line.text())
def Sele_Format(self, text):
"""
用于选择音频/视频格式
"""
# if self.combo.addItem('Download Music/Audio'):
# self.result.setText(self.down_Music(self.YouTube_URL_Line.text()))
# else:
# self.result.setText(self.down_Video(self.YouTube_URL_Line.text()))
if text == 'Download Music/Audio':
return self.down_Music(self.YouTube_URL_Line.text())
# return self.Working()
else:
return self.down_Video(self.YouTube_URL_Line.text())
def run():
app = QApplication(sys.argv)
ex = YouTube_dl_MacGUI()
sys.exit(app.exec())
if __name__ == '__main__':
run()

简要的添加了代理以及增加链接即可进行下载,默认下载质量最好的。视频格式为.mp4,音乐为.m4a

如果失效出错了,大多是因为YouTube-dl的版本问题,基本上更新一下就好。

实际上不仅限于下载YouTube上的资源,其中的YouTube-dl支持,基本上都能下载,比如pronhub…实用,实用。

参考链接

---------------本文终---------------

文章作者:刘俊

最后更新:2019年05月23日 - 08:05

许可协议: 转载请保留原文链接及作者。