The DVBLink Server has a great Remote API [1] and can easily be integrated into third party products. I actually managed to use the existing Plex DVR (Beta) with my DVBLink server using a simple setup with a web server in between to translate the API.
My setup uses an Apache web server listening on ports 80 and 5004. On port 80 I deliver the configuration files (discover.json, lineup_status.json and lineup.json). While these could be built dynamically using the DVBLink Remote API, I am using static versions that I manually created for now. With the channel IDs Plex then builds up the EPG.
For the recordings I use a simple set of pass-through RewriteRules running on port 5004 to map the channels.
Unfortunately, there is still a drawback as I cannot specify any duration for the stream in DVBLink. As such, Plex DVR will just continue and I have to manually stop the recordings.
It would be great if DVBLink Server could be integrated into a future version of Plex DVR, especially as it supports lots of different tuners. However, I do unterstand that during the Beta period you are going to focus on the HDHomeRun product.
Could you send me your discover.json, lineup_status.json and lineup.json files? I want to work on having these generated automagically, but I can’t find documentation on how they should be structured.
Unfortunately I didn’t have much time to continue with the setup and writing the translation layer between the two components. I’m still struggling with finding a solution how to stop the recording.
Instead of using the Rewrite approach from above, using Apache, I tried to come up with a small proxy written in Python that could then also do the translation. However, if I just close the stream after the recording duration, the recording fails and is lost. It would be much appreciated if anyone knew how the end of the recording should be signaled to Plex.
Anyway, I have attached the static json files. You probably need to adapt them with additional channels and your URLs. I anonymized the DeviceID and DeviceAuth token, so I hope it is still working.
In the current static setup I use an Apache running a virtualhost on port 80 that distributes the static json files and another virtualhost running on port 5004 with the Rewrite rules from the first post.
Many thanks! I will play with it a bit. Why does the tuner stop the recording? …
That sounds strange to me
I had assumed that Plex asks for the stream,. creates the recording and stops receiving the stream when the program is over. Lets see if I can tweak your code to call the TVH HTSP api, otherwise I will docker-install DVBLink and see tonight how far I come.
@iPhonedation said:
Many thanks! I will play with it a bit. Why does the tuner stop the recording? …
That sounds strange to me
I had assumed that Plex asks for the stream,. creates the recording and stops receiving the stream when the program is over. Lets see if I can tweak your code to call the TVH HTSP api, otherwise I will docker-install DVBLink and see tonight how far I come.
Cheers
Alex
Please keep us/me updated on this, I’m willing to help out if needed
so I get to the point that I can receive the stream via Chrome from TVH by replicating the ReWriteRule from above… But it does not seem that Plex really saves it.
I will spend some more time on this tomorrow. The EPG looks very promising actually.
What wonders me is the time/duration in the URL call. Does HDHR stop the stream by itself after that time? That would explain the comment from bcyrill.
I’ve actully started an python proxy implementation, I’ve got it covered as far as discover.json, lineup_status.json and lineup.json goes
I however can’t find an example output of “http://–ip–/lineup.post?scan=start&source=Cable” (change source to whatever is currently in use) to mimic.
Do you need the scan? I hacked the tvh-playlist file into a .json in the format (just 3 channels as a test) and it works like a charme to select the region and getting the EPG.
Yes … But you could provide a lineup.json file instead of scanning.
I got it to work. So I just recorded Tagesthemen for a few minutes and it worked flawlessly. The ReWrite to my TVH server just needed to have the user:password@ in front of the URL.
I will program a movie tonight and see how this worked.
@iPhonedation said:
Yes … But you could provide a lineup.json file instead of scanning.
I got it to work. So I just recorded Tagesthemen for a few minutes and it worked flawlessly. The ReWrite to my TVH server just needed to have the user:password@ in front of the URL.
I will program a movie tonight and see how this worked.
Yeah, just an typo in my JSON generation. So my proxy properly proxy’s requests TVH<>Plex (channel propergation works), however I can’t seem to get past this screen, hitting continue does nothing.
Will investigate further
EDIT: duh. seems to be an Chrome issue, Edge works
@iPhonedation said:
Actually, I just recorded a series and it stopped just by itself, no issue at all here on my setup. so i am not sure if this is really required.
RewriteEngine on RewriteRule "^/auto/v001.*$" "http://plex:plex@iphnasvdr:9981/stream/channelid/1571866797?ticket=43892B897FAF6465BB31B187B4995EBE931BF622&profile=htsp" RewriteRule "^/auto/v002.*$" "http://plex:plex@iphnasvdr:9981/stream/channelid/1488363555?ticket=291F1CC01F6A395F646B9BD22779780120945882&profile=pass"
while iphnasvdr is the dns name of my qnap where the tvh runs on.
Both work. I took these out of http://tvheadend:9981/playlist which generates a .m3u file. And then manually put them in a apache.conf file that is my vhost.conf for port 5004.
I had to make the two following changes to modify the request on the fly (It’s a single hardcoded channel for now):
class HttpParser(object):
...
def process_line(self, data):
line = data.split(SP)
if self.type == HTTP_REQUEST_PARSER:
self.method = line[0].upper()
# for now always record the following hard coded channel
line[1] = '/dvblink/direct?channel=10670000'
...
class Proxy(multiprocessing.Process):
...
def _process_request(self, data):
...
if self.request.method == b"CONNECT":
host, port = self.request.url.path.split(COLON)
elif self.request.url:
# hardcoded host and port
host, port = '<IP of DVBLink Server>', 8101
Also I just noted that when I was trying to implement the stream to stop, that I forgot to send an empty chunk in the end which apparently in “chunked transfer encoding” signals the end (https://en.wikipedia.org/wiki/Chunked_transfer_encoding).