You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
9.0 KiB
Python
231 lines
9.0 KiB
Python
2 years ago
|
from PyQt5 import QtWidgets as qtw
|
||
|
from PyQt5 import QtGui as qtg
|
||
|
from PyQt5 import QtCore as qtc
|
||
|
|
||
|
from pytube import YouTube
|
||
|
from urllib.request import urlopen
|
||
|
import urllib.request
|
||
|
|
||
|
from PyQt5.QtWidgets import QApplication, QGridLayout, QVBoxLayout, QLabel
|
||
|
|
||
|
from collections import OrderedDict
|
||
|
from functools import partial
|
||
|
|
||
|
import sys
|
||
|
|
||
|
class Ui_MainWindow(object):
|
||
|
def setupUi(self, MainWindow):
|
||
|
MainWindow.setObjectName("MainWindow")
|
||
|
MainWindow.resize(388, 255)
|
||
|
self.centralwidget = qtw.QWidget(MainWindow)
|
||
|
self.centralwidget.setObjectName("centralwidget")
|
||
|
self.widget = qtw.QWidget(self.centralwidget)
|
||
|
self.widget.setGeometry(qtc.QRect(20, 10, 361, 241))
|
||
|
self.widget.setObjectName("widget")
|
||
|
self.gridLayout = qtw.QGridLayout(self.centralwidget)
|
||
|
self.gridLayout.setObjectName("gridLayout")
|
||
|
self.verticalLayout = qtw.QVBoxLayout(self.widget)
|
||
|
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||
|
self.horizontalLayout = qtw.QHBoxLayout()
|
||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||
|
self.lineEdit_url = qtw.QLineEdit(self.widget)
|
||
|
self.lineEdit_url.setObjectName("lineEdit_url")
|
||
|
self.horizontalLayout.addWidget(self.lineEdit_url)
|
||
|
self.insertUrl = qtw.QPushButton(self.widget)
|
||
|
self.insertUrl.setObjectName("insertUrl")
|
||
|
self.horizontalLayout.addWidget(self.insertUrl)
|
||
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||
|
self.scrollA = qtw.QScrollArea(self.widget)
|
||
|
self.scrollA.setWidgetResizable(True)
|
||
|
self.scrollA.setObjectName("scrollA")
|
||
|
self.scrollAreaWidgetContents = qtw.QWidget()
|
||
|
self.scrollAreaWidgetContents.setGeometry(qtc.QRect(0, 0, 357, 206))
|
||
|
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||
|
self.gridLayout_scroller = qtw.QGridLayout(self.scrollAreaWidgetContents)
|
||
|
self.gridLayout_scroller.setObjectName("gridLayout_scroller")
|
||
|
self.scrollA.setWidget(self.scrollAreaWidgetContents)
|
||
|
self.verticalLayout.addWidget(self.scrollA)
|
||
|
MainWindow.setCentralWidget(self.centralwidget)
|
||
|
|
||
|
self.retranslateUi(MainWindow)
|
||
|
qtc.QMetaObject.connectSlotsByName(MainWindow)
|
||
|
|
||
|
def retranslateUi(self, MainWindow):
|
||
|
_translate = qtc.QCoreApplication.translate
|
||
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
||
|
self.insertUrl.setText(_translate("MainWindow", "PushButton"))
|
||
|
|
||
|
class QYTVidItem(qtw.QWidget):
|
||
|
def __init__(self, parent=None):
|
||
|
super(QYTVidItem, self).__init__(parent)
|
||
|
|
||
|
self.vid_layout = qtw.QHBoxLayout()
|
||
|
self.vidDetailLayout = qtw.QVBoxLayout()
|
||
|
self.vidHeaderLayout = qtw.QHBoxLayout()
|
||
|
self.vidSpecsLayout = qtw.QHBoxLayout()
|
||
|
self.vidStartEndLayout = qtw.QHBoxLayout()
|
||
|
self.buttonLayout = qtw.QHBoxLayout()
|
||
|
|
||
|
self.title = ""
|
||
|
self.url = ""
|
||
|
|
||
|
def setData(self,purl):
|
||
|
self.url = purl.strip()
|
||
|
|
||
|
errTxt = "OK"
|
||
|
|
||
|
# load Youtube vid infos
|
||
|
yt_vid = YouTube(url=purl)
|
||
|
|
||
|
self.title = yt_vid.title
|
||
|
|
||
|
##left Side:
|
||
|
# Thumbnail of video (or default if no thumb is found)
|
||
|
thumbNail_url = yt_vid.thumbnail_url
|
||
|
thumbPixmap = qtg.QPixmap()
|
||
|
try:
|
||
|
request = urllib.request.Request(thumbNail_url)
|
||
|
response = urllib.request.urlopen(request)
|
||
|
data = response.read()
|
||
|
thumbPixmap.loadFromData(data)
|
||
|
|
||
|
icoLabel = qtw.QLabel()
|
||
|
icoLabel.setPixmap(thumbPixmap.scaled(150,150,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||
|
self.vid_layout.addWidget(icoLabel)
|
||
|
except Exception:
|
||
|
pass
|
||
|
|
||
|
##right side
|
||
|
# most upper row:
|
||
|
# title
|
||
|
title = qtw.QLabel(yt_vid.title)
|
||
|
self.vidHeaderLayout.addWidget(title)
|
||
|
|
||
|
self.btn_remove = qtw.QToolButton()
|
||
|
self.vidHeaderLayout.addWidget(self.btn_remove)
|
||
|
|
||
|
self.vidDetailLayout.addItem(self.vidHeaderLayout)
|
||
|
|
||
|
# Mid row:
|
||
|
# Video Specs
|
||
|
dur_time = yt_vid.length
|
||
|
duration = qtw.QLabel("Duration: {} sec".format(dur_time))
|
||
|
self.vidSpecsLayout.addWidget(duration)
|
||
|
|
||
|
self.vidDetailLayout.addItem(self.vidSpecsLayout)
|
||
|
|
||
|
# mid lower row:
|
||
|
# Start/End Marker
|
||
|
self.vidStartEndLayout.setContentsMargins(5,0,5,0)
|
||
|
self.vidStartEndLayout.setSpacing(10);
|
||
|
self.vidStartEndLayout.setAlignment(qtc.Qt.AlignLeft)
|
||
|
|
||
|
vid_start_txt = qtw.QLabel("start at(sec):")
|
||
|
vid_start_txt.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||
|
self.vidStartEndLayout.addWidget(vid_start_txt)
|
||
|
|
||
|
lowVal = 0
|
||
|
self.vid_start = qtw.QLabel(str(lowVal))
|
||
|
self.vid_start.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||
|
self.vidStartEndLayout.addWidget(self.vid_start)
|
||
|
|
||
|
vid_end_txt = qtw.QLabel("end at(sec):")
|
||
|
vid_end_txt.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||
|
self.vidStartEndLayout.addWidget(vid_end_txt)
|
||
|
|
||
|
highVal = 99
|
||
|
self.vid_end = qtw.QLabel(str(highVal))
|
||
|
|
||
|
self.vidStartEndLayout.addWidget(self.vid_end)
|
||
|
self.vidStartEndLayout.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||
|
self.vidDetailLayout.addItem(self.vidStartEndLayout)
|
||
|
|
||
|
# lower row:
|
||
|
# Video specific Buttons (picograms)
|
||
|
self.buttonLayout.setSpacing(10);
|
||
|
self.buttonLayout.setAlignment(qtc.Qt.AlignLeft)
|
||
|
|
||
|
btn_play = qtw.QToolButton()
|
||
|
self.buttonLayout.addWidget(btn_play)
|
||
|
|
||
|
btn_stop = qtw.QToolButton()
|
||
|
self.buttonLayout.addWidget(btn_stop)
|
||
|
|
||
|
btn_download = qtw.QToolButton()
|
||
|
self.buttonLayout.addWidget(btn_download)
|
||
|
|
||
|
self.vidDetailLayout.addItem(self.buttonLayout)
|
||
|
|
||
|
#assamble Layouts and activate it
|
||
|
self.vid_layout.addItem(self.vidDetailLayout)
|
||
|
self.setLayout(self.vid_layout)
|
||
|
|
||
|
return errTxt
|
||
|
|
||
|
|
||
|
class MainWindow(qtw.QMainWindow):
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args,**kwargs)
|
||
|
|
||
|
self.main_window = Ui_MainWindow()
|
||
|
self.main_window.setupUi(self)
|
||
|
|
||
|
self.ytVidODict = OrderedDict()
|
||
|
|
||
|
self.main_window.insertUrl.clicked.connect(self.insertUrl)
|
||
|
|
||
|
def insertUrl(self):
|
||
|
|
||
|
if (self.main_window.lineEdit_url.text() == ''):
|
||
|
return
|
||
|
else:
|
||
|
newUrl = self.main_window.lineEdit_url.text()
|
||
|
|
||
|
if newUrl.strip() in self.ytVidODict:
|
||
|
return
|
||
|
|
||
|
#Test URL: Rick Roll https://www.youtube.com/watch?v=Lrj2Hq7xqQ8
|
||
|
#Test URL2: BudS&TerH - Lala Remix: https://www.youtube.com/watch?v=lL7jwhWAU_k
|
||
|
|
||
|
item = QYTVidItem(self.main_window.scrollA)
|
||
|
returnCode = item.setData(newUrl)
|
||
|
if (returnCode == "OK"):
|
||
|
row = self.main_window.gridLayout_scroller.count()
|
||
|
col = 0
|
||
|
self.main_window.gridLayout_scroller.addWidget(item,row,col,1,1)
|
||
|
|
||
|
#save in OrderedDict:
|
||
|
item.btn_remove.clicked.connect(partial(self.removeYTVid,newUrl))
|
||
|
self.ytVidODict[newUrl.strip()] = item
|
||
|
else:
|
||
|
self.main_window.insert_url_msg.setText(returnCode)
|
||
|
|
||
|
self.main_window.lineEdit_url.setText("")
|
||
|
|
||
|
def removeYTVid(self,url):
|
||
|
#pop from ordered dict
|
||
|
for vidItem in self.ytVidODict:
|
||
|
if vidItem == url.strip():
|
||
|
self.ytVidODict.pop(url.strip())
|
||
|
break
|
||
|
|
||
|
#clear gridlayout from remaining children
|
||
|
for i in reversed(range(self.main_window.gridLayout_scroller.count())):
|
||
|
widgetToRemove = self.main_window.gridLayout_scroller.itemAt( i ).widget()
|
||
|
self.main_window.gridLayout_scroller.removeWidget( widgetToRemove )
|
||
|
|
||
|
#repopulate gridlayout
|
||
|
for vidItem in self.ytVidODict:
|
||
|
row = self.main_window.gridLayout_scroller.count()
|
||
|
col = 0
|
||
|
self.main_window.gridLayout_scroller.addWidget(self.ytVidODict[vidItem],row,col,1,1)
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
app = QApplication(sys.argv)
|
||
|
window = MainWindow()
|
||
|
|
||
|
window.show()
|
||
|
|
||
|
sys.exit(app.exec_())
|