1
0
Fork 0
VideoPlayer/src/qml/Dialogs/PlaylistDialog.qml

219 lines
6 KiB
QML
Raw Normal View History

import QtQuick 2.0
2018-12-22 14:13:53 +00:00
import QtQuick.Controls 2.3
import QtQuick.Dialogs 1.3
2018-12-22 14:21:42 +00:00
import QtQuick.Window 2.2
import player 1.0
Dialog {
2020-05-06 12:43:01 +01:00
id: playlistDialog
title: "Playlist"
height: Math.max(480, childrenRect.height * playlistListView.count)
width: 720
modality: Qt.NonModal
property int thumbnailJobsRunning: 0
property variant thumbnailJobs: []
property int titleJobsRunning: 0
property variant titleJobs: []
function addThumbnailToCache(name, output) {
output = output.replace("maxresdefault", "sddefault").split('\n')[0]
thumbnailCache.addURL(name, output)
thumbnailJobs.shift()
thumbnailJobsRunning -= 1
}
ThumbnailCache {
id: thumbnailCache
}
Rectangle {
visible: false
id: titleGetter
signal titleFound(string name, string title)
}
Timer {
interval: 100
repeat: true
triggeredOnStart: true
running: true
onTriggered: {
if (thumbnailJobsRunning < 2) {
if (thumbnailJobs.length > 0) {
if (thumbnailJobs[0].startsWith(
"https://www.youtube.com/playlist?list=")) {
thumbnailJobs.shift()
return
}
var component = Qt.createComponent("ThumbnailProcess.qml")
var thumbnailerProcess = component.createObject(playlistDialog, {
"name": thumbnailJobs[0]
})
if (String(titleJobs[0]).indexOf("://") !== -1) {
thumbnailerProcess.start("youtube-dl",
["--get-thumbnail", thumbnailJobs[0]])
} else {
thumbnailerProcess.start(
"ffmpegthumbnailer",
["-i", thumbnailJobs[0], "-o", "/tmp/" + Qt.md5(
thumbnailJobs[0]) + ".png"])
}
thumbnailJobsRunning += 1
}
}
}
2020-05-06 12:43:01 +01:00
}
Timer {
interval: 100
repeat: true
triggeredOnStart: true
running: true
onTriggered: {
if (titleJobsRunning < 5) {
if (titleJobs.length > 0) {
if (titleJobs[0].startsWith(
"https://www.youtube.com/playlist?list=")) {
titleJobs.shift()
return
}
var component = Qt.createComponent("TitleProcess.qml")
var titleProcess = component.createObject(playlistDialog, {
"name": titleJobs[0]
})
titleProcess.start("youtube-dl", ["--get-title", titleJobs[0]])
titleJobs.shift()
titleJobsRunning += 1
}
}
}
2020-05-06 12:43:01 +01:00
}
Connections {
target: player
onPlaylistChanged: function (playlist) {
playlistModel.clear()
thumbnailJobs = []
titleJobs = []
titleJobsRunning = 0
thumbnailJobsRunning = 0
for (var thing in playlist) {
var item = playlist[thing]
playlistModel.append({
"playlistItemTitle": item["title"],
"playlistItemFilename": item["filename"],
"current": item["current"],
"playlistPos": thing
})
}
}
2020-05-06 12:43:01 +01:00
}
Component {
id: playlistDelegate
Item {
id: playlistItem
property string itemURL: ""
property string itemTitle: ""
width: playlistDialog.width
height: childrenRect.height
function getText(title, filename) {
var itemText = ""
if (title.length > 0) {
itemText += '<b>Title:</b> ' + title + "<br>"
}
2020-05-06 12:43:01 +01:00
if (filename.length > 0) {
itemText += '<b>Filename:</b> ' + filename
}
2020-05-06 12:43:01 +01:00
return itemText
}
Connections {
target: thumbnailCache
onThumbnailReady: function (name, url, path) {
if (name == playlistItem.itemURL) {
thumbnail.source = path
}
}
}
Connections {
target: titleGetter
onTitleFound: function (name, title) {
if (name == playlistItem.itemURL) {
titleJobsRunning -= 1
playlistItem.itemTitle = title
}
}
}
Image {
id: thumbnail
source: ""
height: source.toString().length > 1 ? 144 : 0
width: source.toString().length > 1 ? 256 : 0
}
Button {
width: parent.width - 20
id: playlistItemButton
font.pixelSize: 12
padding: 0
anchors.left: thumbnail.right
bottomPadding: 0
contentItem: Text {
id: playlistItemText
font: parent.font
color: "white"
text: playlistItem.getText(itemTitle, itemURL)
height: parent.height
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
wrapMode: Text.Wrap
}
2020-05-06 12:43:01 +01:00
onClicked: {
player.playerCommand(Enums.Commands.SetPlaylistPos, playlistPos)
}
2020-05-06 12:43:01 +01:00
background: Rectangle {
color: current ? "orange" : "transparent"
}
}
2020-05-06 12:43:01 +01:00
Component.onCompleted: {
if (typeof playlistItemTitle !== "undefined") {
playlistItem.itemTitle = playlistItemTitle
} else {
playlistDialog.titleJobs.push(playlistItemFilename)
}
2020-05-06 12:43:01 +01:00
if (typeof playlistItemFilename !== "undefined") {
playlistItem.itemURL = playlistItemFilename
} else {
playlistItem.itemURL = ""
}
2020-05-06 12:43:01 +01:00
playlistDialog.thumbnailJobs.push(playlistItemFilename)
}
}
}
ListView {
id: playlistListView
anchors.fill: parent
model: ListModel {
id: playlistModel
}
delegate: playlistDelegate
highlight: Item {}
snapMode: ListView.SnapToItem
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar {
active: playlistListView.count > 1 ? true : true
}
2020-05-06 12:43:01 +01:00
focus: true
}
}