Files
qyouvideo/VideoPlayer.qml

181 lines
4.6 KiB
QML
Raw Normal View History

2025-10-18 21:40:02 +02:00
import QtQuick 6.8
import QtMultimedia 6.8
import QtQuick.Controls 6.8
import QtQuick.Layouts 6.8
import QYRComponents 1.0
2025-10-19 22:35:30 +02:00
Item {
// color: Colors.surface1
// radius: 10
required property string id
property bool hasThumbnail: false
property bool loading: true
property bool failed: false
property string title
property string description
property string extension
property real position: 0
property real duration: 0
property real ratio
anchors.fill: parent
2025-10-18 21:40:02 +02:00
ColumnLayout {
2025-10-19 22:35:30 +02:00
visible: !loading && !failed
2025-10-18 21:40:02 +02:00
anchors.fill: parent
2025-10-19 22:35:30 +02:00
Image {
Layout.fillWidth: true
height: width * parent.parent.ratio
asynchronous: true
cache: true
source: parent.parent.hasThumbnail ? ("https://youvideo.nonamesoft.xyz/thumbnails/" + parent.parent.id) : "https://youvideo.nonamesoft.xyz/thumbnails/audio.png"
fillMode: Image.PreserveAspectFit
2025-10-19 02:58:12 +02:00
}
2025-10-18 21:40:02 +02:00
RowLayout {
Button {
2025-10-19 02:58:12 +02:00
text: Player.loading ? "Loading" : (Player.playing ? "Pause" : "Play")
enabled: !Player.loading
2025-10-18 21:40:02 +02:00
onClicked: function() {
if (Player.playing) {
Player.pause()
} else {
Player.play();
}
}
}
Button {
text: "Stop"
onClicked: Player.stop()
}
2025-10-19 02:58:12 +02:00
Label {
heading: "h4"
text: new Date(Player.position).toISOString().slice(14, 19)
}
2025-10-18 21:40:02 +02:00
Slider {
Layout.fillWidth: true
from: 0
2025-10-19 22:35:30 +02:00
to: parent.parent.parent.duration
value: parent.parent.parent.position
2025-10-19 02:58:12 +02:00
buffered: Player.buffered
onMoved: Player.position = value
}
Label {
heading: "h4"
2025-10-19 22:35:30 +02:00
text: new Date(parent.parent.parent.duration).toISOString().slice(14, 19)
2025-10-19 02:58:12 +02:00
}
Label {
text: Player.buffered
2025-10-18 21:40:02 +02:00
}
Slider {
from: 0
to: 1
value: Player.volume
onMoved: Player.volume = value
}
}
2025-10-19 02:58:12 +02:00
Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
clip: true
2025-10-19 22:35:30 +02:00
text: parent.parent.title
2025-10-19 02:58:12 +02:00
heading: "h2"
font.bold: true
}
Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
clip: true
2025-10-19 22:35:30 +02:00
text: parent.parent.description
2025-10-19 02:58:12 +02:00
heading: "h4"
font.bold: true
}
2025-10-19 22:35:30 +02:00
Item {
Layout.fillHeight: true
}
}
BusyIndicator {
anchors.centerIn: parent
visible: loading
running: loading
}
ColumnLayout {
Layout.alignment: Qt.AlignVCenter
anchors.centerIn: parent
visible: failed
Label {
text: "Couldn't get video details!"
heading: "h2"
font.bold: true
}
Label {
text: "This could mean that either your internet or YouVideo is down."
heading: "h4"
}
Label {
Layout.bottomMargin: 25
text: "Check your network connection and try again!"
heading: "h4"
}
Button {
text: "Retry"
onClicked: parent.fetchData()
}
}
Timer {
interval: 1000
running: true
onTriggered: parent.fetchData()
}
function fetchData() {
loading = true;
failed = false;
const xhr = new XMLHttpRequest;
xhr.open("GET", "https://youvideo.nonamesoft.xyz/youvideo/video/" + id);
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
loading = false;
if (xhr.status != 200) {
console.log("Invalid response");
failed = true;
return;
}
const data = JSON.parse(xhr.responseText);
console.log("Received video metadata");
title = data.name;
description = data.description;
extension = data.extension;
ratio = data.metadata.size[0] / data.metadata.size[1];
console.log(ratio);
}
}
xhr.ontimeout = function() {
loading = false;
failed = true;
console.log("Request timed out");
}
xhr.send();
2025-10-18 21:40:02 +02:00
}
}