mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-17 00:59:29 -07:00
add client-side generation for playlist.json for static builds
This commit is contained in:
@@ -1,16 +1,15 @@
|
||||
FROM node:24-alpine AS node-builder
|
||||
WORKDIR /app
|
||||
|
||||
# RUN npm install gulp
|
||||
|
||||
COPY package.json .
|
||||
COPY package-lock.json .
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
RUN rm dist/playlist.json
|
||||
|
||||
FROM nginx:alpine
|
||||
# COPY --from=node-builder /app/server /usr/share/nginx/html
|
||||
COPY --from=node-builder /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
14
README.md
14
README.md
@@ -80,6 +80,13 @@ npm run buildDist
|
||||
```
|
||||
The resulting files will be in the /dist folder in the root of the project. These can then be uploaded to a web server for hosting, no server-side scripting is required.
|
||||
|
||||
When using the provided Docker image, the browser will generate `playlist.json`
|
||||
on the fly by scanning the `/music` directory served by nginx. The image
|
||||
intentionally omits this file so the page falls back to scanning the directory.
|
||||
Simply bind mount your music folder and the playlist will be created
|
||||
automatically. If no files are found in `/music`, the built in tracks located in
|
||||
`/music/default/` will be used instead.
|
||||
|
||||
## What's different
|
||||
|
||||
I've made several changes to this Weather Star 4000 simulation compared to the original hardware unit and the code that this was forked from.
|
||||
@@ -129,9 +136,12 @@ If you're looking for the original music that played during forecasts [TWCClassi
|
||||
### Customizing the music
|
||||
Placing .mp3 files in the `/server/music` folder will override the default music included in the repo. Subdirectories will not be scanned. When weatherstar loads in the browser it will load a list if available files and randomize the order when it starts playing. On each loop through the available tracks the order will again be shuffled. If you're using the static files method to host your WeatherStar music is located in `/music`.
|
||||
|
||||
If using docker, you must pass a local accessible folder to the container in the `/app/server/music` directory.
|
||||
If using docker, you can bind mount a local folder containing your music files.
|
||||
Mount the folder at `/usr/share/nginx/html/music` so the browser can read the
|
||||
directory listing and build the playlist automatically. If there are no `.mp3`
|
||||
files in `/music`, the built in tracks from `/music/default/` are used.
|
||||
```
|
||||
docker run -p 8080:8080 -v /path/to/local/music:/app/server/music ghcr.io/netbymatt/ws4kp
|
||||
docker run -p 8080:8080 -v /path/to/local/music:/usr/share/nginx/html/music ghcr.io/netbymatt/ws4kp
|
||||
```
|
||||
|
||||
### Music doesn't auto play
|
||||
|
||||
20
nginx.conf
Normal file
20
nginx.conf
Normal file
@@ -0,0 +1,20 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location / {
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
location /music/ {
|
||||
autoindex on;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { json } from './utils/fetch.mjs';
|
||||
import { json, text } from './utils/fetch.mjs';
|
||||
import Setting from './utils/setting.mjs';
|
||||
|
||||
let playlist;
|
||||
@@ -19,18 +19,38 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
getMedia();
|
||||
});
|
||||
|
||||
const scanMusicDirectory = async () => {
|
||||
const parseDirectory = async (path, prefix = "") => {
|
||||
const listing = await text(path);
|
||||
const matches = [...listing.matchAll(/href="([^\"]+\.mp3)"/gi)];
|
||||
return matches.map((m) => `${prefix}${m[1]}`);
|
||||
};
|
||||
|
||||
try {
|
||||
let files = await parseDirectory("music/");
|
||||
if (files.length === 0) {
|
||||
files = await parseDirectory("music/default/", "default/");
|
||||
}
|
||||
return { availableFiles: files };
|
||||
} catch (e) {
|
||||
console.error("Unable to scan music directory");
|
||||
console.error(e);
|
||||
return { availableFiles: [] };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const getMedia = async () => {
|
||||
try {
|
||||
// fetch the playlist
|
||||
const rawPlaylist = await json('playlist.json');
|
||||
// store the playlist
|
||||
playlist = rawPlaylist;
|
||||
// enable the media player
|
||||
enableMediaPlayer();
|
||||
} catch (e) {
|
||||
console.error("Couldn't get playlist");
|
||||
console.error(e);
|
||||
}
|
||||
try {
|
||||
// fetch the playlist
|
||||
const rawPlaylist = await json('playlist.json');
|
||||
playlist = rawPlaylist;
|
||||
} catch (e) {
|
||||
console.warn("Couldn't get playlist.json, falling back to directory scan");
|
||||
playlist = await scanMusicDirectory();
|
||||
}
|
||||
|
||||
enableMediaPlayer();
|
||||
};
|
||||
|
||||
const enableMediaPlayer = () => {
|
||||
|
||||
Reference in New Issue
Block a user