123 lines
3.7 KiB
Plaintext
123 lines
3.7 KiB
Plaintext
import QtQuick 6.8
|
|
import QtMultimedia 6.8
|
|
|
|
pragma Singleton
|
|
|
|
Item {
|
|
readonly property string streamURLPrefix: "https://youradio.nonamesoft.xyz/youradio/api/"
|
|
readonly property string metadataURL: "https://youradio.nonamesoft.xyz/youradio/api/status-json.xsl"
|
|
readonly property var slugLookup: ({
|
|
"autoradio": 0,
|
|
"live": 1,
|
|
"bassboosted": 2
|
|
})
|
|
property var streams: ([
|
|
{
|
|
name: "Autoradio",
|
|
slug: "autoradio",
|
|
title: "",
|
|
listeners: 0
|
|
},
|
|
{
|
|
name: "Live Mix",
|
|
slug: "live",
|
|
title: "",
|
|
listeners: 0
|
|
},
|
|
{
|
|
name: "Deep Bass",
|
|
slug: "bassboosted",
|
|
title: "",
|
|
listeners: 0
|
|
}
|
|
])
|
|
property var failedConnAttempts: 0
|
|
|
|
property alias playing: player.playing
|
|
property alias volume: output.volume
|
|
property var loading: player.mediaStatus == Qt.LoadingMedia
|
|
|
|
property var currentIndex: null
|
|
property var currentStream: null
|
|
|
|
function startPlaying(index) {
|
|
if ((playing && index == currentIndex) || index < 0 || index >= streams.length) {
|
|
return;
|
|
}
|
|
if (playing) {
|
|
player.stop();
|
|
}
|
|
print("Starting playing stream no. " + index);
|
|
currentIndex = index;
|
|
currentStream = streams[index];
|
|
player.source = streamURLPrefix + currentStream.slug;
|
|
player.play();
|
|
}
|
|
|
|
function stopPlaying() {
|
|
if (!playing) {
|
|
return;
|
|
}
|
|
print("Stopping playback");
|
|
currentIndex = null;
|
|
currentStream = null;
|
|
player.source = "";
|
|
player.stop()
|
|
}
|
|
|
|
MediaPlayer {
|
|
id: player
|
|
source: ""
|
|
|
|
audioOutput: AudioOutput {
|
|
id: output
|
|
volume: 0.3
|
|
}
|
|
|
|
onErrorOccurred: function(error, errorString) {
|
|
const index = currentIndex
|
|
currentIndex = null
|
|
currentIndex = index;
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
interval: 10000
|
|
repeat: true
|
|
running: true
|
|
triggeredOnStart: true
|
|
onTriggered: function() {
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState == XMLHttpRequest.DONE) {
|
|
parent.failedConnAttempts = 0;
|
|
// try {
|
|
const object = JSON.parse(xhr.responseText.toString()).icestats;
|
|
object.source.forEach(station => {
|
|
const index = parent.slugLookup[station.server_name];
|
|
if (index == null) {
|
|
console.warn("Unknown slug encountered in metadata: " + station.server_name);
|
|
return
|
|
}
|
|
parent.streams[index].title = station.title.replace(/\[[a-zA-Z0-9]{11}\]/, "");
|
|
parent.streams[index].listeners = station.listeners;
|
|
if (index == parent.currentIndex) {
|
|
parent.currentStream = parent.streams[index];
|
|
}
|
|
});
|
|
// } catch {
|
|
// console.error("Failed deserializing metadata response");
|
|
// }
|
|
}
|
|
}
|
|
xhr.open("GET", parent.metadataURL);
|
|
xhr.timeout = 10000;
|
|
xhr.ontimeout = function() {
|
|
console.log("Metadata request timed out after 10 seconds");
|
|
parent.failedConnAttempts++;
|
|
}
|
|
xhr.send();
|
|
}
|
|
}
|
|
}
|