1
0
mirror of https://github.com/fHDHR/fHDHR_NextPVR.git synced 2025-12-06 15:26:57 -05:00

Merge pull request #58 from deathbybandaid/dev

Dev
This commit is contained in:
Deathbybandaid 2020-11-20 09:03:55 -05:00 committed by GitHub
commit 87227bb020
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 551 additions and 53 deletions

View File

@ -1,32 +1,20 @@
# fHDHR_NextPVR
<p align="center">fHDHR_NextPVR <img src="docs/images/logo.ico" alt="Logo"/></p>
Welcome to the world of streaming to Plex! We use some fancy python here to achieve a system of:
Welcome to the world of streaming content as a DVR device! We use some fancy python here to achieve a system of:
**f**un
**H**ome
**D**istribution
**H**iatus &
**H**iatus
**R**ecreation
(based off of original code from
Please Check the [Docs](docs/README.md) for Installation information.
* [tvhProxy by jkaberg](https://github.com/jkaberg/tvhProxy)
* [locast2plex by tgorgdotcom](https://github.com/tgorgdotcom/locast2plex)
* myself coding for locast2plex
)
PRs welcome for:
* Docker support
Please Check the repository wiki for Installation information.
Officially marking this Fork as Beta.
fHDHR is labeled as beta until we reach v1.0.0
Join us in `#fHDHR <irc://irc.freenode.net/#fHDHR>`_ on Freenode.
Due to multiple issues, I'm dropping support for Windows. Sorry. I'll accept PRs to alleviate this.
Due to multiple issues, I'm dropping official support for Windows.

View File

@ -27,6 +27,10 @@
# path = ffmpeg
# bytes_per_read = 1152000
[vlc]
# path = cvlc
# bytes_per_read = 1152000
[direct_stream]
# chunksize = 1048576
@ -42,7 +46,6 @@
# port = 8866
# ssl =
# pin =
# weight = 300
[zap2it]
# delay = 5

156
docs/ADV_Config.md Normal file
View File

@ -0,0 +1,156 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
[Basic Configuration](Config.md) | [Advanced Configuration](ADV_Config.md) | [WebUI](WebUI.md)
---
Here, we'll break down all of the configuration options per section.
## Main
Here's the `main` section.
* `uuid` will be created automatically, you need not worry about this.
* `cache_dir` is handy for keeping cached files out of the script directory. This is helpful for reinstalls as well as development.
````
[main]
# uuid =
# cache_dir =
````
## fhdhr
The `fhdhr` contains all the configuration options for interfacing between this script and your media platform.
* `address` and `port` are what we will allow the script to listen on. `0.0.0.0` is the default, and will respond to all.
* `discovery_address` may be helpful for making SSDP work properly. If `address` is not `0.0.0.0`, we will use that. If this is not set to a real IP, we won't run SSDP. SSDP is only really helpful for discovering in Plex/Emby. It's a wasted resource since you can manually add the `ip:port` of the script to Plex.
* `tuner_count` is a limit of devices able to stream from the script.
* `friendlyname` is to set the name that Plex sees the script as.
* `stream_type` can be set to `ffmpeg`, `vlc` or `direct`.
````
[fhdhr]
# address = 0.0.0.0
# discovery_address = 0.0.0.0
# port = 5004
# stream_type = direct
# tuner_count = 4
# friendlyname = fHDHR-NextPVR
# reporting_firmware_name = fHDHR_NextPVR
# reporting_manufacturer = BoronDust
# reporting_model = fHDHR
# reporting_firmware_ver = 20201001
# reporting_tuner_type = Antenna
# device_auth = fHDHR
````
# EPG
* `images` can be set to `proxy` or `pass`. If you choose `proxy`, images will be reverse proxied through fHDHR.
* `method` defaults to `origin` and will pull the xmltv data from NextPVR. Other Options include `blocks` which is an hourly schedule with minimal channel information. Another option is `zap2it`, which is another source of EPG information. Channel Numbers may need to be manually mapped.
* `update_frequency` * `epg_update_frequency` determines how often we check for new scheduling information. In Seconds.
````
[epg]
# images = pass
# method = origin
# update_frequency = 43200
````
## ffmpeg
The `ffmpeg` section includes:
* `path` is useful if ffmpeg is not in your systems PATH, or you want to manually specify.
* `bytes_per_read` determines how many bytes of the stream to read before sending the data to your client. Increasing this value may cause longer load times, and lowering it may effect `stuttering`.
````
[ffmpeg]
# path = ffmpeg
# bytes_per_read = 1152000
````
## vlc
The `vlc` section includes:
* `path` is useful if ffmpeg is not in your systems PATH, or you want to manually specify.
* `bytes_per_read` determines how many bytes of the stream to read before sending the data to your client. Increasing this value may cause longer load times, and lowering it may effect `stuttering`.
````
[vlc]
# path = ffmpeg
# bytes_per_read = 1152000
````
## direct_stream
The `direct_stream` section is for when you set the `[fhdhr]stream_type` to `direct`
* `chunksize` is how much data to read at a time.
````
[direct_stream]
# chunksize = 1024*1024
````
# Logging
* `level` determines the amount of logging you wish to see in the console, as well as to the logfile (stored in your cache directory).
````
[logging]
# level = WARNING
````
# Database
* experiment with these settings at your own risk. We use sqlalchemy to provide database options, but we default to sqlite.
TODO: improve documentation here.
````
[database]
# type = sqlite
# driver = None
````
## NextPVR
The `nextpvr` section
* What `address` to contact nextpvrat.
* what `port` does nextpvruse
* does nextpvruse `ssl`?
* `pin` is a required credential.
````
[nextpvr]
address = localhost
port = 8866
ssl =
pin =
````
## zap2it
`zap2it` contains a ton of configuration options, and defaults to options that in my experience don't need to be adjusted.
* `postalcode` is a value of importance, and is helpful. If not set, the script will attempt to retrieve your postalcode automatically.
````
[zap2it]
# delay = 5
# postalcode = None
# affiliate_id = gapzap
# country = USA
# device = -
# headendid = lineupId
# isoverride = True
# languagecode = en
# pref =
# timespan = 6
# timezone =
# userid = -
````

43
docs/Config.md Normal file
View File

@ -0,0 +1,43 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
[Basic Configuration](Config.md) | [Advanced Configuration](ADV_Config.md) | [WebUI](WebUI.md)
---
The example config file contains all of the things that the typical user may need to fill out.
Please see the Advanced Configuration page for more information.
## fHDHR
Under `fhdhr`, you'll find 2 addresses listed. `0.0.0.0` works great for a listen address, however, it seems that SSDP works best if the discovery address is set to the IP to say that there is a service at.
````
[fhdhr]
# address = 0.0.0.0
# port = 5004
# discovery_address = 0.0.0.0
````
## NextPVR
NextPVR requires signin pin, so add that.
````
[nextpvr]
address = localhost
port = 8866
pin =
````

15
docs/Origin.md Normal file
View File

@ -0,0 +1,15 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
This varient of fHDHR connects to a local NextPVR instance.

46
docs/README.md Normal file
View File

@ -0,0 +1,46 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
# The Boring Disclaimers (at the top of the docs for a reason)
fHDHR is a Python service to take various sources of video and make them accessible to client software including, but not limited to:
* [Plex](https://www.plex.tv/)
* [Emby](https://emby.media/)
* [Jellyfin](https://jellyfin.org/)
* [Channels](https://getchannels.com/)
fHDHR is not directly affiliated with the above client software, and you will receive NO support for this script via their forums.
fHDHR is able to connect to clients by emulating a piece of hardware called the [HDHomeRun from SiliconDust](https://www.silicondust.com/). fHDHR is in NO way affiliated with SiliconDust, and is NOT a HDHomeRun device. fHDHR simply uses the API structure used by the authentic HDHomeRun to connect to client DVR solutions.
# History
I got the Huappage QuadHD, and the Mohu Sail as a pandemic-project. All was fine working within Plex, but I also have emby setup as a backup to Plex when auth is broken.
I thought to myself, "Self, I should look on github for a way to share my tv tuner between the two".
That's when I tried both npvrProxy with NextPVR as well as tvhProxy with TVHeadend. I had to tinker with both to get them working, but I started testing which one I liked more.
Around this same time, I stumbled upon [locast2plex by tgorgdotcom](https://github.com/tgorgdotcom/locast2plex). I wanted to contribute to that project to get it to a point that I could fork it to work for other video stream sources.
The locast2plex code development wasn't going quite fast enough for the feature-creep in my head.
I then proceded to create the initial iteration of fHDHR which I originally called "FakeHDHR". I've rewritten the core functionality a few times before landing on the current code structure, which feels 'right'.
I've worked really hard to create a structure that simplifies new variants of the core code to work with different 'origin' streams. Combining these works really well with [xTeVe](https://github.com/xteve-project/xTeVe).
One of the variants goes as far as scraping a table from a PDF file for creating a channel guide!
I can easily create more variants of the project to do other video sources. Paid ones, I could potentially accept donations for, as I don't want to pay to develop for multiple platforms.

26
docs/Related-Projects.md Normal file
View File

@ -0,0 +1,26 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
While the fHDHR reops share very little code from the below projects, they were a source of inspiration:
* [tvhProxy by jkaberg](https://github.com/jkaberg/tvhProxy)
* [locast2plex by tgorgdotcom](https://github.com/tgorgdotcom/locast2plex)
Aside from the above, these other projects are worth a look as well:
* [npvrProxy](https://github.com/rogueosb/npvrProxy)
* [xTeVe](https://xteve.de/)
* [telly](https://github.com/tellytv/telly)
* [dizquetv](https://github.com/vexorian/dizquetv)

129
docs/Usage.md Normal file
View File

@ -0,0 +1,129 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
[Basic Configuration](Config.md) | [Advanced Configuration](ADV_Config.md) | [WebUI](WebUI.md)
---
# Author Notes
* All Testing is currently done in Proxmox LXC, Ubuntu 20.04, Python 3.8
# Prerequisites
* A Linux or Mac "Server". Windows currently does not work. A "Server" is a computer that is typically always online.
* Python 3.7 or later.
* Consult [This Page](Origin.md) for additional setup specific to this variant of fHDHR.
# Optional Prerequisites
* If you intend to use Docker, [This Guide](https://docs.docker.com/get-started/) should help you get started. The author of fHDHR is not a docker user, but will still try to help.
fHDHR uses direct connections with video sources by default. Alternatively, you can install and update the [config](Config.md) accordingly. You will need to make these available to your systems PATH, or manually set their path via the config file.
* ffmpeg
* vlc
# Installation
## Linux
* Download the zip, or git clone
* Navigate into your script directory and run `pip3 install -r requirements.txt`
* Copy the included `config.example.ini` file to a known location. The script will not run without this. There is no default configuration file location. [Modify the configuration file to suit your needs.](Config.md)
* Run with `python3 main.py -c=` and the path to the config file.
## Docker
This portion of the guide assumes you are using a Linux system with both docker and docker-compose installed. This (or some variation thereof) may work on Mac or Windows, but has not been tested.
* this guide assumes we wish to use the `~/fhdhr` directory for our install (you can use whatever directory you like, just make the appropriate changes elsewhere in this guide) and that we are installing for NextPVR support
* run the following commands to clone the repo into `~/fhdhr/fHDHR_NextPVR`
```
cd ~/fhdhr
git clone https://github.com/fHDHR/fHDHR_NextPVR.git
```
* create your config.ini file (as described earlier in this guide) in the `~/fhdhr/fHDHR_NextPVR` directory
* while still in the `~/fhdhr` directory, create the following `docker-compose.yml` file
```
version: '3'
services:
nextpvr:
build: ./fHDHR_NextPVR
container_name: nextpvr
network_mode: host
volumes:
- ./fHDHR_NextPVR/config.ini:/app/config/config.ini
```
* run the following command to build and launch the container
```
docker-compose up --build -d nextpvr
```
After a short period of time (during which docker will build your new fHDHR container), you should now have a working build of fHDHR running inside a docker container.
As the code changes and new versions / bug fixes are released, at any point you can pull the latest version of the code and rebuild your container with the following commands:
```
cd ~/fhdhr/fHDHR_NextPVR
git checkout master
git pull
cd ~/fhdhr
docker-compose up --build -d nextpvr
```
<hr />
You can also run multiple instances of fHDHR to support additional sources by cloning the appropriate repo into your `~/fhdhr` directory and adding the necessary services to the docker-compose file we created above.
* for example, if we also wanted PlutoTV support, you would clone the PlutoTV repository:
```
cd ~/fhdhr
git clone https://github.com/fHDHR/fHDHR_PlutoTV.git
```
* **NOTE**: if you are running multiple services on the same machine, you must change the port in your config.ini file for each one. For example, if NextPVR was using the default port of 5004, PlutoTV cannot also use that port. You must change the port in your PlutoTV config.ini file to something else (5005, for example).
* add plutotv as a service in your `docker-compose.yml` file
```
version: '3'
services:
nextpvr:
build: ./fHDHR_NextPVR
container_name: nextpvr
network_mode: host
volumes:
- ./fHDHR_NextPVR/config.ini:/app/config/config.ini
plutotv:
build: ./fHDHR_PlutoTV
container_name: plutotv
network_mode: host
volumes:
- ./fHDHR_PlutoTV/config.ini:/app/config/config.ini
```
* run the following command to build and launch the container
```
docker-compose up --build -d plutotv
```
You can repeat these instructions for as many fHDHR containers as your system resources will allow.
# Setup
Now that you have fHDHR running, You can navigate (in a web browser) to the IP:Port from the configuration step above.
If you did not setup a `discovery_address` in your config, SSDP will be disabled. This is not a problem as clients like Plex can have the IP:Port entered manually!
You can copy the xmltv link from the webUI and use that in your client software to provide Channel Guide information.

98
docs/WebUI.md Normal file
View File

@ -0,0 +1,98 @@
<p align="center">fHDHR <img src="images/logo.ico" alt="Logo"/></p>
---
[Main](README.md) | [Setup and Usage](Usage.md) | [NextPVR](Origin.md) | [Credits/Related Projects](Related-Projects.md)
---
**f**un
**H**ome
**D**istribution
**H**iatus
**R**ecreation
---
[Basic Configuration](Config.md) | [Advanced Configuration](ADV_Config.md) | [WebUI](WebUI.md)
---
This Page will introduce basic handling of the script from the Web Interface provided at IP:Port
The Pages are available in the buttons at the top, links to xmltv and m3u are provided at the top for ease of access.
# Main Landing Page
Below is the main landing page with basic information.
<img src="screenshots/webui_main.PNG" alt="Main Page"/>
# NextPVR
Here you will have access to some basic information about the service we are proxying.
The webUI will still work, even if setup didn't go smoothly.
<img src="screenshots/webui_origin.PNG" alt="Origin Page"/>
# Guide
This Page give you information about what is currently playing on all stations. It will also show the time remaining for each item.
* Note: The Play link in the left hand column can be copied to play a channel in VLC media player!
<img src="screenshots/webui_guide.PNG" alt="Guide Page"/>
# Cluster
Since SSDP is used for service discovery, I decided to also use it for ease of management.
This tab will not have the below options if SSDP isn't running.
Joining a cluster will provide a second row of buttons for the clustered servers.
Unjoined:
<img src="screenshots/webui_cluster_unjoined.PNG" alt="Cluster Page, UnJoined"/>
Joined:
<img src="screenshots/webui_cluster_joined.PNG" alt="Cluster Page, Joined"/>
# Streams
This Page will show all active streams, and tuner information. You can also terminate a stream from here.
* Note: Clients will often have an amount buffered, and the connection termination is not immediate from a viewing perspective. However, the connection to the source is indeed cut off.
<img src="screenshots/webui_streams.PNG" alt="Streams Page"/>
# xmltv
This page will give you access to all the xmltv formats provided by this varient.
From here, you can manually update or even clear the cached epg, and then update.
<img src="screenshots/webui_xmltv.PNG" alt="xmltv Page"/>
# Version
This page will give valuable information about the environment the script is being run in.
<img src="screenshots/webui_version.PNG" alt="Version Page"/>
# Diganostics
This page has various links to json/xml files that make the magic work, as well as debug and cluster information.
<img src="screenshots/webui_diagnostics.PNG" alt="Diagnostics Page"/>
# Settings
This page allows viewing/changing all possible configuration options.
* Note: This will require a restart of the script to have any effect.
<img src="screenshots/webui_diagnostics.PNG" alt="Diagnostics Page"/>

BIN
docs/images/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -22,7 +22,7 @@ if sys.version_info.major == 2 or sys.version_info < (3, 7):
opersystem = platform.system()
if opersystem in ["Windows"]:
print("WARNING: This script may fail on Windows.")
print("WARNING: This script may fail on Windows. Try Setting the `thread_method` to `threading`")
def build_args_parser():

View File

@ -1,4 +1,5 @@
import os
import sys
import random
import configparser
import pathlib
@ -8,6 +9,7 @@ import platform
import json
import fHDHR.exceptions
from fHDHR import fHDHR_VERSION
from fHDHR.tools import isint, isfloat, is_arithmetic, is_docker
@ -49,15 +51,14 @@ class Config():
def load_versions(self):
self.internal["versions"] = {
"opersystem": None,
"isdocker": False,
"ffmpeg": "N/A",
"vlc": "N/A"
}
self.internal["versions"] = {}
self.internal["versions"]["fHDHR"] = fHDHR_VERSION
self.internal["versions"]["Python"] = sys.version
opersystem = platform.system()
self.internal["versions"]["opersystem"] = opersystem
self.internal["versions"]["Operating System"] = opersystem
if opersystem in ["Linux", "Darwin"]:
# Linux/Mac
if os.getuid() == 0 or os.geteuid() == 0:
@ -70,7 +71,7 @@ class Config():
print("Uncommon Operating System, use at your own risk.")
isdocker = is_docker()
self.internal["versions"]["isdocker"] = isdocker
self.internal["versions"]["Docker"] = isdocker
if self.dict["fhdhr"]["stream_type"] == "ffmpeg":
try:

View File

@ -2,13 +2,13 @@
from .index_html import Index_HTML
from .origin_html import Origin_HTML
from .cluster_html import Cluster_HTML
from .diagnostics_html import Diagnostics_HTML
from .streams_html import Streams_HTML
from .version_html import Version_HTML
from .guide_html import Guide_HTML
from .cluster_html import Cluster_HTML
from .streams_html import Streams_HTML
from .xmltv_html import xmlTV_HTML
from .settings import Settings_HTML
from .version_html import Version_HTML
from .diagnostics_html import Diagnostics_HTML
from .settings_html import Settings_HTML
class fHDHR_Pages():
@ -16,12 +16,12 @@ class fHDHR_Pages():
def __init__(self, fhdhr):
self.fhdhr = fhdhr
self.index = Index_HTML(fhdhr)
self.settings = Settings_HTML(fhdhr)
self.origin = Origin_HTML(fhdhr)
self.cluster = Cluster_HTML(fhdhr)
self.diagnostics = Diagnostics_HTML(fhdhr)
self.version = Version_HTML(fhdhr)
self.guide = Guide_HTML(fhdhr)
self.streams = Streams_HTML(fhdhr)
self.xmltv = xmlTV_HTML(fhdhr)
self.index_html = Index_HTML(fhdhr)
self.origin_html = Origin_HTML(fhdhr)
self.guide_html = Guide_HTML(fhdhr)
self.cluster_html = Cluster_HTML(fhdhr)
self.streams_html = Streams_HTML(fhdhr)
self.xmltv_html = xmlTV_HTML(fhdhr)
self.version_html = Version_HTML(fhdhr)
self.diagnostics_html = Diagnostics_HTML(fhdhr)
self.settings_html = Settings_HTML(fhdhr)

View File

@ -1,4 +1,3 @@
import sys
from flask import request, render_template
@ -13,13 +12,7 @@ class Version_HTML():
return self.get(*args)
def get(self, *args):
version_dict = {
"fHDHR": self.fhdhr.version,
"Python": sys.version,
"Operating System": self.fhdhr.config.internal["versions"]["opersystem"],
"Using Docker": self.fhdhr.config.internal["versions"]["isdocker"],
"ffmpeg": self.fhdhr.config.internal["versions"]["ffmpeg"],
"vlc": self.fhdhr.config.internal["versions"]["vlc"],
}
version_dict = {}
for key in list(self.fhdhr.config.internal["versions"].keys()):
version_dict[key] = self.fhdhr.config.internal["versions"][key]
return render_template('version.html', request=request, fhdhr=self.fhdhr, version_dict=version_dict, list=list)