forked from ghostfox/qyouradio
Compare commits
5 Commits
fuckedupgi
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ac6248c66 | ||
|
|
c168086601 | ||
| 629408b02e | |||
|
|
e66cf1b137 | ||
|
|
e091c97305 |
@@ -21,6 +21,8 @@ qt_add_resources(appqyouvideo "resources"
|
|||||||
resources/logo.png
|
resources/logo.png
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(ComponentCache.qml
|
||||||
|
PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
|
||||||
|
|
||||||
qt_add_qml_module(appqyouvideo
|
qt_add_qml_module(appqyouvideo
|
||||||
URI qyouvideo
|
URI qyouvideo
|
||||||
@@ -31,6 +33,7 @@ qt_add_qml_module(appqyouvideo
|
|||||||
ViewAbout.qml
|
ViewAbout.qml
|
||||||
ViewVideoList.qml
|
ViewVideoList.qml
|
||||||
VideoPlayer.qml
|
VideoPlayer.qml
|
||||||
|
ComponentCache.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
||||||
@@ -65,4 +68,3 @@ install(SCRIPT ${deploy_script})
|
|||||||
|
|
||||||
add_subdirectory(QYRComponents)
|
add_subdirectory(QYRComponents)
|
||||||
|
|
||||||
project(qyouvideo VERSION 0.1 LANGUAGES CXX)
|
|
||||||
|
|||||||
11
ComponentCache.qml
Normal file
11
ComponentCache.qml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick 6.8
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property var videoPlayer: Qt.createComponent("VideoPlayer.qml")
|
||||||
|
property var viewVideoList: Qt.createComponent("ViewVideoList.qml")
|
||||||
|
property var viewAbout: Qt.createComponent("ViewAbout.qml")
|
||||||
|
|
||||||
|
Component.onCompleted: Player.unloadVideo()
|
||||||
|
}
|
||||||
126
Main.qml
126
Main.qml
@@ -11,87 +11,79 @@ ApplicationWindow {
|
|||||||
height: 800
|
height: 800
|
||||||
title: qsTr("QYouVideo")
|
title: qsTr("QYouVideo")
|
||||||
|
|
||||||
ColumnLayout {
|
flags: Qt.Dialog
|
||||||
anchors.fill: parent
|
modality: Qt.ApplicationModal
|
||||||
|
|
||||||
Rectangle {
|
header: Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 43
|
height: 43
|
||||||
|
|
||||||
color: Colors.surface0
|
color: Colors.surface0
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 3
|
anchors.margins: 3
|
||||||
|
|
||||||
Label {
|
Button {
|
||||||
Layout.leftMargin: 5
|
// visible: stack.depth > 1
|
||||||
text: "QYouVideo"
|
text: "Back"
|
||||||
heading: "h1"
|
onClicked: stack.popCurrentItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Label {
|
||||||
Layout.fillWidth: true
|
id: logo
|
||||||
}
|
// visible: stack.currentItem.StackView.index == 0
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
text: "QYouVideo"
|
||||||
|
heading: "h1"
|
||||||
|
clip: true
|
||||||
|
}
|
||||||
|
|
||||||
TabBar {
|
|
||||||
id: tabbar
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
background: Item{}
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
TabButton {
|
Button {
|
||||||
text: qsTr("Videos")
|
text: qsTr("Videos")
|
||||||
outlined: true
|
outlined: true
|
||||||
implicitWidth: 80
|
implicitWidth: 80
|
||||||
}
|
onClicked: if (!(stack.currentItem instanceof ViewVideoList)) stack.push(ComponentCache.viewVideoList.createObject(stack))
|
||||||
TabButton {
|
}
|
||||||
text: qsTr("About")
|
Button {
|
||||||
outlined: true
|
text: qsTr("About")
|
||||||
implicitWidth: 80
|
outlined: true
|
||||||
}
|
implicitWidth: 80
|
||||||
TabButton {
|
onClicked: if (!(stack.currentItem instanceof ViewAbout)) stack.push(ComponentCache.viewAbout.createObject(stack))
|
||||||
text: qsTr("Upload")
|
}
|
||||||
}
|
Button {
|
||||||
}
|
text: qsTr("Upload")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SwipeView {
|
StackView {
|
||||||
Layout.fillWidth: true
|
id: stack
|
||||||
Layout.fillHeight: true
|
// __wheelAreaScrollSpeed: 50
|
||||||
Layout.margins: 20
|
|
||||||
|
|
||||||
interactive: false
|
anchors.fill: parent
|
||||||
currentIndex: tabbar.currentIndex
|
anchors.margins: 20
|
||||||
|
|
||||||
Loader {
|
initialItem: ViewVideoList {}
|
||||||
// active: tabbar.currentIndex == 0
|
|
||||||
active: true
|
|
||||||
asynchronous: true
|
|
||||||
visible: status == Loader.Ready
|
|
||||||
source: "ViewVideoList.qml"
|
|
||||||
}
|
|
||||||
Loader {
|
|
||||||
// active: tabbar.currentIndex == 1
|
|
||||||
active: true
|
|
||||||
asynchronous: true
|
|
||||||
visible: status == Loader.Ready
|
|
||||||
source: "ViewAbout.qml"
|
|
||||||
}
|
|
||||||
Loader {
|
|
||||||
// active: tabbar.currentIndex == 2
|
|
||||||
active: true
|
|
||||||
asynchronous: true
|
|
||||||
visible: status == Loader.Ready
|
|
||||||
sourceComponent: Label {
|
|
||||||
heading: "h1"
|
|
||||||
text: "No idea if I'll ever implement this so don't worry >w<"
|
|
||||||
font.bold: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: contentItem.highlightMoveDuration = 160;
|
function openVideo(id) {
|
||||||
|
// if (stack.find((item, index) => {
|
||||||
|
// // If found player instance
|
||||||
|
// if (item.id == id) {
|
||||||
|
// // stack.pop(index, StackView.Immediate);
|
||||||
|
// stack.push(item)
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }) == null) {
|
||||||
|
// If didn't find player instance
|
||||||
|
stack.push(ComponentCache.videoPlayer.createObject(stack, {id: id}));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import QtQuick.Controls 6.8
|
|||||||
import QtQuick.Controls.Basic 6.8
|
import QtQuick.Controls.Basic 6.8
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
|
id: spinner
|
||||||
contentItem: Rectangle {
|
contentItem: Rectangle {
|
||||||
implicitWidth: 44
|
implicitWidth: 44
|
||||||
implicitHeight: 44
|
implicitHeight: 44
|
||||||
@@ -20,13 +21,13 @@ BusyIndicator {
|
|||||||
radius: 12
|
radius: 12
|
||||||
}
|
}
|
||||||
|
|
||||||
// RotationAnimator {
|
RotationAnimator {
|
||||||
// target: parent
|
target: spinner
|
||||||
// running: parent.parent.visible && parent.parent.running
|
running: spinner.visible && spinner.running
|
||||||
// from: 0
|
from: 0
|
||||||
// to: 360
|
to: 360
|
||||||
// loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
// duration: 1250
|
duration: 1250
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,6 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
id: area
|
id: area
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: Player.loadVideo(parent.id)
|
onClicked: stack.openVideo(parent.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
165
VideoPlayer.qml
165
VideoPlayer.qml
@@ -5,74 +5,82 @@ import QtQuick.Layouts 6.8
|
|||||||
|
|
||||||
import QYRComponents 1.0
|
import QYRComponents 1.0
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
visible: Player.active
|
// color: Colors.surface1
|
||||||
color: Colors.surface1
|
// radius: 10
|
||||||
radius: 10
|
|
||||||
|
|
||||||
property bool unrolled: true
|
StackView.onRemoved: destroy()
|
||||||
|
|
||||||
// width: childrenRect.width
|
required property string id
|
||||||
height: unrolled ? 560 : 96
|
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
|
||||||
|
|
||||||
MouseArea {
|
anchors.fill: parent
|
||||||
anchors.fill: parent
|
|
||||||
height: 20
|
|
||||||
hoverEnabled: true
|
|
||||||
propagateComposedEvents: true
|
|
||||||
|
|
||||||
onClicked: unrolled = true;
|
Component.onCompleted: Player.onPositionChanged = () => {
|
||||||
onContainsMouseChanged: function() {
|
console.log("test print");
|
||||||
if (!containsMouse) {
|
if (Player.id == id) {
|
||||||
unrolled = false;
|
position = Player.position
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component.onDestruction: if (Player.id == id) Player.unloadVideo()
|
||||||
|
onPositionChanged: if (Player.id == id) Player.position = position
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
visible: !loading && !failed
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Item {
|
Image {
|
||||||
visible: unrolled
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: 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
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Button {
|
Button {
|
||||||
text: Player.loading ? "Loading" : (Player.playing ? "Pause" : "Play")
|
text: Player.id == id ? (Player.loading ? "Loading" : (Player.playing ? "Pause" : "Play")) : "Play"
|
||||||
enabled: !Player.loading
|
enabled: Player.id != id || !(Player.loading && Player.id == id)
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
|
if (Player.id != id) {
|
||||||
|
Player.loadVideo(parent.parent.parent.id, parent.parent.parent.extension, parent.parent.parent.title, parent.parent.parent.position);
|
||||||
|
}
|
||||||
|
|
||||||
if (Player.playing) {
|
if (Player.playing) {
|
||||||
Player.pause()
|
Player.pause();
|
||||||
} else {
|
} else {
|
||||||
Player.play();
|
Player.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
|
||||||
text: "Stop"
|
|
||||||
onClicked: Player.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
heading: "h4"
|
heading: "h4"
|
||||||
text: new Date(Player.position).toISOString().slice(14, 19)
|
text: new Date(parent.parent.parent.position).toISOString().slice(14, 19)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Slider {
|
Slider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 0
|
from: 0
|
||||||
to: Player.duration
|
to: parent.parent.parent.duration
|
||||||
value: Player.position
|
value: parent.parent.parent.position
|
||||||
buffered: Player.buffered
|
buffered: Player.id == id ? Player.buffered : 0
|
||||||
onMoved: Player.position = value
|
onMoved: parent.parent.parent.position = value
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
heading: "h4"
|
heading: "h4"
|
||||||
text: new Date(Player.duration).toISOString().slice(14, 19)
|
text: new Date(parent.parent.parent.duration).toISOString().slice(14, 19)
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -91,19 +99,102 @@ Rectangle {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
clip: true
|
clip: true
|
||||||
text: Player.title
|
text: parent.parent.title
|
||||||
heading: "h2"
|
heading: "h2"
|
||||||
font.bold: true
|
font.bold: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
visible: unrolled
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
clip: true
|
clip: true
|
||||||
text: Player.description
|
text: parent.parent.description
|
||||||
heading: "h4"
|
heading: "h4"
|
||||||
font.bold: true
|
font.bold: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.parent.fetchData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 0
|
||||||
|
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;
|
||||||
|
duration = data.metadata.duration * 1000;
|
||||||
|
ratio = data.metadata.size[0] / data.metadata.size[1];
|
||||||
|
if (ratio == NaN) {
|
||||||
|
ratio = 1.77777;
|
||||||
|
}
|
||||||
|
console.log(ratio);
|
||||||
|
if (Player.id == id) {
|
||||||
|
console.log("Already playing, this is not intended but possible in its current state so it's a feature, not a bug :3");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player.loadVideo(id, extension, title, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.ontimeout = function() {
|
||||||
|
loading = false;
|
||||||
|
failed = true;
|
||||||
|
console.log("Request timed out");
|
||||||
|
}
|
||||||
|
xhr.send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,14 @@ import QYRComponents 1.0
|
|||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|
||||||
property bool loading: true
|
property bool loading: true
|
||||||
property bool failed: false
|
property bool failed: false
|
||||||
|
|
||||||
GridView {
|
GridView {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
width: Math.floor(parent.width / cellWidth) * cellWidth
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: Player.active ? 96 : 0
|
|
||||||
visible: !loading || !failed
|
visible: !loading || !failed
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
model: ListModel { id: model }
|
model: ListModel { id: model }
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
@@ -24,6 +22,8 @@ Item {
|
|||||||
cellHeight: 224
|
cellHeight: 224
|
||||||
|
|
||||||
delegate: VideoEntry {}
|
delegate: VideoEntry {}
|
||||||
|
|
||||||
|
Component.onCompleted: console.log(parent.width / cellWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
@@ -56,12 +56,12 @@ Item {
|
|||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: "Retry"
|
text: "Retry"
|
||||||
onClicked: parent.fetchData()
|
onClicked: parent.parent.fetchData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
interval: 1000
|
interval: 0
|
||||||
running: true
|
running: true
|
||||||
onTriggered: parent.fetchData()
|
onTriggered: parent.fetchData()
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ Item {
|
|||||||
loading = true;
|
loading = true;
|
||||||
failed = false;
|
failed = false;
|
||||||
const xhr = new XMLHttpRequest;
|
const xhr = new XMLHttpRequest;
|
||||||
xhr.open("GET", "http://youvideo.nonamesoft.xyz/youvideo/api/videos");
|
xhr.open("GET", "https://youvideo.nonamesoft.xyz/youvideo/api/videos");
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||||||
loading = false;
|
loading = false;
|
||||||
@@ -94,11 +94,4 @@ Item {
|
|||||||
}
|
}
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoPlayer {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
98
player.cpp
98
player.cpp
@@ -1,17 +1,17 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
// HOLY GRAIL
|
// HOLY GRAIL
|
||||||
// https://doc.qt.io/qt-6/qaudiobufferoutput.htmli t
|
// https://doc.qt.io/qt-6/qaudiobufferoutput.html
|
||||||
|
|
||||||
Player::Player(QObject *parent) : QObject(parent),
|
Player::Player(QObject *parent) : QObject(parent),
|
||||||
player(this), output(this), manager(this)
|
player(this), output(this)
|
||||||
{
|
{
|
||||||
QObject::connect(&this->player, &QMediaPlayer::mediaStatusChanged, this, [this] () {
|
QObject::connect(&this->player, &QMediaPlayer::mediaStatusChanged, this, [this] () {
|
||||||
const QMediaPlayer::MediaStatus status = this->player.mediaStatus();
|
const QMediaPlayer::MediaStatus status = this->player.mediaStatus();
|
||||||
if (status == QMediaPlayer::NoMedia)
|
if (status == QMediaPlayer::NoMedia)
|
||||||
{
|
{
|
||||||
qDebug("Player::Player(): NoMedia");
|
qDebug("Player::Player(): NoMedia");
|
||||||
this->stop();
|
this->unloadVideo();
|
||||||
}
|
}
|
||||||
else if (status == QMediaPlayer::BufferingMedia || status == QMediaPlayer::LoadingMedia)
|
else if (status == QMediaPlayer::BufferingMedia || status == QMediaPlayer::LoadingMedia)
|
||||||
{
|
{
|
||||||
@@ -26,13 +26,12 @@ Player::Player(QObject *parent) : QObject(parent),
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (this->m_position == 0)
|
||||||
|
{
|
||||||
|
this->player.play();
|
||||||
|
}
|
||||||
this->m_loading = false;
|
this->m_loading = false;
|
||||||
emit this->loadingChanged();
|
emit this->loadingChanged();
|
||||||
if (!this->m_initialLoadFinished)
|
|
||||||
{
|
|
||||||
this->m_initialLoadFinished = true;
|
|
||||||
this->play();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -41,10 +40,10 @@ Player::Player(QObject *parent) : QObject(parent),
|
|||||||
emit this->positionChanged();
|
emit this->positionChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(&this->player, &QMediaPlayer::bufferProgressChanged, this, [this] () {
|
// QObject::connect(&this->player, &QMediaPlayer::bufferProgressChanged, this, [this] () {
|
||||||
this->m_buffered = this->player.bufferedTimeRange().latestTime() / this->m_duration;
|
// this->m_buffered = this->player.bufferedTimeRange().latestTime() / this->m_duration;
|
||||||
emit this->bufferedChanged();
|
// emit this->bufferedChanged();
|
||||||
});
|
// });
|
||||||
|
|
||||||
QObject::connect(&this->player, &QMediaPlayer::errorOccurred, this, [this] () {
|
QObject::connect(&this->player, &QMediaPlayer::errorOccurred, this, [this] () {
|
||||||
this->m_failed = true;
|
this->m_failed = true;
|
||||||
@@ -107,47 +106,28 @@ void Player::setPosition(float newPosition)
|
|||||||
// Methods
|
// Methods
|
||||||
// ***********
|
// ***********
|
||||||
|
|
||||||
void Player::loadVideo(QString id)
|
// For QYouRadio:
|
||||||
|
// QEventLoop loop(this);
|
||||||
|
// QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||||
|
// loop.exec();
|
||||||
|
// const QJsonDocument data = QJsonDocument::fromJson(reply->readAll());
|
||||||
|
|
||||||
|
void Player::loadVideo(QString id, QString extension, QString title, float position)
|
||||||
{
|
{
|
||||||
if (this->m_active)
|
if (this->m_id != id)
|
||||||
{
|
{
|
||||||
this->unloadVideo();
|
this->unloadVideo();
|
||||||
}
|
}
|
||||||
QNetworkReply* reply = this->manager.get(QNetworkRequest(QUrl("https://youvideo.nonamesoft.xyz/youvideo/video/" + id)));
|
|
||||||
|
|
||||||
QEventLoop loop(this);
|
|
||||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
|
||||||
loop.exec();
|
|
||||||
|
|
||||||
if (reply->error() != QNetworkReply::NoError)
|
|
||||||
{
|
|
||||||
qDebug() << "Player::loadVideo(): Video " << id << " doesn't exist!\n";
|
|
||||||
delete reply;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonDocument data = QJsonDocument::fromJson(reply->readAll());
|
|
||||||
|
|
||||||
this->player.setSource(QUrl("https://youvideo.nonamesoft.xyz/youvideo/api/videofile/with_extension/" + id + data ["extension"].toString()));
|
|
||||||
|
|
||||||
this->m_title = data["name"].toString();
|
|
||||||
emit this->titleChanged();
|
|
||||||
|
|
||||||
this->m_description = data["description"].toString();
|
|
||||||
emit this->descriptionChanged();
|
|
||||||
|
|
||||||
this->m_id = id;
|
this->m_id = id;
|
||||||
emit this->idChanged();
|
emit this->idChanged();
|
||||||
|
|
||||||
this->m_initialLoadFinished = false;
|
this->player.setSource(QUrl("https://youvideo.nonamesoft.xyz/youvideo/api/videofile/with_extension/" + id + extension));
|
||||||
|
|
||||||
this->m_active = true;
|
this->m_title = title;
|
||||||
emit this->activeChanged();
|
emit this->titleChanged();
|
||||||
|
|
||||||
this->m_duration = data["metadata"]["duration"].toDouble() * 1000;
|
this->m_position = position;
|
||||||
emit this->durationChanged();
|
|
||||||
|
|
||||||
this->m_position = 0;
|
|
||||||
emit this->positionChanged();
|
emit this->positionChanged();
|
||||||
|
|
||||||
this->m_buffered = 0;
|
this->m_buffered = 0;
|
||||||
@@ -159,24 +139,31 @@ void Player::loadVideo(QString id)
|
|||||||
this->m_failed = false;
|
this->m_failed = false;
|
||||||
emit this->failedChanged();
|
emit this->failedChanged();
|
||||||
|
|
||||||
qDebug() << "Player::loadVideo(): Loaded video https://youvideo.nonamesoft.xyz/youvideo/api/videofile/with_extension/" + id + data ["extension"].toString();
|
qDebug() << "Player::loadVideo(): Loaded video https://youvideo.nonamesoft.xyz/youvideo/api/videofile/with_extension/" + id + extension;
|
||||||
|
|
||||||
delete reply;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::unloadVideo() {
|
void Player::unloadVideo() {
|
||||||
qDebug("Player::unloadVideo(): Video unloaded");
|
qDebug("Player::unloadVideo(): Video unloaded");
|
||||||
|
|
||||||
|
this->m_id = "";
|
||||||
|
emit this->idChanged();
|
||||||
|
|
||||||
this->player.setSource(QUrl(""));
|
this->player.setSource(QUrl(""));
|
||||||
this->player.stop();
|
this->player.stop();
|
||||||
|
|
||||||
|
this->m_title = "";
|
||||||
|
emit this->titleChanged();
|
||||||
|
|
||||||
|
this->m_loading = false;
|
||||||
|
emit this->loadingChanged();
|
||||||
|
|
||||||
this->m_failed = false;
|
this->m_failed = false;
|
||||||
emit this->activeChanged();
|
emit this->failedChanged();
|
||||||
this->m_active = false;
|
|
||||||
emit this->activeChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::play()
|
void Player::play()
|
||||||
{
|
{
|
||||||
if (!this->m_active || this->m_loading)
|
if (this->m_id.length() == 0 || this->m_loading)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -185,19 +172,10 @@ void Player::play()
|
|||||||
|
|
||||||
void Player::pause()
|
void Player::pause()
|
||||||
{
|
{
|
||||||
if (!this->m_active || this->m_loading)
|
if (this->m_id.length() == 0 || this->m_loading)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->player.pause();
|
this->player.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::stop()
|
|
||||||
{
|
|
||||||
if (!this->m_active || this->m_loading)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->player.stop();
|
|
||||||
this->unloadVideo();
|
|
||||||
}
|
|
||||||
|
|||||||
17
player.h
17
player.h
@@ -4,7 +4,6 @@
|
|||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QtQmlIntegration/qqmlintegration.h>
|
#include <QtQmlIntegration/qqmlintegration.h>
|
||||||
|
|
||||||
class Player : public QObject
|
class Player : public QObject
|
||||||
@@ -14,10 +13,7 @@ class Player : public QObject
|
|||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
|
|
||||||
Q_PROPERTY(QString title MEMBER m_title NOTIFY titleChanged FINAL)
|
Q_PROPERTY(QString title MEMBER m_title NOTIFY titleChanged FINAL)
|
||||||
Q_PROPERTY(QString description MEMBER m_description NOTIFY descriptionChanged FINAL)
|
|
||||||
Q_PROPERTY(QString id MEMBER m_id NOTIFY idChanged FINAL)
|
Q_PROPERTY(QString id MEMBER m_id NOTIFY idChanged FINAL)
|
||||||
Q_PROPERTY(bool active MEMBER m_active NOTIFY activeChanged FINAL)
|
|
||||||
Q_PROPERTY(float duration MEMBER m_duration NOTIFY durationChanged FINAL)
|
|
||||||
Q_PROPERTY(float position MEMBER m_position WRITE setPosition NOTIFY positionChanged FINAL)
|
Q_PROPERTY(float position MEMBER m_position WRITE setPosition NOTIFY positionChanged FINAL)
|
||||||
Q_PROPERTY(float buffered MEMBER m_buffered NOTIFY bufferedChanged FINAL)
|
Q_PROPERTY(float buffered MEMBER m_buffered NOTIFY bufferedChanged FINAL)
|
||||||
Q_PROPERTY(bool loading MEMBER m_loading NOTIFY loadingChanged FINAL)
|
Q_PROPERTY(bool loading MEMBER m_loading NOTIFY loadingChanged FINAL)
|
||||||
@@ -36,18 +32,14 @@ public:
|
|||||||
void setVolume(float newVolume);
|
void setVolume(float newVolume);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadVideo(QString id);
|
void loadVideo(QString id, QString extension, QString title, float position);
|
||||||
void unloadVideo();
|
void unloadVideo();
|
||||||
void play();
|
void play();
|
||||||
void pause();
|
void pause();
|
||||||
void stop();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void titleChanged();
|
void titleChanged();
|
||||||
void descriptionChanged();
|
|
||||||
void idChanged();
|
void idChanged();
|
||||||
void activeChanged();
|
|
||||||
void durationChanged();
|
|
||||||
void positionChanged();
|
void positionChanged();
|
||||||
void bufferedChanged();
|
void bufferedChanged();
|
||||||
void loadingChanged();
|
void loadingChanged();
|
||||||
@@ -58,16 +50,11 @@ signals:
|
|||||||
private:
|
private:
|
||||||
QMediaPlayer player;
|
QMediaPlayer player;
|
||||||
QAudioOutput output;
|
QAudioOutput output;
|
||||||
QNetworkAccessManager manager;
|
\
|
||||||
|
|
||||||
QString m_title = "";
|
QString m_title = "";
|
||||||
QString m_description = "";
|
|
||||||
QString m_id = "";
|
QString m_id = "";
|
||||||
float m_duration = 0;
|
|
||||||
float m_position = 0;
|
float m_position = 0;
|
||||||
float m_buffered = 0;
|
float m_buffered = 0;
|
||||||
bool m_initialLoadFinished = false;
|
|
||||||
bool m_active = false;
|
|
||||||
bool m_loading = false;
|
bool m_loading = false;
|
||||||
bool m_failed = false;
|
bool m_failed = false;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user