Skip to content

Commit

Permalink
Merge pull request #66 from jfarseneau/lucasreiners_optional_streamin…
Browse files Browse the repository at this point in the history
…g_url

Lucasreiners optional streaming url
  • Loading branch information
jfarseneau authored Jan 1, 2022
2 parents 428b2bd + cc6a903 commit 629b03a
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 28 deletions.
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM node:9-alpine
LABEL maintainer "[email protected]"
FROM node:16-alpine
LABEL maintainer="[email protected]"

COPY . /antennas
WORKDIR "/antennas"

RUN yarn install
RUN npm install

EXPOSE 5004
CMD ["node", "index.js"]
CMD ["npx", "."]
39 changes: 27 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![Antennas](https://raw.githubusercontent.com/TheJF/antennas/master/docs/images/antennas-logo.png)
![Antennas](https://raw.githubusercontent.com/jfarseneau/antennas/master/docs/images/antennas-logo.png)

A JavaScript port of [tvhProxy](https://github.com/jkaberg/tvhProxy) which is a program that translates the Tvheadend API to emulate a HDHomeRun API. This is particularly useful to connect [Plex's DVR feature](https://www.plex.tv/features/live-tv-dvr/) to Tvheadend.

Expand All @@ -7,18 +7,18 @@ A JavaScript port of [tvhProxy](https://github.com/jkaberg/tvhProxy) which is a
### Tvheadend Configuration
To be able to stream from Tvheadend through Plex, you need to set up an anonymous user in Tvheadend that has streaming rights. You can do this in the users section, by creating a user `*`:

![Example configuration](https://raw.githubusercontent.com/TheJF/antennas/master/docs/images/tvheadend-config.png)
![Example configuration](https://raw.githubusercontent.com/jfarseneau/antennas/master/docs/images/tvheadend-config.png)

### Using binaries

Head over to the [release](https://github.com/TheJF/antennas/releases) section and download the binary for your platform. It will come with a `config/config.yml` that you can edit to reflect your setup, and you can simply run `antennas` in the console and the server will start up and start proxying Tvheadend over to Plex!
Head over to the [release](https://github.com/jfarseneau/antennas/releases) section and download the binary for your platform. It will come with a `config/config.yml` that you can edit to reflect your setup, and you can simply run `antennas` in the console and the server will start up and start proxying Tvheadend over to Plex!

### Run locally using Node

Right now, due to Docker networking issues, the best way to get this working is by running it directly through node.

* [Set up Node locally](https://nodejs.org/en/download/)
* Clone this repo: `git clone https://github.com/TheJF/antennas.git` or [download the source code directly from releases](https://github.com/TheJF/antennas/releases) and extract it
* Clone this repo: `git clone https://github.com/jfarseneau/antennas.git` or [download the source code directly from releases](https://github.com/jfarseneau/antennas/releases) and extract it
* Run `yarn install` or `npm install` to install dependencies
* In the directory where it was extracted, run `node index.js` (Note, Node version must be above 7)

Expand All @@ -27,22 +27,33 @@ To run it as a daemon:

## Run locally using NPX

`npx antennas --config foo/bar.yml` OR
`TVHEADEND_URL=http://admin:[email protected]:9981 ANTENNAS_URL=http://127.0.0.1:5004 TUNER_COUNT=6 DEVICE_UUID=2f70c0d7-90a3-4429-8275-cbeeee9cd605 npx antennas`
``` shell
npx antennas --config foo/bar.yml
```

OR

``` shell
TVHEADEND_URL=http://admin:[email protected]:9981 ANTENNAS_URL=http://127.0.0.1:5004 TUNER_COUNT=6 DEVICE_UUID=2f70c0d7-90a3-4429-8275-cbeeee9cd605 npx antennas
````

### Docker

Another way to get it running is to run it using Docker. Note that some functionality is currently not quite working when hosting this as a Docker container, namely, discovery from Plex. But with that warning, if you so choose to continue using Docker, the instructions are below.

To start a Docker container running Antennas, run the command below. Note you must replace the `ANTENNAS_URL` and `TVHEADEND_URL` value to match your setup:
`docker run -p 5004:5004 -e ANTENNAS_URL=http://x.x.x.x:5004 -e TVHEADEND_URL=http://replace:[email protected]:9981 thejf/antennas`

``` shell
docker run -p 5004:5004 -e ANTENNAS_URL=http://x.x.x.x:5004 -e TVHEADEND_URL=http://replace:[email protected]:9981 thejf/antennas
```

To view if the configurations have been passed correctly, you can point your browser to where you are hosting Antennas (in the above example, it would be `http://x.x.x.x:5004` but this is a placeholder address that __needs__ to be changed) and you should see a summary of your configurations on the page:

![Example landing page](https://raw.githubusercontent.com/TheJF/antennas/master/docs/images/example-index.png)
![Example landing page](https://raw.githubusercontent.com/jfarseneau/antennas/master/docs/images/example-index.png)

Alternatively, you can set it with all the available environment variables:
```

``` shell
docker create --name=antennas
-e ANTENNAS_URL=http://x.x.x.x:5004
-e TVHEADEND_URL=http://replace:[email protected]:9981
Expand All @@ -53,15 +64,16 @@ Alternatively, you can set it with all the available environment variables:

And then `docker start antennas`

Or, you can try by mounting a volume, set by yourself in path/to/config, that will need a config.yml to work. Example of a config.yml is [available here](https://github.com/TheJF/antennas/blob/master/config/config.yml), or below:
```
Or, you can try by mounting a volume, set by yourself in path/to/config, that will need a config.yml to work. Example of a config.yml is [available here](https://github.com/jfarseneau/antennas/blob/master/config/config.yml), or below:

``` yml
tvheadend_url: http://replace:[email protected]:9981
antennas_url: http://x.x.x.x:5004
tuner_count: 6
```

* `docker create --name=antennas -v <path/to/config>:/antennas/config -p 5004:5004 thejf/antennas`
* Set up `config.yml` (see configuration instructions [here](https://github.com/TheJF/antennas#configuration)) where you pointed the config volume (what you replaced `<path/to/config>` with
* Set up `config.yml` (see configuration instructions [here](https://github.com/jfarseneau/antennas#configuration)) where you pointed the config volume (what you replaced `<path/to/config>` with
* Finally, `docker start antennas`

## Configuration
Expand All @@ -74,11 +86,14 @@ Antennas will look for three values inside a `config/config.yml` file. They are:

* `tvheadend_url`: This is the path to your Tvheadend setup, with username, password, and port. Plex doesn't like `localhost` so it's best to find your own local IP and put this in if Tvheadend and Plex are running on the same network. For example: `http://user:[email protected]:9981`
* `tuner_count`: This is for the number of tuners in Tvheadend.
* `stream_url`: Optional field to set a stream URL that is different from the Tvheadend URL, for private Docker networks

#### Environment variables

If you want to set environment variables instead of modifying the config.yml, you can do so. The environment variable names are the same than the config.yml, except capitalized. So, `TVHEADEND_URL` and `TUNER_COUNT`.

Optionally, for private Docker networks that need to expose a different URL for the streams, you can specify a public stream URL using `TVHEADEND_STREAM_URL`

#### CLI parameters

- `--config` followed by the config path, i.e. `--config foo/bar.yml` will allow you to set a custom path for the config file
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "antennas",
"version": "4.0.2",
"version": "4.1.0",
"description": "HDHomeRun emulator for Plex DVR to connect to Tvheadend.",
"main": "index.js",
"repository": "https://github.com/thejf/antennas",
Expand Down
4 changes: 4 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ <h2>Config Settings</h2>
<td>URL for Tvheadend</td>
<td><a id="tvheadendUrl"></a></td>
</tr>
<tr>
<td>URL for Tvheadend streams</td>
<td><a id="tvheadendStreamUrl"></a></td>
</tr>
<tr>
<td>URL for Antennas</td>
<td><a id="antennasUrl"></a></td>
Expand Down
1 change: 1 addition & 0 deletions public/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function urlReplace(elementId) {
fetch('/antennas_config.json').then((result) => {
let config = JSON.parse(result);
urlReplace('#tvheadendUrl')(config.tvheadend_parsed_uri);
urlReplace('#tvheadendStreamUrl')(config.tvheadend_parsed_stream_uri);
urlReplace('#antennasUrl')(config.antennas_url);
replace('#tunerCount')(config.tuner_count);
replace('#status')(config.status);
Expand Down
28 changes: 20 additions & 8 deletions src/configHandler.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
const yaml = require('js-yaml');
const fs = require('fs');

function structureConfig(tvheadendUrl, antennasUrl, tunerCount, deviceUuid) {
let splitURI = tvheadendUrl.split('@');
let parsedTvheadendURI;
function parseTvheadendURI(uri) {
let splitURI = uri.split('@');
let parsedUri;
if (splitURI.length > 1) {
let password = splitURI[0].split(':')[2];
let username = splitURI[0].split(":")[1].substr(2);
let parsedURI = `${splitURI[0].split(":")[0]}://${splitURI[1]}`
parsedTvheadendURI = {
parsedUri = {
username: username,
password: password,
uri: parsedURI,
}
} else {
parsedTvheadendURI = {
parsedUri = {
username: null,
password: null,
uri: tvheadendUrl,
uri: uri,
}
}

return parsedUri;
}

function structureConfig(tvheadendUrl, tvheadendStreamUrl, antennasUrl, tunerCount, deviceUuid) {
const parsedTvheadendURI = parseTvheadendURI(tvheadendUrl);
const parsedTvheadendStreamURI = parseTvheadendURI(tvheadendStreamUrl);
return {
tvheadend_parsed_uri: parsedTvheadendURI.uri,
tvheadend_username: parsedTvheadendURI.username,
tvheadend_password: parsedTvheadendURI.password,
tvheadend_url: tvheadendUrl,
tvheadend_stream_url: tvheadendStreamUrl,
tvheadend_parsed_stream_uri: parsedTvheadendStreamURI.uri,
tvheadend_stream_username: parsedTvheadendStreamURI.username,
tvheadend_stream_password: parsedTvheadendStreamURI.password,
antennas_url: antennasUrl,
tuner_count: tunerCount,
device_uuid: deviceUuid
Expand All @@ -35,16 +45,18 @@ function structureConfig(tvheadendUrl, antennasUrl, tunerCount, deviceUuid) {
function loadConfig(configFile = 'config/config.yml') {
// Check if you even need to load the config file
if (process.env.TVHEADEND_URL && process.env.ANTENNAS_URL && process.env.TUNER_COUNT && process.env.DEVICE_UUID) {
return structureConfig(process.env.TVHEADEND_URL, process.env.ANTENNAS_URL, process.env.TUNER_COUNT, process.env.DEVICE_UUID);
const tvheadendStreamUrl = process.env.TVHEADEND_STREAM_URL || process.env.TVHEADEND_URL; // Optional
return structureConfig(process.env.TVHEADEND_URL, tvheadendStreamUrl, process.env.ANTENNAS_URL, parseInt(process.env.TUNER_COUNT), process.env.DEVICE_UUID);
}

// If you do, load it
if (fs.existsSync(configFile)) {
let config = yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
return structureConfig(
process.env.TVHEADEND_URL || config.tvheadend_url,
process.env.TVHEADEND_STREAM_URL || config.stream_url || process.env.TVHEADEND_URL || config.tvheadend_url,
process.env.ANTENNAS_URL || config.antennas_url,
process.env.TUNER_COUNT || config.tuner_count,
parseInt(process.env.TUNER_COUNT) || config.tuner_count,
process.env.DEVICE_UUID || config.device_uuid,
)
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/lineup.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = function(config) {
lineup.push({
GuideNumber: String(channel.number),
GuideName: channel.name,
URL: `${config.tvheadend_url}/stream/channel/${channel.uuid}`
URL: `${config.tvheadend_stream_url}/stream/channel/${channel.uuid}`
})
}
}
Expand Down

0 comments on commit 629b03a

Please sign in to comment.