Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:16

# Set working directory
WORKDIR /app

# Copy project files
COPY . .

# Install dependencies
RUN npm install

# Expose default port
EXPOSE 8000

# Start the application with environment variables
CMD ["sh", "-c", "node server/server.js --port ${PORT:-8000} ${HQPLAYER_HOST:+--hqpip $HQPLAYER_HOST}"]
97 changes: 3 additions & 94 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 56 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# HQPWV
# HQPWV

HQPWV is a local webserver that allows you to remotely control [HQPlayer](https://www.signalyst.com/consumer.html) from any device on your network using a web browser.

[End-user installation instructions](https://github.com/zeropointnine/hqpwv/blob/master/readme_enduser.md)
Expand All @@ -10,17 +10,17 @@ Demo video:
[![Demo video](https://i.vimeocdn.com/video/1226369138-b9eb51cefba593dcf444fd1bad72adcfae4474ee2ac765ea22cc37d1d90515b5-d?mw=1920&mh=1080&q=100)](https://vimeo.com/593569610 "Demo video")


# Development setup
# Development setup

1. `cd` to the project directory.

2. Make sure Node.js is installed. Then enter:
`npm install`.
`npm install`.

3. To modify the css, make sure `sass` is installed. Then compile with:
`sass scss/main.scss www/css/main.css`
If simply trying to run the project, this step can be skipped, as the compiled css is included in the repository.

4. Make sure [HQPlayer 4](https://www.signalyst.com/consumer.html) is running.

5. Start the server:
Expand All @@ -31,4 +31,51 @@ If simply trying to run the project, this step can be skipped, as the compiled c
Executables are generated with `pkg` by simply entering:
`pkg .`

Front-end code consists of untranspiled, vanilla ES6 classes.
Front-end code consists of untranspiled, vanilla ES6 classes.


# Docker Deployment

For quick testing or one-off runs, you can launch HQPWV using Docker directly:

```bash
docker run -d \
-p 8080:8000 \
-e HQPLAYER_HOST=192.168.1.6 \
--name hqpwv \
muness/hqpwv:latest
```

- Replace `192.168.1.6` with the IP address of your HQPlayer Desktop instance.
- The web UI will be available at `http://<host-ip>:8080`.

Note: On macOS or Windows hosts, UDP-based HQPlayer discovery is not available inside Docker containers, so using `HQPLAYER_HOST` is required.

For longer-term or multi-service deployments (e.g. on a NAS), see the Docker Compose section below.

## Docker Compose Deployment

For a more streamlined and repeatable setup, you can deploy HQPWV using Docker Compose:

1. Create a `docker-compose.yml` file with the following content:

```yaml
services:
hqpwv:
image: muness/hqpwv:latest
container_name: hqpwv
ports:
- "8080:8000"
environment:
- HQPLAYER_HOST=192.168.1.6
```

- Replace `192.168.1.6` with the actual IP address of your HQPlayer Desktop instance.

2. Start the service:

```bash
docker compose up -d
```

3. Open your browser to `http://<host-ip>:8080` to use the web UI.
13 changes: 11 additions & 2 deletions server/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,22 @@ let validHqpHostnames = [];

let isFirstChunk = true;
let clientRequestXml; // The request data fro the client
let clientRequestAsJson;
let clientRequestAsJson;
let responseCallback; // The callback to be invoked upon completion of the current 'command'
let normalBuffer = Buffer.alloc(0); // The buffered data which accumulates until complete, used for 'normal' responses
let isPossiblyMultiChunk;

const start = (callback) => {
initCallback = callback;

const overrideIp = process.env.HQPLAYER_HOST;
if (overrideIp) {
log.x(`[i] Skipping discovery, using HQPLAYER_HOST: ${overrideIp}`);
hqpIp = overrideIp;
initSocket();
return;
}

initDiscoverySocket();
};

Expand All @@ -50,7 +59,7 @@ const initDiscoverySocket = () => {
}
log.x('creating udp socket');
discoSocket = dgram.createSocket('udp4');

discoSocket.on('error', () => {
log.w(`udp socket error:\n${err.stack}\n`);
discoSocket.close();
Expand Down