diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72bec8dc..7301414c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,34 +1,42 @@
-## TBD (not yet released)
+## v0.8.0 (2020-07-03)
-### New:
+### [Black Lives Matter.](https://blacklivesmatter.com)
-- [ReplayGain](https://en.wikipedia.org/wiki/ReplayGain) support. No more scrambling for the volume when a new song starts! With properly tagged media, each song's loudness can now be normalized automatically.
-- Rooms can now be password-protected
-- CD+Graphics can now be resized in the player
-- Added Changelog/Sponsor viewer and GitHub links to the About panel
+### Sponsors
-### Changed:
+Massive thanks to this release's sponsors: [fulldecent](https://github.com/fulldecent), [vze22jjw](https://github.com/vze22jjw)
-- (app) Reduced motion and improved accessibility of modals
-- (app) Fixed status not respected when creating a new room
-- (player) Web Audio API support is now required (only for browsers running the player)
-- (player) Fixed media possibly not (pre)loading in Firefox
-- (player) Visualizer sensitivity can now be set up to 200%
-- (server) Added minimum password length (8) requirement and removed length limit
-- (server) Fixed incorrect queue potentially emitted after setting preferred media
-- (server) Improved filename parser and renamed config option `separator` to `delimiter`
-- (server) Improved logging and made `3 (info)` the default log file level
+If you have fun with it, consider [sponsoring](https://github.com/sponsors/bhj) as we roll down [the road to v1.0](https://github.com/bhj/karaoke-forever/issues/13).
+
+### New
+
+- **(app)** [ReplayGain support](http://www.karaoke-forever.com/docs/#preferences-admin-only). No more scrambling for the volume when a new song starts! With properly tagged media, the player can automatically minimize volume differences between songs.
+- **(app)** Rooms can now be password-protected
+- **(player)** CD+Graphics now have shadows, can be resized, and use less CPU
+- **(player)** **(breaking)** Web Audio API support is now required (only for browsers running the player)
+- **(server)** **(breaking)** Database will be migrated and no longer compatible with v0.7.x
+
+### Changed
+
+- **(app)** Reduced motion and improved accessibility of modals
+- **(app)** Fixed status not respected when creating a new room
+- **(player)** Visualizer sensitivity can now be set up to 200%
+- **(player)** Fixed media possibly not (pre)loading in Firefox
+- **(server)** Added minimum password length requirement (6) and removed limit
+- **(server)** Fixed incorrect queue potentially emitted after setting preferred media
+- **(server)** Improved filename parser and renamed config option `separator` to `delimiter`
+- **(server)** Improved logging and made `3 (info)` the default log file level
## v0.7.4 (2019-12-30)
- Initial release on [npm](https://www.npmjs.com/package/karaoke-forever)
-- (app) Improved sign in/first run form
-- (app) Added About panel with version and licenses
-- (app) General style improvements
-- (server) Improved field validation and error messages
-- (server) Songs/artists without known media are no longer removed automatically after scan
-- (server) Media in nonexistent paths are now removed after scan
-- (server) Replace dep `squel` with `sqlate`
+- **(app)** Improved sign in/first run form
+- **(app)** Added About panel with version and licenses
+- **(app)** General style improvements
+- **(server)** Improved field validation and error messages
+- **(server)** Songs/artists without known media are no longer removed automatically after scan
+- **(server)** Media in nonexistent paths are now removed after scan
+- **(server)** Replace dep `squel` with `sqlate`
## v0.7.3 (2019-09-13)
diff --git a/README.md b/README.md
index a10b2f9b..07b84e51 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,33 @@
# Karaoke Forever
-Host awesome karaoke parties where everyone can easily find and queue songs from their phone's web browser. The player is also browser-based with support for [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG) and MP4 video files. The server runs on your local network (see [Karaoke Forever Server](https://www.karaoke-forever.com/docs/#karaoke-forever-server)) with no internet connection required.
+Host awesome karaoke parties where everyone can easily find and queue songs from their phone's web browser. The player is also browser-based with support for MP3+G, MP4 video and WebGL visualizations. The server runs locally, no internet connection required.
-Karaoke Forever basically has 3 parts:
-
-- **[Server:](https://www.karaoke-forever.com/docs/#karaoke-forever-server)** Runs on Mac/Windows/Linux/etc. to serve the app and media files on your local network.
-
-- **[Mobile browser app:](https://www.karaoke-forever.com/docs/#karaoke-forever)** Everyone can quickly join and queue songs without having to install anything.
-
-- **[Player:](https://www.karaoke-forever.com/docs/#player-admin-only)** Just another part of the browser app, but designed to run in fullscreen mode on the system handling audio and video for a [room](https://www.karaoke-forever.com/docs/#rooms-admin-only).
-
-[![Karaoke Forever Demo Video](https://www.karaoke-forever.com/static/karaoke-forever-demo1-540p.jpg)](https://www.karaoke-forever.com/static/karaoke-forever-demo1-540p.mp4)
+[![Karaoke Forever](/docs/assets/images/README.jpg?raw=true)](/docs/assets/images/README.jpg?raw=true)
- App running in Mobile Safari (left) and Firefox/Chrome/Edge (right)
- Watch demo video in
- 540p |
- 720p |
- 1080p
+ App in mobile browser (top) controlling player in Firefox/Chrome (bottom)
+Karaoke Forever basically has 3 parts:
+
+- **[Server:](https://www.karaoke-forever.com/docs/#karaoke-forever-server)** Runs on almost any OS to serve the app and your media files
+- **[App:](https://www.karaoke-forever.com/docs/#karaoke-forever-the-web-app)** Fast, modern browser app designed for "karaoke conditions"
+- **[Player:](https://www.karaoke-forever.com/docs/#player)** Just another part of the app, designed to run fullscreen on the system handling audio/video for a [room](https://www.karaoke-forever.com/docs/#rooms-admin-only)
+
## Features
-- Modern browser-based app and player with dark UI designed for "karaoke conditions"
-- [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG) and MP4 video file support
-- Milkdrop visualizations via [Butterchurn](https://github.com/jberg/butterchurn) (requires [WebGL 2](https://caniuse.com/#feat=webgl2))
-- Prioritizes singers based on the amount of time since each last sang
-- Multiple simultaneous rooms/queues/players
+- [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG) and MP4 video support
+- [MilkDrop](https://en.wikipedia.org/wiki/MilkDrop)-style visualizations via [Butterchurn](https://github.com/jberg/butterchurn) (requires WebGL 2)
+- [ReplayGain](https://en.wikipedia.org/wiki/ReplayGain) volume normalization support
+- Singers prioritized by time since each last sang
+- Multiple simultaneous rooms/queues (optionally password-protected)
- No telemetry; all data stored locally
-Karaoke Forever assumes its player will be mixed with any microphones (either in software or an outboard mixer). See the [F.A.Q.](https://www.karaoke-forever.com/faq/#whats-the-recommended-microphone-audio-setup) for more information.
+Karaoke Forever assumes its player will be mixed with any microphones (either in software or an outboard mixer). See the [F.A.Q.](https://www.karaoke-forever.com/faq#whats-the-recommended-audio-setup) for more information.
-## Documentation
+## Getting Started
-Please see [Quick Start](https://www.karaoke-forever.com/docs#quick-start) to get started, or jump to the documentation for [Karaoke Forever](https://www.karaoke-forever.com/docs/#karaoke-forever) (the "web" app) or [Karaoke Forever Server](https://www.karaoke-forever.com/docs/#karaoke-forever-server).
+The [Karaoke Forever website](https://www.karaoke-forever.com/) has a [Quick Start ](https://www.karaoke-forever.com/docs/#quick-start) section as well as the documentation for [Karaoke Forever](https://www.karaoke-forever.com/docs/#karaoke-forever-the-web-app) (the "web" app) and [Karaoke Forever Server](https://www.karaoke-forever.com/docs/#karaoke-forever-server).
## Discord / Support
@@ -41,7 +35,7 @@ Join the [Karaoke Forever Discord Server](https://discord.gg/PgqVtFq) for genera
## Contributing & Development
-Contributions are most welcome! Make sure you have [Node.js 12](https://nodejs.org/en/), then:
+Contributions are most welcome! Make sure you have [Node.js](https://nodejs.org/en/) 12 or later, then:
1. Fork and clone the repo
2. `npm i`
diff --git a/docs/assets/css/poole.scss b/docs/assets/css/poole.scss
index 97221d68..0407fe92 100755
--- a/docs/assets/css/poole.scss
+++ b/docs/assets/css/poole.scss
@@ -80,28 +80,28 @@ a:focus {
}
/* Headings */
-h1, h2, h3, h4, h5, h6 {
- margin-bottom: .5rem;
- font-weight: bold;
- line-height: 1.25;
- color: #313131;
- text-rendering: optimizeLegibility;
-}
-h1 {
- font-size: 2rem;
-}
-h2 {
- margin-top: 1rem;
- font-size: 1.5rem;
-}
-h3 {
- margin-top: 1.5rem;
- font-size: 1.25rem;
-}
-h4, h5, h6 {
- margin-top: 1rem;
- font-size: 1rem;
-}
+// h1, h2, h3, h4, h5, h6 {
+// margin-bottom: .5rem;
+// font-weight: bold;
+// line-height: 1.25;
+// color: #313131;
+// text-rendering: optimizeLegibility;
+// }
+// h1 {
+// font-size: 2rem;
+// }
+// h2 {
+// margin-top: 1rem;
+// font-size: 1.5rem;
+// }
+// h3 {
+// margin-top: 1.5rem;
+// font-size: 1.25rem;
+// }
+// h4, h5, h6 {
+// margin-top: 1rem;
+// font-size: 1rem;
+// }
/* Body text */
p {
diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss
index 99c94a38..352dd673 100644
--- a/docs/assets/css/style.scss
+++ b/docs/assets/css/style.scss
@@ -1,39 +1,24 @@
@import "variables.scss";
@import "poole.scss";
+html {
+ font: 16px/1.5 sans-serif;
+ font-size: unquote("min(max(calc(.5rem + 1vw), 16px), 22px)"); // min=16, max=22, fluid between
+}
+
body {
background-color: #000;
color: hsl(var(--hue-blue), 10%, 70%);
- font: 16px/1.5 sans-serif;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Raleway', sans-serif;
- margin-top: 2rem;
- margin-bottom: 1rem;
-}
-
-h1 {
- font-size: 36px;
- color: hsl(var(--hue-blue), 10%, 75%);
- border-bottom: 1px solid hsl(var(--hue-blue), 10%, 65%);
- margin-top: .5rem;
}
-h2 { font-size: 32px; color: hsl(var(--hue-blue), 10%, 70%); }
-h3 { font-size: 24px; color: hsl(var(--hue-blue), 10%, 60%); }
-h4 { font-size: 18px; color: hsl(var(--hue-blue), 10%, 50%); }
-
-@media (min-width: 42em) {
- html {
- font-size: inherit;
- }
-
- h1, h2, h3 {
- margin-top: 2.5rem;
- margin-bottom: 1.5rem;
- }
-}
+h1 { color: hsl(var(--hue-blue), 10%, 80%); border-bottom: 1px solid hsl(var(--hue-blue), 10%, 65%); font-weight: 200; }
+h2 { color: hsl(var(--hue-blue), 10%, 70%); font-size: 1.8rem; font-weight: 200; }
+h3 { color: hsl(var(--hue-blue), 10%, 60%); font-size: 1.4rem; }
+h4 { color: hsl(var(--hue-blue), 10%, 50%); font-size: 1.2rem; margin-bottom: 1rem}
strong {
color: inherit;
@@ -81,22 +66,39 @@ hr { border-color: #777; }
text-decoration: underline;
}
+/*
+ * Container
+ */
+.content {
+ padding-top: 1rem;
+ padding-bottom: 4rem;
+}
+
+@media (min-width: 50rem) {
+ .content {
+ padding-top: 6rem;
+ max-width: 80rem;
+ margin-left: 20rem;
+ margin-right: 0;
+ }
+}
+
/*
* Sidebar
*/
-@media (min-width: 42em) {
+@media (min-width: 50rem) {
.sidebar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
- padding-top: 4rem;
- width: 24rem;
+ padding-top: 3rem;
+ width: 20rem;
overflow-y: scroll;
nav {
display: block;
- margin: 2em;
+ margin: 1.5rem;
}
}
@@ -115,7 +117,7 @@ header {
#btn-nav {
box-sizing: content-box;
fill: var(--btn-bg-color);
- padding: .5em 1em 0 0;
+ padding: 1.5rem 1rem 0 0;
cursor: pointer;
}
@@ -172,9 +174,9 @@ a.nav-item:focus {
*/
.logo {
font-family: 'Raleway', sans-serif;
- font-size: 18px;
+ font-size: 2rem;
white-space: nowrap;
- padding-top: .5em;
+ padding-top: .5rem;
flex: 1;
}
@@ -184,19 +186,20 @@ a.nav-item:focus {
.logo img {
margin: 0;
- width: 2em;
+ width: 3rem;
position: relative;
display: inline-block;
- right: -1em;
+ top: -.25rem;
+ right: -1.5rem;
}
.logo h1 {
- color: hsl(var(--hue-blue), 10%, 80%);
border: none;
- font-weight: 200;
+ color: var(--logo-color);
display: inline-block;
- font-size: 100%;
- margin: 0;
+ font-weight: 200;
+ font-size: 2rem;
+ margin-bottom: 0;
text-shadow: var(--text-shadow-glow);
}
@@ -204,45 +207,30 @@ a.nav-item:focus {
text-align: center;
display: none;
font-weight: 200;
- text-shadow: none;
+ text-shadow: var(--text-shadow-glow);
}
.nospace {
font-size: 0;
}
-@media (min-width: 42em) {
+@media (min-width: 50rem) {
.logo {
font-size: 36px;
}
.logo img {
- width: 50px;
- height: 50px;
top: -32px;
right: -26px;
}
- .logo .description {
- display: block;
- font-size: 16px;
+ .logo h1 {
+ margin-bottom: 1rem;
}
-}
-/*
- * Container
- */
-.content {
- padding-top: 1rem;
- padding-bottom: 4rem;
-}
-
-@media (min-width: 42em) {
- .content {
- padding-top: 8rem;
- max-width: 80rem;
- margin-left: 23rem;
- margin-right: 0;
+ .logo .description {
+ display: block;
+ font-size: 1rem;
}
}
@@ -281,19 +269,6 @@ aside.warn {
.icon { fill: var(--warn-color); }
}
-/*
- * Screenshot layout
- */
-.row {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-around;
-}
-
-.row figure {
- flex-shrink: 0;
-}
-
/*
* Icons
*/
@@ -305,21 +280,87 @@ aside.warn {
.icon.external { fill: var(--info-color); }
/*
- * Screenshots/Videos
+ * Screenshots
*/
-figure {
- margin: 1.5em 0;
+ul.screenshots {
+ display: flex;
+ flex-wrap: wrap;
+ list-style: none;
+ padding: 0;
+
+ li {
+ height: 20vh;
+ flex-grow: 1;
+ }
+
+ img {
+ max-height: 100%;
+ min-width: 100%;
+ object-fit: cover;
+ vertical-align: bottom;
+ padding: .5rem;
+ }
+
+ ::after {
+ content:"";
+ flex-grow: 10;
+ }
+}
+
+.row {
+ display: flex;
+ justify-content: space-around;
+ img {
+ max-height: 50vh;
+ margin: 0 auto;
+ }
+}
+
+figure {
figcaption {
+ color: hsl(var(--hue-blue), 20%, 50%);
text-align: center;
font-style: italic;
+ font-weight: bold;
+ margin-top: .5rem;
}
+}
- video {
- max-width: 100%;
- min-width: 100%;
- height: auto !important;
- border: 1px solid #333;
- outline: none;
- }
+/*
+ * :target image overlay
+ */
+.overlay {
+ position: fixed;
+ z-index: 99;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0,0,0,0.9);
+ display: flex;
+ align-items: center;
+ text-align: center;
+ visibility: hidden;
+ opacity: 0;
+ transition: opacity .167s;
+}
+
+.overlay img {
+ max-width: 90% !important;
+ max-height: 90% !important;
+ margin: auto;
+ width: auto;
+ height: auto;
+}
+
+.overlay:target {
+ visibility: visible;
+ outline: none;
+ opacity: 1;
+}
+
+.overlay:target img {
+ width: 100%;
+ object-fit: contain;
}
diff --git a/docs/assets/css/variables.scss b/docs/assets/css/variables.scss
index 0df1b1fc..1e224dbb 100644
--- a/docs/assets/css/variables.scss
+++ b/docs/assets/css/variables.scss
@@ -1,9 +1,9 @@
:root {
--hue-blue: 209;
- --hue-pink: 290;
+ --hue-pink: 270;
--bg-color: #000;
- --text-color: #ddd;
+ --text-color: #hsl(var(--hue-blue), 10%, 87%);
--link-color: hsl(var(--hue-blue), 92%, 70%);
--text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
--box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
@@ -15,6 +15,7 @@
--info-bg-color: hsl(var(--hue-blue), 100%, 12%);
--warn-color: hsl(var(--hue-pink), 100%, 50%);
--warn-bg-color: hsl(var(--hue-pink), 50%, 20%);
+ --logo-color: hsl(var(--hue-blue), 10%, 85%);
--text-shadow-glow: 0 0 5px hsl(var(--hue-pink), 100%, 45%), 0 0 10px hsl(var(--hue-pink), 100%, 45%);
}
diff --git a/docs/assets/images/README.jpg b/docs/assets/images/README.jpg
new file mode 100644
index 00000000..22e0fbbd
Binary files /dev/null and b/docs/assets/images/README.jpg differ
diff --git a/docs/assets/images/logo_mic.png b/docs/assets/images/logo_mic.png
index 62e40b5f..b8f016b8 100644
Binary files a/docs/assets/images/logo_mic.png and b/docs/assets/images/logo_mic.png differ
diff --git a/docs/config.yaml b/docs/config.yaml
index 30c65e8f..25634959 100644
--- a/docs/config.yaml
+++ b/docs/config.yaml
@@ -3,4 +3,8 @@ languageCode: en-us
title: Karaoke Forever
permalinks:
page: "/:slug/"
-pygmentsStyle: solarized-dark
+pygmentsStyle: solarized-dark256
+markup:
+ goldmark:
+ renderer:
+ unsafe: true
diff --git a/docs/content/_index.md b/docs/content/_index.md
index 73d84bad..1a70dad3 100644
--- a/docs/content/_index.md
+++ b/docs/content/_index.md
@@ -2,36 +2,31 @@
title: Overview
---
-Host awesome karaoke parties where everyone can easily find and queue songs from their phone's web browser. The player is also browser-based with support for [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG) and MP4 video files. The server runs on your local network (see Karaoke Forever Server) with no internet connection required.
+Host awesome karaoke parties where everyone can easily find and queue songs from their phone's web browser. The player is also browser-based with support for MP3+G, MP4 video and WebGL visualizations. The server runs locally, no internet connection required.
-Karaoke Forever basically has 3 parts:
-
-- **Server:** Runs on Mac/Windows/Linux/etc. to serve the app and media files on your local network.
+{{< screenshots >}}
-- **Mobile browser app:** Everyone can join in without having to install anything on their phones.
-
-- **Player:** Just another part of the browser app, but designed to run in fullscreen mode on the system handling audio and video for a [room](https://www.karaoke-forever.com/docs/#rooms-admin-only).
+Karaoke Forever basically has 3 parts:
-
-
- App running in Mobile Safari (left) and Firefox/Chrome/Edge (right)
-
+- **Server:** Runs on almost any OS to serve the app and your media files
+- **App:** Fast, modern browser app designed for "karaoke conditions"
+- **Player:** Just another part of the app, designed to run fullscreen on the system handling audio/video for a room
## Features
-- Modern browser-based app and player with dark UI designed for "karaoke conditions"
-- [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG) and MP4 video file support
-- Milkdrop visualizations via [Butterchurn](https://github.com/jberg/butterchurn) (requires [WebGL 2](https://caniuse.com/#feat=webgl2))
-- Prioritizes singers based on the amount of time since each last sang
-- Multiple simultaneous rooms/queues/players
+- [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG){{% icon-external %}} and MP4 video support
+- [MilkDrop](https://en.wikipedia.org/wiki/MilkDrop){{% icon-external %}}-style visualizations via [Butterchurn](https://github.com/jberg/butterchurn){{% icon-external %}} (requires WebGL 2)
+- [ReplayGain](https://en.wikipedia.org/wiki/ReplayGain){{% icon-external %}} volume normalization support
+- Singers prioritized by time since each last sang
+- Multiple simultaneous rooms/queues (optionally password-protected)
- No telemetry; all data stored locally
-Karaoke Forever assumes its player will be mixed with any microphones (either in software or an outboard mixer). See the F.A.Q. for more information.
+Karaoke Forever assumes its player will be mixed with any microphones (either in software or an outboard mixer). See the F.A.Q. for more information.
## Download
-The Releases page has the latest packaged versions of Karaoke Forever Server for macOS and Windows.
+If you'll be running the server on macOS or Windows, you probably want Releases{{% icon-external %}}. On any OS with [Node.js](https://nodejs.org){{% icon-external %}}, see Installation.
## Documentation
@@ -39,8 +34,8 @@ Please see Quick Start to
## Discord / Support
-Join the [Karaoke Forever Discord Server](https://discord.gg/PgqVtFq) for general support and development chat, or just to say hi!
+Join the [Karaoke Forever Discord Server](https://discord.gg/PgqVtFq){{% icon-external %}} for general support and development chat, or just to say hi!
## Contributing & Development
-See the GitHub project page.
+See the GitHub project page{{% icon-external %}}.
diff --git a/docs/content/docs/app-account.png b/docs/content/docs/app-account.png
new file mode 100644
index 00000000..8d3e8267
Binary files /dev/null and b/docs/content/docs/app-account.png differ
diff --git a/docs/content/docs/app-displayctrl.png b/docs/content/docs/app-displayctrl.png
new file mode 100644
index 00000000..d77fb9d6
Binary files /dev/null and b/docs/content/docs/app-displayctrl.png differ
diff --git a/docs/content/docs/app-library.png b/docs/content/docs/app-library.png
new file mode 100644
index 00000000..7635aeaf
Binary files /dev/null and b/docs/content/docs/app-library.png differ
diff --git a/docs/content/docs/app-library2.png b/docs/content/docs/app-library2.png
new file mode 100644
index 00000000..32ba8d5b
Binary files /dev/null and b/docs/content/docs/app-library2.png differ
diff --git a/docs/content/docs/app-player.jpg b/docs/content/docs/app-player.jpg
new file mode 100644
index 00000000..8d0d380b
Binary files /dev/null and b/docs/content/docs/app-player.jpg differ
diff --git a/docs/content/docs/app-queue.png b/docs/content/docs/app-queue.png
new file mode 100644
index 00000000..b4fe929a
Binary files /dev/null and b/docs/content/docs/app-queue.png differ
diff --git a/docs/content/docs/index.md b/docs/content/docs/index.md
index 8750e400..04b9d741 100644
--- a/docs/content/docs/index.md
+++ b/docs/content/docs/index.md
@@ -1,159 +1,192 @@
---
title: Documentation
+resources:
+- src: 'app-library.png'
+ params:
+ galleryOrder: 1
+- src: 'app-queue.png'
+ params:
+ galleryOrder: 2
+- src: 'app-account.png'
+ params:
+ galleryOrder: 3
+- src: 'app-displayctrl.png'
+ params:
+ galleryOrder: 4
+- src: 'app-player.jpg'
+ params:
+ galleryOrder: 5
---
## Quick Start
1. Install [Karaoke Forever Server](#karaoke-forever-server) on the system that will serve the app and media on your local network.
-2. Browse to the server URL. You can copy or open the URL in your default browser using the Karaoke Forever Server menu bar or tray icon (macOS or Windows only).
+2. Browse to the [app](#karaoke-forever-the-web-app) at the **server URL**. You can copy or open the URL in your default browser using the Karaoke Forever Server menu bar or tray icon in macOS or Windows, respectively.
-
-
-3. Create your admin account at the welcome page.
+
-4. In the Preferences panel, tap Media Folders and add your [supported media files](#supported-media).
+3. Create your **admin** account at the welcome page.
-5. When the media scan is finished, the new songs will appear in the [library](#library) view. Queue a few songs by tapping an artist's name, then tapping a song title.
+4. In the Preferences panel, tap Media Folders and add your [supported media](#media-files).
-6. If you are not on the system that will be running the [player](#player-admin-only) go there now, browse to the server URL and sign in with your admin account.
+5. Once the media scanner finishes, head to the [library](#library) and add some songs by tapping an artist, then tapping a song title. A glowing song means it's upcoming in the queue.
-7. You should see a notice at the top that no players are present, so tap the Start Player link. (If you don't see a notice, your current browser doesn't support fullscreen mode)
+6. Now we just need a [player](#player). On the system that will output the room's audio/video, browse to the **server URL**, sign in with your admin account, and tap the **Start Player** link at the top. If you don't see a link, your current browser doesn't support fullscreen mode, but you can still navigate to `/player`.
-8. Click Play in the playback controls that appear at the top. The current singer will temporarily have access to these while it's their turn. Admins always have access to the playback controls.
+7. Playback and display controls will appear on all your devices now that there's a player in the room. The current singer sees these during their turn; admins always see these.
-You are now ready to party!
+Congratulations, you are now ready to press play and party!
## Karaoke Forever (the "web" app)
-Karaoke Forever is a modern mobile browser app that lets everyone join in without having to install anything on their phones. It's built for small screens and touch, but a mouse is supported in desktop browsers (click and drag to emulate a swipe gesture).
+Karaoke Forever is a modern mobile browser app that lets everyone join quickly, without having to install anything on their phones. It's built for touch, but a mouse is supported in desktop browsers (click and drag to emulate swipe gestures).
### Library
-The library view lists available songs organized by artist. The search/filter area at the top allows searching by artist name and song title, and/or showing only favorited songs.
+The library view lists available songs organized by artist. The search area at the top allows filtering by artist name, song title and/or your starred songs:
-Tap an artist to reveal their songs, then tap the song title to add it to the queue, or tap its star to favorite it.
+
+
+Tap to expand an artist, then tap a song's title to queue it. You can also tap its star to save it for later. A glowing song indicates that it's upcoming in the queue. Artists will also glow to show that they contain queued or starred songs.
-Admins can reveal additional options for each song, such as Get Info, by swiping left on the song. As an admin you may see songs with an italicized number at the end, like *(2)*. That means there are two versions (media files) of the same song. The version in the folder highest in the [Media Folders](#preferences-admin-only) list will be queued unless another version of the song has been set as preferred.
+If there are multiple versions (media files) of a song, admins will see an italicized number in parentheses after the title, and the version in the folder highest in the [Media Folders](#preferences-admin-only) list will be used by default. Admins can also reveal additional options for a song, such as Get Info, by swiping left on it.
### Queue
-The queue view shows the current, upcoming and previously played songs.
+The queue view shows your room's previous, current and upcoming songs:
-Karaoke Forever tries to distribute singers as fairly as possible by prioritizing the queue based on the amount of time since each user last sang. This also means users joining later in the session won't be stuck at the back of a long queue.
+
+
+Singers are prioritized by time since each last sang, so those joining later in the session aren't penalized and will get right to the front of the queue.
-To remove an upcoming song, swipe left and tap the remove button. Non-admin users can only remove their own songs. Admins also see additional options when swiping left.
+To remove an upcoming song, swipe left and tap X. Normal users can only remove their own songs, but admins can remove anyone's upcoming song. Admins will also see additional options when swiping left, such as Get Info.
### Account
-The account view lets users manage their account; admins will see additional panels.
+The account view lets users manage their account, while admins will see additional panels:
+
+
#### Rooms (admin only)
The Rooms panel allows admins to create, edit or remove rooms.
-Karaoke Forever uses "rooms" to organize sessions by time and space (spacetime?) Each room gets its own song queue and player, and can have one of the following statuses:
+Karaoke Forever uses "rooms" to organize sessions by time and space (spacetime?) Users choose an open room when signing in, and each room has its own queue.
+
+Rooms can have one of the following statuses:
- - `open` The room can be entered and have songs queued. Users choose an open room when signing in.
- - `closed` The room can no longer be entered and no more songs can be queued, but current occupants are not kicked out and can play through the queue.
+ - `open` Can be signed in to and have songs queued.
+ - `closed` Can no longer be signed in to or have more songs queued. When closing, current occupants are unaffected and can continue playing through the existing queue.
It's best to create a new room before each session so that you start with an empty queue, then set the room to `closed` when finished.
#### Preferences (admin only)
-The Preferences panel allows admins to configure [Karaoke Forever Server](#karaoke-forever-server).
+The Preferences panel allows admins to set these global preferences:
-- **Media Folders:** Add folders with [supported media files](#supported-media) to scan them into the library. When multiple folders contain a version of the same song, the version in the folder highest in the list will be used. Karaoke Forever Server does not automatically detect changes to media folders; click Refresh to re-scan.
+- **Media Folders**
+ - Add folders with [supported media files](#media-files) to scan them into the library. When multiple folders contain a version of the same song, the version in the folder highest in this list will be used. Karaoke Forever Server does not automatically look for changes to media folders; tap Refresh to re-scan.
+- **Player**
+ - **ReplayGain (clip-safe)**: [ReplayGain](https://en.wikipedia.org/wiki/ReplayGain){{% icon-external %}} metadata tags allow the player to automatically minimize volume differences between songs, resulting in a better experience for all, and without affecting the dynamic range of each song (no compression). This option should generally only be enabled when you know all of your media is properly tagged. It normally reduces the player's overall volume significantly, so just turn your output up, and/or your mics down.
#### My Account
-This panel lets users change their name, username or password and sign out.
+The My Account panel allows users to change their username, password, display name or picture as well as sign out.
-### Player (admin only)
+### Player
-The player view is designed to run fullscreen in the browser on the system handling audio/video for a [room](#rooms-admin-only). The latest versions of these browsers are currently supported:
+The player is a part of the [app](#karaoke-forever-the-web-app) that's designed to run fullscreen on the system handling audio/video for a [room](#rooms-admin-only). The latest versions of these browsers are officially supported:
- Firefox
- - Chrome/Chromium/Edge
+ - Chromium/Chrome/Edge
-To start a player, sign in as an admin to the desired room and a notice will appear with a link to start the player. If you don't see a notice, your browser doesn't support fullscreen mode or there is already another player detected in the room (you can still manually navigate to `/player`).
+
+
+To start a player, sign in to the desired room as an admin and a player link will appear at the top. If you don't see a link, fullscreen support wasn't detected, but you can still manually navigate to `/player`.
+
+MP4 videos will be played verbatim, while media with CD+Graphics have additional display options, including [MilkDrop](https://en.wikipedia.org/wiki/MilkDrop){{% icon-external %}}-style visualizations. As with the playback controls, admins and the currently-up singer have access to these options.
## Karaoke Forever Server
-The server software hosts the "web" app and your media files on your local network (it is not designed to be run as a service exposed to the Internet). Built on [Node.js](https://nodejs.org) and [SQLite](https://www.sqlite.org), it can run on relatively minimal hardware (Raspberry Pi 3B+).
+The server software hosts the "web" app and your media files on your local network. Built on [Node.js](https://nodejs.org){{% icon-external %}} and [SQLite](https://www.sqlite.org){{% icon-external %}}, it can run on relatively minimal hardware (Raspberry Pi 3B+).
### Installation
#### macOS or Windows
-Download and install the latest release. Karaoke Forever Server runs in the menu bar or tray:
+Download{{% icon-external %}} and install the latest release. Karaoke Forever Server runs in the menu bar or tray:
- {{< figure src="kfs_mac.png" alt="Karaoke Forever Server (macOS)" caption="macOS" >}}
- {{< figure src="kfs_win.png" alt="Karaoke Forever Server (Windows)" caption="Windows" >}}
+ {{< img src="server-macos.png" alt="Karaoke Forever Server (macOS)" caption="macOS" >}}
+ {{< img src="server-windows.png" alt="Karaoke Forever Server (Windows)" caption="Windows" >}}
-#### Any OS with Node.js 12+
+#### Any OS with Node.js
-- Install via ```npm```
+Karaoke Forever Server requires [Node.js](https://nodejs.org){{% icon-external %}} 12 or later.
+
+1. Install via ```npm```
{{< highlight shell >}}
$ npm i -g karaoke-forever
{{< /highlight >}}
-- Start the server
+
+
+2. Start the server
{{< highlight shell >}}
$ karaoke-forever-server
{{< /highlight >}}
-- Watch the output for "Web server running at..." and browse to the server URL
-
-
+3. Watch the output for "Web server running at..." and browse to the **server URL**
-### Supported Media
+### Media Files
-- [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG) (the .cdg and .mp3 files must have the same name; Karaoke Forever will also look for an .m4a audio file and use it instead if present)
+The following media formats are supported:
-- MP4 (since mp4/m4a files are only containers, codec support can vary depending on the browser running the [player](#player-admin-only))
+- [MP3+G](https://en.wikipedia.org/wiki/MP3%2BG){{% icon-external %}} (.cdg and .mp3 files must be named the same; if .m4a is present it will be used instead)
-Karaoke Forever expects media filenames to be in the format "Artist - Title" (see [MetaParser](#metaparser) for more info). Media files that couldn't be parsed are [logged to a file](#file-locations) (to change the level of logging, see [Command Line Options](#command-line-options)).
+- MP4 video (since .mp4/.m4a files are only containers, codec support can vary depending on the browser running the [player](#player))
-### MetaParser
+Media filenames are expected to be in "Artist - Title" format by default, but this can be configured per-folder using a `_kfconfig.js` file. When this file is encountered in a folder it applies to all files and subfolders. If any subfolders have their own `_kfconfig.js`, that will take precedence.
-When determining the artist name and song title for each media file, the filenames are assumed to be in the format "Artist - Title". This can be configured per-folder using a `_kfconfig.js` file. When a `_kfconfig.js` file is encountered in a folder it applies to all files and subfolders within. If any subfolders have their own `_kfconfig.js` files those will take precedence.
+Media with filenames that couldn't be parsed are [logged to a file](#file-locations) (to change the level of logging, see [Command Line Options](#command-line-options)) and won't appear in the library view.
-#### Configuring the Parser
+#### Configuring the Metadata Parser
-You can configure the default parser by returning an object with the options you want to override. For example, if a folder has filenames in the format "Title - Artist" instead, you could add this `_kfconfig.js` file:
+You can configure the default metadata parser by returning an object with the options you want to override. For example, if a folder has filenames in the format "Title - Artist" instead, you could add this `_kfconfig.js` file:
{{< highlight js >}}
return {
@@ -162,9 +195,7 @@ return {
{{< /highlight >}}
@@ -172,15 +203,15 @@ The default configuration is:
{{< highlight js >}}
return {
- articles: ['A', 'An', 'The'], // false will disable article normalization
+ articles: ['A', 'An', 'The'], // false disables article normalization
artistOnLeft: true,
- delimiter: '-',
+ delimiter: '-', // can also be a RegExp
}
{{< /highlight >}}
-#### Creating a Parser (Experimental)
+#### Creating a Metadata Parser (Experimental)
-Your `_kfconfig.js` can also return a *parser creator* instead of a configuration object. A parser creator returns a function (parser) that can be called for each media file. The [default parser](/repo/blob/master/server/Scanner/MetaParser/defaultMiddleware.js) is still available so you don't have to reinvent the wheel.
+Your `_kfconfig.js` can also return a *parser creator* instead of a configuration object. A parser creator returns a function (parser) that can be called for each media file. The [default parser](/repo/blob/master/server/Scanner/MetaParser/defaultMiddleware.js){{% icon-external %}} is still available so you don't have to reinvent the wheel.
The following example creates a parser that removes the word 'junk' from each filename before handing off to the default parser:
@@ -193,7 +224,7 @@ return ({ compose, getDefaultParser, defaultMiddleware }) => {
return compose(
customMiddleware, // our custom pre-processing
- getDefaultParser(), // then the default parser (optionally accepts a configuration object)
+ getDefaultParser(), // everything else (optionally accepts a configuration object)
)
}
{{< /highlight >}}
@@ -201,15 +232,15 @@ return ({ compose, getDefaultParser, defaultMiddleware }) => {
Your parser creator is passed an object with the following properties:
- `compose` (function) accepts functions (or arrays of functions) as arguments and returns a single composed function that can be used as a parser
-- `getDefaultParser` (function) gets an instance of the default parser, which itself can be used as middleware. Note that the method must be called because you can optionally pass a [configuration object](#configuring-the-parser) when getting an instance
-- `defaultMiddleware` [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) containing the [default middleware](/repo/blob/master/server/Scanner/MetaParser/defaultMiddleware.js) in order. This can be used to recompose the middleware in your custom parser
+- `getDefaultParser` (function) gets an instance of the default parser, which itself can be used as middleware. Note that the method must be called because you can optionally pass a [configuration object](#configuring-the-metadata-parser) when getting an instance
+- `defaultMiddleware` [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map){{% icon-external %}} containing the [default middleware](/repo/blob/master/server/Scanner/MetaParser/defaultMiddleware.js){{% icon-external %}} in order. This can be used to recompose the middleware in your custom parser
When a media file is scanned, the parser is called with a context object `ctx` having the following properties:
- `dir` (string) full path of the containing folder
- `dirSep` (string) path segment separator used by the current OS (`/` or `\`)
- `name` (string) media filename (without extension)
-- `tags` (object) media file's [tags/metadata fields](https://github.com/Borewit/music-metadata/blob/master/doc/common_metadata.md)
+- `tags` (object) media file's [tags/metadata fields](https://github.com/Borewit/music-metadata/blob/master/doc/common_metadata.md){{% icon-external %}}
Middleware may mutate `ctx` as required. Once finished, the following properties on it will be used:
@@ -221,9 +252,7 @@ Middleware may mutate `ctx` as required. Once finished, the following properties
It's important that each middleware calls `next` unless you don't want the chain to continue (for instance, if you've set `artist` and `title` manually and want to use them as-is).
@@ -255,8 +284,8 @@ Karaoke Forever Server supports the following command line options:
## Acknowledgements
-- [David Zukowski](https://zuko.me): react-redux-starter-kit, which this project began as a fork of (all contributors up until it was detached to its own project are listed on the Contributors page)
-- [Luke Tucker](https://github.com/ltucker/): the original JavaScript CD+Graphics implementation
-- Carter Corker: pointing out [babel-plugin-react-css-modules](https://github.com/gajus/babel-plugin-react-css-modules) is totally a thing
+- [David Zukowski](https://zuko.me){{% icon-external %}}: react-redux-starter-kit, which this project began as a fork of (all contributors up until it was detached to its own project are listed on the Contributors page)
+- [Luke Tucker](https://github.com/ltucker/){{% icon-external %}}: the original JavaScript CD+Graphics implementation
+- Carter Corker: pointing out [babel-plugin-react-css-modules](https://github.com/gajus/babel-plugin-react-css-modules){{% icon-external %}} is totally a thing
- Stuart Albert: the name, originally a reference to Duke Nukem Forever, given the development time and almost vaporware status
-- B&W mic icon by [Freepik](https://www.freepik.com/) from [flaticon.com](https://www.flaticon.com/)
+- B&W mic icon by [Freepik](https://www.freepik.com/){{% icon-external %}} from [flaticon.com](https://www.flaticon.com/){{% icon-external %}}
diff --git a/docs/content/docs/kfs_mac.png b/docs/content/docs/kfs_mac.png
deleted file mode 100644
index 907c1cd6..00000000
Binary files a/docs/content/docs/kfs_mac.png and /dev/null differ
diff --git a/docs/content/docs/kfs_win.png b/docs/content/docs/kfs_win.png
deleted file mode 100644
index f9c0220d..00000000
Binary files a/docs/content/docs/kfs_win.png and /dev/null differ
diff --git a/docs/content/docs/server-macos.png b/docs/content/docs/server-macos.png
new file mode 100644
index 00000000..3969c916
Binary files /dev/null and b/docs/content/docs/server-macos.png differ
diff --git a/docs/content/docs/server-windows.png b/docs/content/docs/server-windows.png
new file mode 100644
index 00000000..8990ec7e
Binary files /dev/null and b/docs/content/docs/server-windows.png differ
diff --git a/docs/content/faq.md b/docs/content/faq.md
index fdda5206..3d2e2079 100644
--- a/docs/content/faq.md
+++ b/docs/content/faq.md
@@ -22,9 +22,9 @@ Karaoke tracks require original recording and production. Please support the cre
No, but... is it still karaoke without a mic? :)
-Karaoke Forever makes no assumptions about audio input so that it can work with any microphone setup, including none at all. The player's output (music) can be mixed with microphones in software or an outboard mixer (see below).
+Karaoke Forever makes no assumptions about audio input so that it can work with any microphone setup, including none at all. The player's output (music) can be mixed with microphones in software or an outboard mixer (see below).
-## What's the recommended microphone/audio setup?
+## What's the recommended audio setup?
There are generally 2 ways to mix Karaoke Forever's player output (the music) with microphones. In either case, at least 2 mics are recommended.
diff --git a/docs/layouts/_default/baseof.html b/docs/layouts/_default/baseof.html
index 25de016f..d10bb1d6 100644
--- a/docs/layouts/_default/baseof.html
+++ b/docs/layouts/_default/baseof.html
@@ -6,7 +6,6 @@