Skip to content

Commit 88107a7

Browse files
authored
Merge pull request #14 from oleksis/master
Version 0.4.1
2 parents b1309fc + c1e5694 commit 88107a7

24 files changed

+547
-253
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.mp3
33
*.mp4
44
*.flv
5+
.vscode
56
build
67
dist
78
*.spec

README.md

+11-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ This repository contains code for a youtube-dl GUI written in PyQt. It is based
88

99
## Requirements:
1010

11+
- Python >= v3.x
1112
- PyQt5
1213
- [youtube_dl](https://github.com/ytdl-org/youtube-dl)
13-
- Python >= v3.x
14+
- [FFmpeg](https://ffmpeg.org/download.html) (optional, to postprocess video files)
15+
16+
### Requirement for build Binaries/Executables
17+
18+
- [PyInstaller](https://www.pyinstaller.org/)
1419

1520
## Features:
1621

@@ -34,13 +39,13 @@ This program is still in beta so if you encounter any bugs feel free to report t
3439

3540
## TODO:
3641

37-
- Fix Convert (main:MainWindow.convert_file)
38-
- integrate save state
3942
- Allow pause/resume functionality
43+
- integrate save state
4044
- ~~integrate post processing options~~
4145
- ~~integrate batch add feature~~
4246
- ~~integrate Queue to make it stable~~
4347
- ~~Change for PyInstaller: setup.py - _see Windows_~~
48+
- ~~Fix Convert (main:MainWindow.convert_file)~~
4449

4550
## Windows:
4651

@@ -52,6 +57,9 @@ python setup.py pyinstaller
5257

5358
This will result in a **dist** and **build** directory. Simply go to the **dist** directory and you will get a ```youtube-dl-gui.exe``` file and some other files. That ```youtube-dl-gui.exe``` file is a standalone executable which can be run simply by double clicking it. You can distribute that file to your friend.
5459

60+
### Download
61+
Can dowload the latest version from [Releases](https://github.com/yasoob/youtube-dl-GUI/releases/latest)
62+
5563
## License:
5664

5765
This project is released under the MIT license. See the included license file.

Threads/PostProcessor.py

+9-10
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,14 @@ def __init__(self, outpath, downloader=None, preferedformat=None):
1313

1414
def run(self, information):
1515
path = information['filepath']
16-
self.outpath = os.path.join(self.outpath, os.path.split(path)[-1])
16+
file_name = os.path.split(path)[-1]
17+
self.outpath = os.path.join(self.outpath, file_name)
18+
1719
if information['ext'] == self._preferedformat:
1820
return True, information
1921

20-
prefix, sep, ext = path.rpartition('.')
21-
22-
# print(path)
23-
# print(self.outpath)
24-
# print(self._preferedformat)
25-
# print(prefix + sep + self._preferedformat)
26-
# print("\n")
22+
prefix, sep, ext = self.outpath.rpartition('.')
23+
self.outpath = prefix + sep + self._preferedformat
2724

2825
self.run_ffmpeg(path, self.outpath, [])
2926
information['filepath'] = self.outpath
@@ -41,7 +38,7 @@ def to_screen(self, e):
4138
class PostProcessorSignals(QtCore.QObject):
4239
"Define the signals available from a running postprocessor thread"
4340

44-
statusSignal = QtCore.pyqtSignal(str)
41+
statusBar_Signal = QtCore.pyqtSignal(str)
4542
list_Signal = QtCore.pyqtSignal([list])
4643
row_Signal = QtCore.pyqtSignal()
4744
finished = QtCore.pyqtSignal()
@@ -82,8 +79,9 @@ def run(self):
8279
self.bytes,
8380
self.eta,
8481
self.speed,
85-
'Converting'
82+
'Converting...'
8683
])
84+
self.signals.statusBar_Signal.emit('Converting...')
8785
self.convert()
8886
self.signals.list_Signal.emit([
8987
self.local_rowcount,
@@ -93,6 +91,7 @@ def run(self):
9391
self.speed,
9492
'Finished'
9593
])
94+
self.signals.statusBar_Signal.emit('Done!')
9695

9796
def format_bytes(self, bytes):
9897
if bytes is None:

UI/AboutDialog.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def setupUi(self, Dialog):
8282
def retranslateUi(self, Dialog):
8383
_translate = QtCore.QCoreApplication.translate
8484
Dialog.setWindowTitle(_translate("Dialog", "About"))
85-
self.label_2.setText(_translate("Dialog", "<html><head/><body><p>Version: 0.4.0</p></body></html>"))
85+
self.label_2.setText(_translate("Dialog", "<html><head/><body><p>Version: 0.4.1</p></body></html>"))
8686
self.label_3.setText(_translate("Dialog", "<html><head/><body><p>Youtube-dl is a front-end to youtube-dl - a CLI application. Youtube-dl provides some additional features. Youtube-dl is not released as a part of youtube-dl. Youtube-dl is a separate project and is developed by Muhammad Yasoob Ullah Khalid.This Youtube-dl project version is mainteined by Oleksis Fraga &lt;[email protected]&gt;</p></body></html>"))
8787
self.label_5.setText(_translate("Dialog", "<html><head/><body><p>Youtube-dl uses youtube-dl which is released into Public Domain. It can be downloaded from <a href=\"https://github.com/ytdl-org/youtube-dl\"><span style=\" text-decoration: underline; color:#0000ff;\">youtube-dl repository</span></a></p></body></html>"))
8888
self.label_4.setText(_translate("Dialog", "<html><head/><body><p>Copyright © 2013-2020</p></body></html>"))

UI/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = '0.4.0'
1+
__version__ = '0.4.1'
22
__author__ = 'yasoob'
33
__maintainer__ = 'Oleksis Fraga'
44
__maintainer_contact__ = '[email protected]'

UI/gui.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def setupUi(self, MainWindow):
292292

293293
def retranslateUi(self, MainWindow):
294294
_translate = QtCore.QCoreApplication.translate
295-
MainWindow.setWindowTitle(_translate("MainWindow", "youtube-dl v0.4.0"))
295+
MainWindow.setWindowTitle(_translate("MainWindow", "youtube-dl v0.4.1"))
296296
self.groupBox.setTitle(_translate("MainWindow", "Enter url and download location"))
297297
self.label_2.setText(_translate("MainWindow", "Video URL:"))
298298
self.label_3.setText(_translate("MainWindow", "Save To:"))

main.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,11 @@ def convert_file_browse(self):
118118
else:
119119
self.ui.BrowseConvertLineEdit.files=file_names
120120

121-
# TODO: Fix it
122121
def convert_file(self,file_path, out_path, preferred_format, delete_tmp=False):
123122
if file_path.split('.')[-1] == preferred_format:
124123
self.ui.statusbar.showMessage('The source and destination formats are same')
125124
return
126125

127-
# TODO: Check file_path (file_name to final preferred_format)
128126
if file_path not in self.convert_list:
129127
options= {
130128
'file_path': file_path,
@@ -136,7 +134,7 @@ def convert_file(self,file_path, out_path, preferred_format, delete_tmp=False):
136134
}
137135
# Using ThreadPool
138136
pprocessorThread = PostProcessor(options)
139-
pprocessorThread.signals.statusSignal.connect(self.ui.statusbar.showMessage)
137+
pprocessorThread.signals.statusBar_Signal.connect(self.ui.statusbar.showMessage)
140138
pprocessorThread.signals.list_Signal.connect(self.add_to_table)
141139
pprocessorThread.signals.row_Signal.connect(self.decrease_rowcount)
142140
self.threadpool.start(pprocessorThread)
@@ -277,7 +275,7 @@ def closeEvent(self, event):
277275
self.kill_all_threads()
278276

279277
def kill_all_threads(self):
280-
self.threadpool.waitForDone(1)
278+
self.threadpool.waitForDone()
281279
self.close()
282280

283281

resources/about-dialog.ui

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
</font>
9797
</property>
9898
<property name="text">
99-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Version: 0.4.0&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
99+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Version: 0.4.1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
100100
</property>
101101
</widget>
102102
</item>

resources/gui_qt-designer-beta.ui

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
14-
<string>youtube-dl v0.4.0</string>
14+
<string>youtube-dl v0.4.1</string>
1515
</property>
1616
<property name="styleSheet">
1717
<string notr="true"/>

youtube_dl/YoutubeDL.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1610,7 +1610,7 @@ def is_wellformed(f):
16101610
if req_format is None:
16111611
req_format = self._default_format_spec(info_dict, download=download)
16121612
if self.params.get('verbose'):
1613-
self.to_stdout('[debug] Default format spec: %s' % req_format)
1613+
self._write_string('[debug] Default format spec: %s\n' % req_format)
16141614

16151615
format_selector = self.build_format_selector(req_format)
16161616

@@ -1871,7 +1871,7 @@ def dl(name, info):
18711871
for ph in self._progress_hooks:
18721872
fd.add_progress_hook(ph)
18731873
if self.params.get('verbose'):
1874-
self.to_stdout('[debug] Invoking downloader on %r' % info.get('url'))
1874+
self.to_screen('[debug] Invoking downloader on %r' % info.get('url'))
18751875
return fd.download(name, info)
18761876

18771877
if info_dict.get('requested_formats') is not None:

youtube_dl/extractor/cspan.py

+23
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
find_xpath_attr,
1111
get_element_by_class,
1212
int_or_none,
13+
js_to_json,
14+
merge_dicts,
1315
smuggle_url,
1416
unescapeHTML,
1517
)
@@ -98,6 +100,26 @@ def _real_extract(self, url):
98100
bc_attr['data-bcid'])
99101
return self.url_result(smuggle_url(bc_url, {'source_url': url}))
100102

103+
def add_referer(formats):
104+
for f in formats:
105+
f.setdefault('http_headers', {})['Referer'] = url
106+
107+
# As of 01.12.2020 this path looks to cover all cases making the rest
108+
# of the code unnecessary
109+
jwsetup = self._parse_json(
110+
self._search_regex(
111+
r'(?s)jwsetup\s*=\s*({.+?})\s*;', webpage, 'jwsetup',
112+
default='{}'),
113+
video_id, transform_source=js_to_json, fatal=False)
114+
if jwsetup:
115+
info = self._parse_jwplayer_data(
116+
jwsetup, video_id, require_title=False, m3u8_id='hls',
117+
base_url=url)
118+
add_referer(info['formats'])
119+
ld_info = self._search_json_ld(webpage, video_id, default={})
120+
return merge_dicts(info, ld_info)
121+
122+
# Obsolete
101123
# We first look for clipid, because clipprog always appears before
102124
patterns = [r'id=\'clip(%s)\'\s*value=\'([0-9]+)\'' % t for t in ('id', 'prog')]
103125
results = list(filter(None, (re.search(p, webpage) for p in patterns)))
@@ -165,6 +187,7 @@ def get_text_attr(d, attr):
165187
formats = self._extract_m3u8_formats(
166188
path, video_id, 'mp4', entry_protocol='m3u8_native',
167189
m3u8_id='hls') if determine_ext(path) == 'm3u8' else [{'url': path, }]
190+
add_referer(formats)
168191
self._sort_formats(formats)
169192
entries.append({
170193
'id': '%s_%d' % (video_id, partnum + 1),

youtube_dl/extractor/drtv.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class DRTVIE(InfoExtractor):
2929
https?://
3030
(?:
3131
(?:www\.)?dr\.dk/(?:tv/se|nyheder|radio(?:/ondemand)?)/(?:[^/]+/)*|
32-
(?:www\.)?(?:dr\.dk|dr-massive\.com)/drtv/(?:se|episode)/
32+
(?:www\.)?(?:dr\.dk|dr-massive\.com)/drtv/(?:se|episode|program)/
3333
)
3434
(?P<id>[\da-z_-]+)
3535
'''
@@ -111,6 +111,9 @@ class DRTVIE(InfoExtractor):
111111
}, {
112112
'url': 'https://dr-massive.com/drtv/se/bonderoeven_71769',
113113
'only_matching': True,
114+
}, {
115+
'url': 'https://www.dr.dk/drtv/program/jagten_220924',
116+
'only_matching': True,
114117
}]
115118

116119
def _real_extract(self, url):

youtube_dl/extractor/extractors.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,10 @@
11901190
EMPFlixIE,
11911191
MovieFapIE,
11921192
)
1193-
from .toggle import ToggleIE
1193+
from .toggle import (
1194+
ToggleIE,
1195+
MeWatchIE,
1196+
)
11941197
from .tonline import TOnlineIE
11951198
from .toongoggles import ToonGogglesIE
11961199
from .toutv import TouTvIE
@@ -1483,6 +1486,8 @@
14831486
YandexMusicTrackIE,
14841487
YandexMusicAlbumIE,
14851488
YandexMusicPlaylistIE,
1489+
YandexMusicArtistTracksIE,
1490+
YandexMusicArtistAlbumsIE,
14861491
)
14871492
from .yandexvideo import YandexVideoIE
14881493
from .yapfiles import YapFilesIE

youtube_dl/extractor/ina.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
class InaIE(InfoExtractor):
15-
_VALID_URL = r'https?://(?:www\.)?ina\.fr/(?:video|audio)/(?P<id>[A-Z0-9_]+)'
15+
_VALID_URL = r'https?://(?:(?:www|m)\.)?ina\.fr/(?:video|audio)/(?P<id>[A-Z0-9_]+)'
1616
_TESTS = [{
1717
'url': 'http://www.ina.fr/video/I12055569/francois-hollande-je-crois-que-c-est-clair-video.html',
1818
'md5': 'a667021bf2b41f8dc6049479d9bb38a3',
@@ -31,6 +31,9 @@ class InaIE(InfoExtractor):
3131
}, {
3232
'url': 'https://www.ina.fr/video/P16173408-video.html',
3333
'only_matching': True,
34+
}, {
35+
'url': 'http://m.ina.fr/video/I12055569',
36+
'only_matching': True,
3437
}]
3538

3639
def _real_extract(self, url):

youtube_dl/extractor/mediaset.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class MediasetIE(ThePlatformBaseIE):
2323
https?://
2424
(?:(?:www|static3)\.)?mediasetplay\.mediaset\.it/
2525
(?:
26-
(?:video|on-demand)/(?:[^/]+/)+[^/]+_|
26+
(?:video|on-demand|movie)/(?:[^/]+/)+[^/]+_|
2727
player/index\.html\?.*?\bprogramGuid=
2828
)
2929
)(?P<id>[0-9A-Z]{16,})
@@ -88,6 +88,9 @@ class MediasetIE(ThePlatformBaseIE):
8888
}, {
8989
'url': 'https://www.mediasetplay.mediaset.it/video/grandefratellovip/benedetta-una-doccia-gelata_F309344401044C135',
9090
'only_matching': True,
91+
}, {
92+
'url': 'https://www.mediasetplay.mediaset.it/movie/herculeslaleggendahainizio/hercules-la-leggenda-ha-inizio_F305927501000102',
93+
'only_matching': True,
9194
}]
9295

9396
@staticmethod

youtube_dl/extractor/pornhub.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,9 @@ def add_video_url(video_url):
346346
view_count = self._extract_count(
347347
r'<span class="count">([\d,\.]+)</span> [Vv]iews', webpage, 'view')
348348
like_count = self._extract_count(
349-
r'<span class="votesUp">([\d,\.]+)</span>', webpage, 'like')
349+
r'<span[^>]+class="votesUp"[^>]*>([\d,\.]+)</span>', webpage, 'like')
350350
dislike_count = self._extract_count(
351-
r'<span class="votesDown">([\d,\.]+)</span>', webpage, 'dislike')
351+
r'<span[^>]+class="votesDown"[^>]*>([\d,\.]+)</span>', webpage, 'dislike')
352352
comment_count = self._extract_count(
353353
r'All Comments\s*<span>\(([\d,.]+)\)', webpage, 'comment')
354354

youtube_dl/extractor/spreaker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def _real_extract(self, url):
126126
class SpreakerShowIE(InfoExtractor):
127127
_VALID_URL = r'https?://api\.spreaker\.com/show/(?P<id>\d+)'
128128
_TESTS = [{
129-
'url': 'https://www.spreaker.com/show/3-ninjas-podcast',
129+
'url': 'https://api.spreaker.com/show/4652058',
130130
'info_dict': {
131131
'id': '4652058',
132132
},

0 commit comments

Comments
 (0)