Compare commits
17 Commits
09041ba78e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e54c6e8b72 | ||
|
|
b9f505a64e | ||
|
|
904a96dcbb | ||
|
|
aaf3b71b7c | ||
|
|
4840619908 | ||
|
|
8bc0539032 | ||
|
|
4510449225 | ||
|
|
cb696853f5 | ||
|
|
fa5216c8d4 | ||
|
|
4e13c78c5a | ||
|
|
a023fbed87 | ||
|
|
27916b6356 | ||
|
|
bc030bb121 | ||
|
|
6b1dd40c92 | ||
|
|
d6e26e739f | ||
| d1b67d52fe | |||
|
|
7d60c306c0 |
37
.drone.star
37
.drone.star
@@ -2,8 +2,8 @@ def main(ctx):
|
|||||||
return [
|
return [
|
||||||
stepPR("amd64", "weirdradio"),
|
stepPR("amd64", "weirdradio"),
|
||||||
stepPR("arm64", "weirdradio"),
|
stepPR("arm64", "weirdradio"),
|
||||||
stepMergeMaster("amd64", "weirdradio"),
|
stepMergeMain("amd64", "weirdradio"),
|
||||||
stepMergeMaster("arm64", "weirdradio"),
|
stepMergeMain("arm64", "weirdradio"),
|
||||||
stepBuildWeekly("amd64", "weirdradio"),
|
stepBuildWeekly("amd64", "weirdradio"),
|
||||||
stepBuildWeekly("arm64", "weirdradio"),
|
stepBuildWeekly("arm64", "weirdradio"),
|
||||||
|
|
||||||
@@ -39,30 +39,19 @@ def notify(ctx):
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
"depends_on": [
|
"depends_on": [
|
||||||
"docker-build-motsognir-amd64",
|
"docker-build-weirdradio-amd64",
|
||||||
"docker-build-motsognir-arm64",
|
"docker-build-weirdradio-arm64",
|
||||||
"docker-build-webtest-amd64",
|
|
||||||
"docker-build-webtest-arm64",
|
|
||||||
"docker-build-unbound-amd64",
|
|
||||||
"docker-build-unbound-arm64",
|
|
||||||
|
|
||||||
"docker-publish-motsognir-amd64",
|
"docker-publish-weirdradio-amd64",
|
||||||
"docker-publish-motsognir-arm64",
|
"docker-publish-weirdradio-arm64",
|
||||||
"docker-publish-webtest-amd64",
|
|
||||||
"docker-publish-webtest-arm64",
|
"docker-publish-weekly-weirdradio-amd64",
|
||||||
"docker-publish-unbound-amd64",
|
"docker-publish-weekly-weirdradio-arm64",
|
||||||
"docker-publish-unbound-arm64",
|
|
||||||
|
|
||||||
"docker-publish-weekly-motsognir-amd64",
|
|
||||||
"docker-publish-weekly-motsognir-arm64",
|
|
||||||
"docker-publish-weekly-webtest-amd64",
|
|
||||||
"docker-publish-weekly-webtest-arm64",
|
|
||||||
"docker-publish-weekly-unbound-amd64",
|
|
||||||
"docker-publish-weekly-unbound-arm64",
|
|
||||||
],
|
],
|
||||||
"trigger": {
|
"trigger": {
|
||||||
"ref": [
|
"ref": [
|
||||||
"refs/heads/master",
|
"refs/heads/main",
|
||||||
"refs/heads/release*",
|
"refs/heads/release*",
|
||||||
"refs/tags/**",
|
"refs/tags/**",
|
||||||
"refs/pull/**",
|
"refs/pull/**",
|
||||||
@@ -106,7 +95,7 @@ def stepPR(arch, path):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def stepMergeMaster(arch, path):
|
def stepMergeMain(arch, path):
|
||||||
return {
|
return {
|
||||||
"kind": "pipeline",
|
"kind": "pipeline",
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
@@ -135,7 +124,7 @@ def stepMergeMaster(arch, path):
|
|||||||
],
|
],
|
||||||
"trigger": {
|
"trigger": {
|
||||||
"ref": [
|
"ref": [
|
||||||
"refs/heads/master",
|
"refs/heads/main",
|
||||||
],
|
],
|
||||||
"status": [
|
"status": [
|
||||||
"success",
|
"success",
|
||||||
@@ -173,7 +162,7 @@ def stepBuildWeekly(arch, path):
|
|||||||
],
|
],
|
||||||
"trigger": {
|
"trigger": {
|
||||||
"ref": [
|
"ref": [
|
||||||
"refs/heads/master",
|
"refs/heads/main",
|
||||||
],
|
],
|
||||||
"event": [
|
"event": [
|
||||||
"cron"
|
"cron"
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
**/*.json
|
**/*.json
|
||||||
node_modules
|
node_modules
|
||||||
.drone.yml
|
.drone.yml
|
||||||
|
assets/baseurl.js
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM node:latest
|
FROM node:latest
|
||||||
LABEL maintainer="dragonchaser <weirdradio@datenschmutz.space>"
|
LABEL maintainer="dragonchaser <weirdradio@datenschmutz.space>"
|
||||||
RUN git clone https://github.com/dragonchaser/weirdradio /weirdradio
|
RUN git clone https://git.wardrum.de/dragonchaser/weirdradio /weirdradio
|
||||||
WORKDIR /weirdradio
|
WORKDIR /weirdradio
|
||||||
RUN npm install
|
RUN npm install
|
||||||
CMD node weirdradio
|
CMD node weirdradio
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
|
|
||||||
[](https://drone.services.datenschmutz.space/dr
|
[](https://drone.services.datenschmutz.space/dragonchaser/weirdradio)
|
||||||
|
|
||||||
# Weirdradio
|
# Weirdradio
|
||||||
|
|
||||||
Weirdradio is a matrix bot that will queue youtube videos into a webfrontend for listening.
|
Weirdradio is a matrix bot that will queue youtube videos into a webfrontend for listening.
|
||||||
This can be used as party juke box (especially in combination with the whatsapp or signal bridge).
|
This can be used as party juke box (especially in combination with the whatsapp or signal bridge).
|
||||||
|
|
||||||
|
**NOTE:** The software is WIP, expect breaking changes, weird behaviour and gargoyle spitting wormholes!
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT see [LICENSE](https://github.com/dragonchaser/matrix-feeder/blob/master/LICENSE) file in this repository.
|
MIT see [LICENSE](https://github.com/dragonchaser/matrix-feeder/blob/master/LICENSE) file in this repository.
|
||||||
@@ -13,8 +14,8 @@ MIT see [LICENSE](https://github.com/dragonchaser/matrix-feeder/blob/master/LICE
|
|||||||
## Run
|
## Run
|
||||||
|
|
||||||
```
|
```
|
||||||
docker build . -t local/weirdradio:latest
|
$> docker build . -t local/weirdradio:latest
|
||||||
docker run -it \
|
$> docker run -it \
|
||||||
-p8090:8090 \
|
-p8090:8090 \
|
||||||
-p8080:8080 \
|
-p8080:8080 \
|
||||||
-v $(pwd)/config:/weirdradio/config \
|
-v $(pwd)/config:/weirdradio/config \
|
||||||
|
|||||||
@@ -2,200 +2,28 @@
|
|||||||
<head>
|
<head>
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="http://www.youtube.com/player_api"
|
src="https://www.youtube.com/player_api"
|
||||||
></script>
|
></script>
|
||||||
|
<script type="text/javascript" src="baseurl.js"></script>
|
||||||
|
<script type="text/javascript" src="logic.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
<title>Weirdradio</title>
|
<title>Weirdradio</title>
|
||||||
</head>
|
</head>
|
||||||
<style>
|
|
||||||
div.body {
|
|
||||||
width: 1024px;
|
|
||||||
height: 768px;
|
|
||||||
border: solid 1px;
|
|
||||||
padding: 1pc;
|
|
||||||
}
|
|
||||||
div.leftcolumn {
|
|
||||||
width: 30%;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
div.title {
|
|
||||||
height: 20%;
|
|
||||||
}
|
|
||||||
div.playlist {
|
|
||||||
height: 80%;
|
|
||||||
}
|
|
||||||
div.rightcolumn {
|
|
||||||
width: 60%;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
#playerframe {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
background-color: purple;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<body onload="connectSocket()">
|
<body onload="connectSocket()">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="leftcolumn">
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>Weirdradio</h1>
|
Weirdradio
|
||||||
</div>
|
</div>
|
||||||
<div id="playlist" class="playlist"></div>
|
<div class="listeners">Listeners: <span id="listeners">1</span></div>
|
||||||
</div>
|
|
||||||
<div class="rightcolumn">
|
|
||||||
<div class="playerframe">
|
<div class="playerframe">
|
||||||
<div id="player"></div>
|
<div id="player"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="playlistframe">
|
||||||
|
<div class="title">
|
||||||
|
Playlist
|
||||||
|
</div>
|
||||||
|
<div id="playlist" class="playlist"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
|
||||||
var playlist = [];
|
|
||||||
var socketConnector = null;
|
|
||||||
var socketSemaphore = false;
|
|
||||||
var tag = document.createElement("script");
|
|
||||||
var currentVideoID = null;
|
|
||||||
var player = null;
|
|
||||||
|
|
||||||
tag.src = "https://www.youtube.com/iframe_api";
|
|
||||||
var firstScriptTag = document.getElementsByTagName("script")[0];
|
|
||||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
|
||||||
|
|
||||||
// 3. This function creates an <iframe> (and YouTube player)
|
|
||||||
// after the API code downloads.
|
|
||||||
var player;
|
|
||||||
function onYouTubeIframeAPIReady() {
|
|
||||||
currentVideoID = "Wch3gJG2GJ4";
|
|
||||||
player = new YT.Player("player", {
|
|
||||||
height: "390",
|
|
||||||
width: "640",
|
|
||||||
videoId: currentVideoID,
|
|
||||||
playerVars: {
|
|
||||||
playsinline: 1,
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
onReady: onPlayerReady,
|
|
||||||
onStateChange: onPlayerStateChange,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPlayerReady(event) {
|
|
||||||
event.target.playVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
var done = false;
|
|
||||||
function onPlayerStateChange(event) {
|
|
||||||
if (event.data == 0) {
|
|
||||||
console.log("playing stopped");
|
|
||||||
removeFromPlaylist(currentVideoID);
|
|
||||||
playNext();
|
|
||||||
}
|
|
||||||
//if (event.data == YT.PlayerState.PLAYING && !done) {
|
|
||||||
// setTimeout(stopVideo, 6000);
|
|
||||||
// done = true;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
function stopVideo() {
|
|
||||||
player.stopVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
function connectSocket() {
|
|
||||||
if (socketSemaphore) {
|
|
||||||
console.log(
|
|
||||||
"Another connection attempt already in progress, canceling!"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log("Connecting to socket");
|
|
||||||
socketSemaphore = true;
|
|
||||||
baseUrl = window.location.host.replace("8080", "8090");
|
|
||||||
let socket = new WebSocket("ws://" + baseUrl);
|
|
||||||
socket.onopen = function (e) {
|
|
||||||
clearInterval(socketConnector);
|
|
||||||
socketConnector = null;
|
|
||||||
socketSemaphore = false;
|
|
||||||
console.log("[open] Connection established");
|
|
||||||
};
|
|
||||||
// TODO: on close and on error attempt reconnect
|
|
||||||
socket.onclose = function (event) {
|
|
||||||
if (event.wasClean) {
|
|
||||||
console.log(
|
|
||||||
`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// e.g. server process killed or network down
|
|
||||||
// event.code is usually 1006 in this case
|
|
||||||
// TODO: add some nice ui thingi to show reconnect
|
|
||||||
// TODO: also add some timeout function to repeat this until connect is successful, let it interact with 'onopen'
|
|
||||||
console.log("[close] Connection died, attempting reconnect");
|
|
||||||
if (!socketConnector) {
|
|
||||||
socketConnector = setInterval(connectSocket, 5000);
|
|
||||||
socketSemaphore = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
socket.onmessage = function (event) {
|
|
||||||
data = JSON.parse(event.data);
|
|
||||||
if (data["videoId"] != undefined && data["videoId"] != null) {
|
|
||||||
addToPlaylist(data);
|
|
||||||
console.log(`[message] Data received from server: ${event.data}`);
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
`[unparseable message] Data received from server ${event.data}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
socketSemaphore = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeFromPlaylist(videoId) {
|
|
||||||
tmp = [];
|
|
||||||
playlist.forEach((item) => {
|
|
||||||
if (item.videoId != videoId) {
|
|
||||||
tmp.push(item);
|
|
||||||
} else {
|
|
||||||
console.log(`removing ${videoId}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
playlist = tmp;
|
|
||||||
// remove from DOM
|
|
||||||
rm = document.getElementById(videoId);
|
|
||||||
if (rm != null) {
|
|
||||||
rm.remove();
|
|
||||||
}
|
|
||||||
currentVideoID = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function playNext() {
|
|
||||||
console.log(playlist)
|
|
||||||
console.log(playlist[0].videoId)
|
|
||||||
if (playlist[0] != null && playlist[0] != "") {
|
|
||||||
player.loadVideoById(playlist[0].videoId);
|
|
||||||
player.playVideo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addToPlaylist(data) {
|
|
||||||
if (document.getElementById(data.videoId) == null) {
|
|
||||||
playlist.push(data);
|
|
||||||
pl = document.getElementById(
|
|
||||||
"playlist"
|
|
||||||
).innerHTML += `<div id="${data.videoId}"><div>${data.title}</div><div><a target="_blank" href="${data.link}">${data.link}</a></div></div>`;
|
|
||||||
if (player.getPlayerState() == YT.PlayerState.ENDED) {
|
|
||||||
player.loadVideoById(data["videoId"]);
|
|
||||||
player.playVideo();
|
|
||||||
currentVideoID = data["videoId"];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(`item ${data.videoId} already exists in playlist skipping`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//function myDebugger() {
|
|
||||||
// console.log(socketSemaphore);
|
|
||||||
// console.log(socketConnector);
|
|
||||||
// console.log("=================");
|
|
||||||
//}
|
|
||||||
//myDebugger = setInterval(myDebugger, 2000);
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
142
assets/logic.js
Normal file
142
assets/logic.js
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
var playlist = [];
|
||||||
|
var socketConnector = null;
|
||||||
|
var socketSemaphore = false;
|
||||||
|
var tag = document.createElement("script");
|
||||||
|
var currentVideoID = null;
|
||||||
|
var player = null;
|
||||||
|
|
||||||
|
tag.src = "https://www.youtube.com/iframe_api";
|
||||||
|
var firstScriptTag = document.getElementsByTagName("script")[0];
|
||||||
|
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||||
|
|
||||||
|
// 3. This function creates an <iframe> (and YouTube player)
|
||||||
|
// after the API code downloads.
|
||||||
|
var player;
|
||||||
|
function onYouTubeIframeAPIReady() {
|
||||||
|
currentVideoID = "tbnLqRW9Ef0";
|
||||||
|
player = new YT.Player("player", {
|
||||||
|
//height: "390",
|
||||||
|
//width: "100%",
|
||||||
|
videoId: currentVideoID,
|
||||||
|
playerVars: {
|
||||||
|
playsinline: 1,
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
onReady: onPlayerReady,
|
||||||
|
onStateChange: onPlayerStateChange,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPlayerReady(event) {
|
||||||
|
event.target.playVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
var done = false;
|
||||||
|
function onPlayerStateChange(event) {
|
||||||
|
if (event.data == 0) {
|
||||||
|
playNext();
|
||||||
|
console.log("playing stopped");
|
||||||
|
}
|
||||||
|
//if (event.data == YT.PlayerState.PLAYING && !done) {
|
||||||
|
// setTimeout(stopVideo, 6000);
|
||||||
|
// done = true;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
function stopVideo() {
|
||||||
|
player.stopVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectSocket() {
|
||||||
|
if (socketSemaphore) {
|
||||||
|
console.log("Another connection attempt already in progress, canceling!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Connecting to socket");
|
||||||
|
socketSemaphore = true;
|
||||||
|
let socket = new WebSocket(wsBaseUrl);
|
||||||
|
socket.onopen = function (e) {
|
||||||
|
clearInterval(socketConnector);
|
||||||
|
socketConnector = null;
|
||||||
|
socketSemaphore = false;
|
||||||
|
console.log("[open] Connection established");
|
||||||
|
};
|
||||||
|
// TODO: on close and on error attempt reconnect
|
||||||
|
socket.onclose = function (event) {
|
||||||
|
if (event.wasClean) {
|
||||||
|
console.log(
|
||||||
|
`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// e.g. server process killed or network down
|
||||||
|
// event.code is usually 1006 in this case
|
||||||
|
// TODO: add some nice ui thingi to show reconnect
|
||||||
|
// TODO: also add some timeout function to repeat this until connect is successful, let it interact with 'onopen'
|
||||||
|
console.log("[close] Connection died, attempting reconnect");
|
||||||
|
if (!socketConnector) {
|
||||||
|
socketConnector = setInterval(connectSocket, 5000);
|
||||||
|
socketSemaphore = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
socket.onmessage = function (event) {
|
||||||
|
data = JSON.parse(event.data);
|
||||||
|
if (data["videoId"] != undefined && data["videoId"] != null) {
|
||||||
|
addToPlaylist(data);
|
||||||
|
updateListeners(data);
|
||||||
|
console.log(`[message] Data received from server: ${event.data}`);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
`[unparseable message] Data received from server ${event.data}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
socketSemaphore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateListeners(data) {
|
||||||
|
document.getElementById("listeners").innerHTML = data.listeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromPlaylist(videoId) {
|
||||||
|
delete playlist[currentVideoID];
|
||||||
|
// remove from DOM
|
||||||
|
rm = document.getElementById(videoId);
|
||||||
|
if (rm != null) {
|
||||||
|
rm.remove();
|
||||||
|
}
|
||||||
|
currentVideoID = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function playNext() {
|
||||||
|
removeFromPlaylist(currentVideoID);
|
||||||
|
if (playlist[0] != null && playlist[0] != "") {
|
||||||
|
player.loadVideoById(playlist[0].videoId);
|
||||||
|
player.playVideo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToPlaylist(data) {
|
||||||
|
if (document.getElementById(data.videoId) == null) {
|
||||||
|
playlist.push(data);
|
||||||
|
pl = document.getElementById(
|
||||||
|
"playlist"
|
||||||
|
).innerHTML += `<div class="playlistrow" id="${data.videoId}">
|
||||||
|
<div class="title">${data.title}</div>
|
||||||
|
<div class="ytlink">
|
||||||
|
<a target="_blank" href="${data.link}">${data.link}</a>
|
||||||
|
</div>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="control" onclick="removeFromPlaylist('${data.videoId}')">Remove</div>
|
||||||
|
<div class="control">Play</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
if (player.getPlayerState() == YT.PlayerState.ENDED) {
|
||||||
|
player.loadVideoById(data["videoId"]);
|
||||||
|
player.playVideo();
|
||||||
|
currentVideoID = data["videoId"];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`item ${data.videoId} already exists in playlist skipping`);
|
||||||
|
}
|
||||||
|
}
|
||||||
79
assets/style.css
Normal file
79
assets/style.css
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
div.body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
div.body > div.title {
|
||||||
|
padding: 1pc;
|
||||||
|
font-size: 2pc;
|
||||||
|
font-weight: bold;
|
||||||
|
float: left;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.body > div.listeners {
|
||||||
|
float: right;
|
||||||
|
width: 20%;
|
||||||
|
padding: 2pc 2pc 0 0;
|
||||||
|
font-size: xx-small;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlistframe {
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlistframe > div.title {
|
||||||
|
padding: 1pc;
|
||||||
|
font-size: 1.5pc;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlist {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlist > div.playlistrow {
|
||||||
|
padding: 1pc;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
div.playlist > div.playlistrow:nth-child(even) {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
div.playlist > div.playlistrow:nth-child(odd) {
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlist > div.playlistrow > div.title{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlist > div.playlistrow > div.ytlink{
|
||||||
|
font-size: xx-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlist > div.playlistrow > div.controls {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playlist > div.playlistrow > div.controls > div.control {
|
||||||
|
float: right;
|
||||||
|
background-color: #aaa;
|
||||||
|
margin: 1pc 0.5pc 0 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.playerframe {
|
||||||
|
}
|
||||||
|
|
||||||
|
#player {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"homeServerUrl": "https://matrix.your-homeserver.org",
|
"homeServerUrl": "https://matrix.your-homeserver.org",
|
||||||
"accessToken": "youraccesstokencanbeobtainedthroughriot",
|
"accessToken": "youraccesstokencanbeobtainedthroughriot",
|
||||||
|
"domain": "yourdomain.tld",
|
||||||
|
"webSocketDomain": "ws.yourdomain.tld",
|
||||||
|
"secure":true,
|
||||||
"storage": "config/bot.json",
|
"storage": "config/bot.json",
|
||||||
"assetDir": "assets/",
|
"assetDir": "assets/",
|
||||||
"webServerPort": "8080",
|
"webServerPort": "8080",
|
||||||
|
|||||||
@@ -20,14 +20,27 @@ const client = new MatrixClient(
|
|||||||
new SimpleFsStorageProvider(config.storage)
|
new SimpleFsStorageProvider(config.storage)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// write javascript for baseurl
|
||||||
|
if (config.secure) {
|
||||||
|
urlConfigData = `var baseUrl = "https://${config.domain}";\nvar wsBaseUrl = "wss://${config.webSocketDomain}";\n`;
|
||||||
|
} else {
|
||||||
|
urlConfigData = `var baseUrl = "http://${config.domain}";\nvar wsBaseUrl = "ws://${config.webSocketDomain}";\n`;
|
||||||
|
}
|
||||||
|
fs.writeFileSync(
|
||||||
|
config.assetDir + "/baseurl.js",
|
||||||
|
urlConfigData,
|
||||||
|
function (err) {
|
||||||
|
if (err) return console.log(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
// load assets
|
// load assets
|
||||||
console.log("Reading assets...")
|
console.log("Reading assets...");
|
||||||
let assets = [];
|
let assets = [];
|
||||||
var files = fs.readdirSync(config.assetDir);
|
var files = fs.readdirSync(config.assetDir);
|
||||||
files.forEach((name) => {
|
files.forEach((name) => {
|
||||||
assets[name] = fs.readFileSync("assets/" + name);
|
assets[name] = fs.readFileSync("assets/" + name);
|
||||||
});
|
});
|
||||||
console.log("[DONE]")
|
console.log("[DONE]");
|
||||||
// create server, this is for delivering the iframe page
|
// create server, this is for delivering the iframe page
|
||||||
const webServer = http
|
const webServer = http
|
||||||
.createServer((req, res) => {
|
.createServer((req, res) => {
|
||||||
@@ -36,7 +49,23 @@ const webServer = http
|
|||||||
reqFileName = "index.html";
|
reqFileName = "index.html";
|
||||||
}
|
}
|
||||||
if (assets[reqFileName] != undefined && assets[reqFileName] != null) {
|
if (assets[reqFileName] != undefined && assets[reqFileName] != null) {
|
||||||
res.writeHead(200, { "Content-Type": "text/html" });
|
extension = reqFileName.split(".").pop();
|
||||||
|
if (extension == "html" || extension == "html") {
|
||||||
|
res.writeHead(200, {
|
||||||
|
"Content-Type": "text/html",
|
||||||
|
"Access-Control-Allow-Origin": "https://" + config.webSocketDomain,
|
||||||
|
});
|
||||||
|
} else if (extension == "js") {
|
||||||
|
res.writeHead(200, {
|
||||||
|
"Content-Type": "text/javascript",
|
||||||
|
"Access-Control-Allow-Origin": "https://" + config.webSocketDomain,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.writeHead(200, {
|
||||||
|
"Content-TYpe": "text/plain",
|
||||||
|
"Access-Control-Allow-Origin": "https://" + config.webSocketDomain,
|
||||||
|
});
|
||||||
|
}
|
||||||
res.end(assets[reqFileName]);
|
res.end(assets[reqFileName]);
|
||||||
} else {
|
} else {
|
||||||
res.writeHead(404, { "Content-Type": "text/plain" });
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
||||||
@@ -85,7 +114,7 @@ client.on("room.message", (roomId, event) => {
|
|||||||
//link_matches = body.match(/https?:\/\/[^\ ]*youtu[^\ ]*/g);
|
//link_matches = body.match(/https?:\/\/[^\ ]*youtu[^\ ]*/g);
|
||||||
var r = new RegExp(/https?:\/\/[^\ ]*youtube.com\/watch\?v=([^\ ]*)/g);
|
var r = new RegExp(/https?:\/\/[^\ ]*youtube.com\/watch\?v=([^\ ]*)/g);
|
||||||
link_matches = r.exec(body);
|
link_matches = r.exec(body);
|
||||||
if (link_matches && link_matches.length > 1) {
|
if (link_matches && link_matches.length > 1 && link_matches[0] != null) {
|
||||||
// get title
|
// get title
|
||||||
request(link_matches[0], function (err, _res, body) {
|
request(link_matches[0], function (err, _res, body) {
|
||||||
if (err) return console.error(err);
|
if (err) return console.error(err);
|
||||||
@@ -100,6 +129,7 @@ client.on("room.message", (roomId, event) => {
|
|||||||
link: link_matches[0],
|
link: link_matches[0],
|
||||||
videoId: link_matches[1],
|
videoId: link_matches[1],
|
||||||
title: title,
|
title: title,
|
||||||
|
listeners: sockets.length,
|
||||||
};
|
};
|
||||||
console.log("Relaying: " + obj.link);
|
console.log("Relaying: " + obj.link);
|
||||||
sockets.forEach((s) => s.send(JSON.stringify(obj)));
|
sockets.forEach((s) => s.send(JSON.stringify(obj)));
|
||||||
|
|||||||
Reference in New Issue
Block a user