from PySide2.QtCore import QObject, Slot, Signal, QThread, QCoreApplication
import pafy
from main import MainWindow
from PySide2.QtWidgets import *
class Worker(MainWindow, QObject):
finished = Signal()
def download(self, video, stream, path):
video_streams = pafy.new(video).streams
video_streams[stream].download(filepath=path, quiet=True, callback=self.progressbar)
self.finished.emit()
def progressbar(self, total, recvd, ratio, rate, eta):
"""
progress Bar For Videos Download
"""
value = int(recvd * 100 / total)
self.progressBar.emit(value)
return
class GetVideo(MainWindow, QObject):
finished = Signal()
def __init__(self):
super().__init__()
def getVideo(self, url):
self.video = pafy.new(url)
self.getStreams(self.video)
return self.video
def thumbnail(self, video):
return video.thumb
def getStreams(self, video):
videoStreams = []
for streams in video.streams:
videoStreams.append(streams)
return videoStreams
def download(self, stream, path, video):
self.worker = Worker()
self.worker_thread = QThread()
self.worker.moveToThread(self.worker_thread)
self.worker.finished.connect(self.worker_thread.quit)
self.worker_thread.started.connect(self.worker.download(video, stream, path))
self.worker_thread.start()
while self.worker_thread.isRunning():
QApplication.sendPostedEvents()
QApplication.processEvents()
QML File
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
import QtQuick.Shapes 1.15
import QtQuick.Dialogs 1.3
import "../components"
Item {
property string videoImage: "https://www.pandasecurity.com/en/mediacenter/src/uploads/2013/11/pandasecurity-facebook-photo-privacy.jpg"
property string saveLoction: '.'
property var items: []
property var path: textPath.text
property var streamIndex: [comboBox.currentIndex, textPath.text]
property int progressbar_value: 0
Rectangle {
id: rectangle
color: "#313038"
anchors.fill: parent
Rectangle {
id: rectangle1
color: "#00000000"
anchors.fill: parent
Row {
id: row
anchors.fill: parent
Image {
id: img
source: videoImage
anchors.horizontalCenter: circularProgressbar.horizontalCenter
asynchronous: false
width: 227
height: 227
anchors.verticalCenter: circularProgressbar.verticalCenter
fillMode: Image.PreserveAspectCrop
layer.enabled: true
layer.effect: OpacityMask {
maskSource: mask
}
}
Rectangle {
id: mask
width: 227
height: 227
radius: 250
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: circularProgressbar.horizontalCenter
visible: false
}
CircularProgressbar{
id: circularProgressbar
width: 250
height: 250
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 20
value: progressbar_value
}
Rectangle {
id: rectangle2
height: 260
color: "#00000000"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
clip: false
anchors.rightMargin: 20
anchors.leftMargin: 300
Rectangle {
id: rectangle3
color: "#5f5e6d"
radius: 20
anchors.fill: parent
anchors.bottomMargin: -19
anchors.leftMargin: -14
anchors.topMargin: -18
anchors.rightMargin: -13
}
TextField {
id: textUrl
y: 0
height: 40
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 0
anchors.rightMargin: 0
placeholderText: qsTr("Text Field")
}
RoundButton {
id: btnGetVideo
height: 40
text: "Get Video"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: textUrl.bottom
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 21
onClicked: backend.checkVideo(textUrl.text)
}
TextField {
id: textPath
height: 40
anchors.left: parent.left
anchors.right: parent.right
anchors.top: btnGetVideo.bottom
anchors.topMargin: 20
placeholderText: qsTr("Text Field")
anchors.leftMargin: 0
anchors.rightMargin: 97
text: path
}
RoundButton {
id: btnBrowse
width: 86
height: 40
text: "Browse"
anchors.left: textPath.right
anchors.top: btnGetVideo.bottom
anchors.bottom: comboBox.top
anchors.leftMargin: 11
anchors.topMargin: 20
anchors.bottomMargin: 20
onClicked: saveDialog.visible = true
}
FileDialog {
id: saveDialog
title: "Save Video"
folder: shortcuts.desktop
selectFolder: true
onAccepted: {
path = saveDialog.fileUrl
}
onRejected: {
massageEnterPath.open()
}
}
MessageDialog{
id: massageEnterPath
title: "Select Folder To Save"
text: "IF You Want To Start Download Video Select Path First"
}
ComboBox {
id: comboBox
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 179
anchors.bottomMargin: 56
anchors.leftMargin: 0
anchors.rightMargin: 0
}
RoundButton {
id: btnDownloadVideo
text: "Download"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: textPath.bottom
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.rightMargin: 0
anchors.topMargin: 60
onClicked:streamIndex.push(textUrl.text), backend.start_download(streamIndex)
}
}
}
}
}
Connections{
target: backend
function onThumb(url){
videoImage = url
}
function onVideoStreams(itemsss){
items.push(itemsss)
comboBox.model = items
}
function onProgressBar(prec){
progressbar_value = prec
console.log("In JavaScript",prec)
CircularProgressbar.value = progressbar_value
}
}
}
Read more here: https://stackoverflow.com/questions/67016058/why-not-put-the-value-of-progress-bar
Content Attribution
This content was originally published by Islam Abd El-Motey at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.