1
0
mirror of https://github.com/fHDHR/fHDHR_NextPVR.git synced 2025-12-06 09:36:59 -05:00

Compare commits

..

No commits in common. "4bd2ff971e702a2bb46dbe120f15cb6ecbad37c2" and "fc0708d8887bb84c722b8639cdfb866f17241a01" have entirely different histories.

17 changed files with 151 additions and 293 deletions

62
config.all.ini Normal file
View File

@ -0,0 +1,62 @@
[main]
# uuid =
# cache_dir =
# servicename = NextPVR
# reponame = fHDHR_NextPVR
[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 = pass
# method = origin
# update_frequency = 43200
[ffmpeg]
# path = ffmpeg
# bytes_per_read = 1152000
[vlc]
# path = cvlc
# bytes_per_read = 1152000
[direct_stream]
# chunksize = 1048576
[logging]
# level = WARNING
[database]
# type = sqlite
# driver = None
[nextpvr]
# address = localhost
# port = 8866
# ssl =
# pin =
[zap2it]
# delay = 5
# postalcode = None
# affiliate_id = gapzap
# country = USA
# device = -
# headendid = lineupId
# isoverride = True
# languagecode = en
# pref =
# timespan = 6
# timezone =
# userid = -

View File

@ -55,6 +55,11 @@
"config_file": true,
"config_web": true
},
"stream_type":{
"value": "direct",
"config_file": true,
"config_web": true
},
"tuner_count":{
"value": 4,
"config_file": true,

View File

@ -5,20 +5,10 @@
"config_file": true,
"config_web": true
},
"origin_quality": {
"quality": {
"value": "none",
"config_file": true,
"config_web": true
},
"transcode_quality": {
"value": "none",
"config_file": true,
"config_web": true
},
"method": {
"value": "direct",
"config_file": true,
"config_web": true
}
},
"ffmpeg":{

View File

@ -28,28 +28,14 @@ Here's the `main` section.
# cache_dir =
````
## streaming
* `method` can be set to `ffmpeg`, `vlc` or `direct`.
* `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`.
````
[streaming]
# method = direct
````
## 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. The default is 3, as per Locast's documentation. A 4th is possible, but is not reccomended.
* `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.
* `reporting_*` are settings that show how the script projects itself as a hardware device.
* `device_auth` and `require_auth` are for an unimplemented Authentication feature.
* `chanscan_on_start` Scans Origin for new channels at startup.
* `stream_type` can be set to `ffmpeg`, `vlc` or `direct`.
````
@ -57,56 +43,61 @@ The `fhdhr` contains all the configuration options for interfacing between this
# address = 0.0.0.0
# discovery_address = 0.0.0.0
# port = 5004
# stream_type = direct
# tuner_count = 4
# friendlyname = fHDHR-Locast
# reporting_firmware_name = fHDHR_Locast
# 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
# require_auth = False
# chanscan_on_start = True
````
# 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 Locast. 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` determines how often we check for new scheduling information. In Seconds.
* `reverse_days` allows Blocks of EPG data to be created prior to the start of the EPG Source data.
* `forward_days` allows Blocks of EPG data to be created after the end of the EPG Source data.
* `block_size` in seconds, sets the default block size for data before, after and missing timeslots.
* `xmltv_offset` allows the final xmltv file to have an offset for users with timezone issues.
* `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
# reverse_days = -1
# forward_days = 7
# block_size = 1800
# xmltv_offset = +0000
````
## 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 = cvlc
# 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
@ -126,27 +117,6 @@ TODO: improve documentation here.
[database]
# type = sqlite
# driver = None
user = None
pass = None
host = None
port = None
name = None
````
## RMG
````
# enabled = True
````
## SSDP
````
# enabled = True
# max_age = 1800
# proto = ipv6
# iface = None
# multicast_address = None
````
## NextPVR

View File

@ -103,7 +103,7 @@ class Config():
isdocker = is_docker()
self.internal["versions"]["Docker"] = isdocker
if self.dict["streaming"]["method"] == "ffmpeg":
if self.dict["fhdhr"]["stream_type"] == "ffmpeg":
try:
ffmpeg_command = [self.dict["ffmpeg"]["path"],
"-version",
@ -121,7 +121,7 @@ class Config():
print("Failed to find ffmpeg.")
self.internal["versions"]["ffmpeg"] = ffmpeg_version
if self.dict["streaming"]["method"] == "vlc":
if self.dict["fhdhr"]["stream_type"] == "vlc":
try:
vlc_command = [self.dict["vlc"]["path"],
"--version",
@ -310,7 +310,7 @@ class Config():
self.dict["database"]["path"] = pathlib.Path(cache_dir).joinpath('fhdhr.db')
if self.dict["streaming"]["method"] not in ["direct", "ffmpeg", "vlc"]:
if self.dict["fhdhr"]["stream_type"] not in ["direct", "ffmpeg", "vlc"]:
raise fHDHR.exceptions.ConfigurationError("Invalid stream type. Exiting...")
if not self.dict["fhdhr"]["discovery_address"] and self.dict["fhdhr"]["address"] != "0.0.0.0":

View File

@ -190,7 +190,7 @@ class Channel():
@property
def api_stream_url(self):
return '/api/tuners?method=%s&channel=%s' % (self.fhdhr.config.dict["streaming"]["method"], self.number)
return '/api/tuners?method=%s&channel=%s' % (self.fhdhr.config.dict["fhdhr"]["stream_type"], self.number)
@property
def m3u_url(self):

View File

@ -1,4 +1,3 @@
import m3u8
from fHDHR.exceptions import TunerError
@ -97,15 +96,12 @@ class Tuners():
raise TunerError("806 - Tune Failed")
if isinstance(stream_info, str):
stream_info = {"url": stream_info, "headers": None}
stream_info = {"url": stream_info}
stream_args["stream_info"] = stream_info
if not stream_args["stream_info"]["url"]:
raise TunerError("806 - Tune Failed")
if "headers" not in list(stream_args["stream_info"].keys()):
stream_args["stream_info"]["headers"] = None
if stream_args["stream_info"]["url"].startswith("udp://"):
stream_args["true_content_type"] = "video/mpeg"
stream_args["content_type"] = "video/mpeg"
@ -116,81 +112,7 @@ class Tuners():
if stream_args["true_content_type"].startswith(tuple(["application/", "text/"])):
stream_args["content_type"] = "video/mpeg"
if stream_args["origin_quality"] != -1:
stream_args["stream_info"]["url"] = self.m3u8_quality(stream_args)
else:
stream_args["content_type"] = stream_args["true_content_type"]
return stream_args
def m3u8_quality(self, stream_args):
m3u8_url = stream_args["stream_info"]["url"]
quality_profile = stream_args["origin_quality"]
if not quality_profile:
quality_profile = "high"
self.fhdhr.logger.info("Origin Quality not set in config. Defaulting to Highest Quality")
else:
quality_profile = quality_profile.lower()
self.fhdhr.logger.info("Origin Quality set in config to %s" % (quality_profile))
while True:
self.fhdhr.logger.info("Opening m3u8 for reading %s" % m3u8_url)
if stream_args["stream_info"]["headers"]:
videoUrlM3u = m3u8.load(m3u8_url, headers=stream_args["stream_info"]["headers"])
else:
videoUrlM3u = m3u8.load(m3u8_url)
if len(videoUrlM3u.playlists):
self.fhdhr.logger.info("%s m3u8 varients found" % len(videoUrlM3u.playlists))
# Create list of dicts
playlists, playlist_index = {}, 0
for playlist_item in videoUrlM3u.playlists:
playlist_index += 1
playlist_dict = {
"url": playlist_item.absolute_uri,
"bandwidth": playlist_item.stream_info.bandwidth,
}
if not playlist_item.stream_info.resolution:
playlist_dict["width"] = None
playlist_dict["height"] = None
else:
try:
playlist_dict["width"] = playlist_item.stream_info.resolution[0]
playlist_dict["height"] = playlist_item.stream_info.resolution[1]
except TypeError:
playlist_dict["width"] = None
playlist_dict["height"] = None
playlists[playlist_index] = playlist_dict
sorted_playlists = sorted(playlists, key=lambda i: (
int(playlists[i]['bandwidth']),
int(playlists[i]['width'] or 0),
int(playlists[i]['height'] or 0)
))
sorted_playlists = [playlists[x] for x in sorted_playlists]
if not quality_profile or quality_profile == "high":
selected_index = -1
elif quality_profile == "medium":
selected_index = int((len(sorted_playlists) - 1)/2)
elif quality_profile == "low":
selected_index = 0
m3u8_stats = ",".join(
["%s %s" % (x, sorted_playlists[selected_index][x])
for x in list(sorted_playlists[selected_index].keys())
if x != "url" and sorted_playlists[selected_index][x]])
self.fhdhr.logger.info("Selected m3u8 details: %s" % m3u8_stats)
m3u8_url = sorted_playlists[selected_index]["url"]
else:
self.fhdhr.logger.info("No m3u8 varients found")
break
return m3u8_url

View File

@ -21,7 +21,18 @@ class Direct_M3U8_Stream():
if not self.stream_args["duration"] == 0:
self.stream_args["time_end"] = self.stream_args["duration"] + time.time()
self.fhdhr.logger.info("Detected stream of m3u8 URL: %s" % self.stream_args["stream_info"]["url"])
self.fhdhr.logger.info("Detected stream URL is m3u8: %s" % self.stream_args["true_content_type"])
channel_stream_url = self.stream_args["stream_info"]["url"]
while True:
self.fhdhr.logger.info("Opening m3u8 for reading %s" % channel_stream_url)
videoUrlM3u = m3u8.load(channel_stream_url)
if len(videoUrlM3u.playlists):
self.fhdhr.logger.info("%s m3u8 varients found" % len(videoUrlM3u.playlists))
channel_stream_url = videoUrlM3u.playlists[0].absolute_uri
else:
break
def generate():
@ -31,11 +42,7 @@ class Direct_M3U8_Stream():
while self.tuner.tuner_lock.locked():
if self.stream_args["stream_info"]["headers"]:
playlist = m3u8.load(self.stream_args["stream_info"]["url"], headers=self.stream_args["stream_info"]["headers"])
else:
playlist = m3u8.load(self.stream_args["stream_info"]["url"])
playlist = m3u8.load(channel_stream_url)
segments = playlist.segments
if len(played_chunk_urls):
@ -63,19 +70,13 @@ class Direct_M3U8_Stream():
self.fhdhr.logger.info("Requested Duration Expired.")
self.tuner.close()
if self.stream_args["stream_info"]["headers"]:
chunk = self.fhdhr.web.session.get(chunkurl, headers=self.stream_args["stream_info"]["headers"]).content
else:
chunk = self.fhdhr.web.session.get(chunkurl).content
chunk = self.fhdhr.web.session.get(chunkurl).content
if not chunk:
break
# raise TunerError("807 - No Video Data")
if key:
if key["url"]:
if self.stream_args["stream_info"]["headers"]:
keyfile = self.fhdhr.web.session.get(key["url"], headers=self.stream_args["stream_info"]["headers"]).content
else:
keyfile = self.fhdhr.web.session.get(key["url"]).content
keyfile = self.fhdhr.web.session.get(key["url"]).content
cryptor = AES.new(keyfile, AES.MODE_CBC, keyfile)
self.fhdhr.logger.info("Decrypting Chunk #%s with key: %s" % (len(played_chunk_urls), key["url"]))
chunk = cryptor.decrypt(chunk)

View File

@ -20,10 +20,7 @@ class Direct_Stream():
self.fhdhr.logger.info("Direct Stream of %s URL: %s" % (self.stream_args["true_content_type"], self.stream_args["stream_info"]["url"]))
if self.stream_args["stream_info"]["headers"]:
req = self.fhdhr.web.session.get(self.stream_args["stream_info"]["url"], stream=True, headers=self.stream_args["stream_info"]["headers"])
else:
req = self.fhdhr.web.session.get(self.stream_args["stream_info"]["url"], stream=True)
req = self.fhdhr.web.session.get(self.stream_args["stream_info"]["url"], stream=True)
def generate():

View File

@ -50,26 +50,12 @@ class FFMPEG_Stream():
self.fhdhr.config.dict["ffmpeg"]["path"],
"-i", stream_args["stream_info"]["url"],
]
ffmpeg_command.extend(self.ffmpeg_headers(stream_args))
ffmpeg_command.extend(self.ffmpeg_duration(stream_args))
ffmpeg_command.extend(self.transcode_profiles(stream_args))
ffmpeg_command.extend(self.ffmpeg_loglevel())
ffmpeg_command.extend(["pipe:stdout"])
return ffmpeg_command
def ffmpeg_headers(self, stream_args):
ffmpeg_command = []
if stream_args["stream_info"]["headers"]:
headers_string = ""
if len(list(stream_args["stream_info"]["headers"].keys())) > 1:
for x in list(stream_args["stream_info"]["headers"].keys()):
headers_string += "%s: %s\r\n" % (x, stream_args["stream_info"]["headers"][x])
else:
for x in list(stream_args["stream_info"]["headers"].keys()):
headers_string += "%s: %s" % (x, stream_args["stream_info"]["headers"][x])
ffmpeg_command.extend(["-headers", '\"%s\"' % headers_string])
return ffmpeg_command
def ffmpeg_duration(self, stream_args):
ffmpeg_command = []
if stream_args["duration"]:
@ -117,30 +103,30 @@ class FFMPEG_Stream():
16:9 content, not exceeding 320x240 30fps for 4:3 content
"""
if stream_args["transcode_quality"]:
self.fhdhr.logger.info("Client requested a %s transcode for stream." % stream_args["transcode_quality"])
stream_args["transcode_quality"] = None
if stream_args["transcode"]:
self.fhdhr.logger.info("Client requested a %s transcode for stream." % stream_args["transcode"])
stream_args["transcode"] = None
ffmpeg_command = []
if not stream_args["transcode_quality"]:
if not stream_args["transcode"]:
ffmpeg_command.extend(
[
"-c", "copy",
"-f", "mpegts",
]
)
elif stream_args["transcode_quality"] == "heavy":
elif stream_args["transcode"] == "heavy":
ffmpeg_command.extend([])
elif stream_args["transcode_quality"] == "mobile":
elif stream_args["transcode"] == "mobile":
ffmpeg_command.extend([])
elif stream_args["transcode_quality"] == "internet720":
elif stream_args["transcode"] == "internet720":
ffmpeg_command.extend([])
elif stream_args["transcode_quality"] == "internet480":
elif stream_args["transcode"] == "internet480":
ffmpeg_command.extend([])
elif stream_args["transcode_quality"] == "internet360":
elif stream_args["transcode"] == "internet360":
ffmpeg_command.extend([])
elif stream_args["transcode_quality"] == "internet240":
elif stream_args["transcode"] == "internet240":
ffmpeg_command.extend([])
return ffmpeg_command

View File

@ -51,17 +51,12 @@ class VLC_Stream():
self.fhdhr.config.dict["vlc"]["path"],
"-I", "dummy", stream_args["stream_info"]["url"],
]
# vlc_command.extend(self.vlc_headers(stream_args))
vlc_command.extend(self.vlc_duration(stream_args))
vlc_command.extend(self.vlc_loglevel())
vlc_command.extend(["--sout"])
vlc_command.extend(self.transcode_profiles(stream_args))
return vlc_command
def vlc_headers(self, stream_args):
vlc_command = []
return vlc_command
def vlc_duration(self, stream_args):
vlc_command = []
if stream_args["duration"]:
@ -100,28 +95,28 @@ class VLC_Stream():
"""
vlc_command = []
if stream_args["transcode_quality"]:
self.fhdhr.logger.info("Client requested a %s transcode for stream." % stream_args["transcode_quality"])
stream_args["transcode_quality"] = None
if stream_args["transcode"]:
self.fhdhr.logger.info("Client requested a %s transcode for stream." % stream_args["transcode"])
stream_args["transcode"] = None
vlc_transcode_string = "#std{mux=ts,access=file,dst=-}"
return [vlc_transcode_string]
'#transcode{vcodec=mp2v,vb=4096,acodec=mp2a,ab=192,scale=1,channels=2,deinterlace}:std{access=file,mux=ts,dst=-"}'
if not stream_args["transcode_quality"]:
if not stream_args["transcode"]:
vlc_command.extend([])
elif stream_args["transcode_quality"] == "heavy":
elif stream_args["transcode"] == "heavy":
vlc_command.extend([])
elif stream_args["transcode_quality"] == "mobile":
elif stream_args["transcode"] == "mobile":
vlc_command.extend([])
elif stream_args["transcode_quality"] == "internet720":
elif stream_args["transcode"] == "internet720":
vlc_command.extend([])
elif stream_args["transcode_quality"] == "internet480":
elif stream_args["transcode"] == "internet480":
vlc_command.extend([])
elif stream_args["transcode_quality"] == "internet360":
elif stream_args["transcode"] == "internet360":
vlc_command.extend([])
elif stream_args["transcode_quality"] == "internet240":
elif stream_args["transcode"] == "internet240":
vlc_command.extend([])
return vlc_command

View File

@ -11,7 +11,7 @@ from .rmg import fHDHR_RMG
from .api import fHDHR_API
fHDHR_web_VERSION = "v0.8.1-beta"
fHDHR_web_VERSION = "v0.8.0-beta"
class fHDHR_HTTP_Server():
@ -219,8 +219,7 @@ class fHDHR_HTTP_Server():
self.http = WSGIServer(self.fhdhr.api.address_tuple,
self.fhdhr.app.wsgi_app,
log=self.fhdhr.logger.logger,
error_log=self.fhdhr.logger.logger)
log=self.fhdhr.logger)
try:
self.http.serve_forever()
self.stop()

View File

@ -1,9 +1,6 @@
from flask import Response, request, redirect
import urllib.parse
import json
import datetime
from fHDHR.tools import humanized_time, channel_sort
class EPG():
@ -42,76 +39,7 @@ class EPG():
epgdict[chan_obj.number]["id"] = chan_obj.dict["origin_id"]
epgdict[chan_obj.number]["thumbnail"] = chan_obj.thumbnail
# Sort the channels
sorted_channel_list = channel_sort(list(epgdict.keys()))
sorted_chan_guide = {}
for channel in sorted_channel_list:
sorted_chan_guide[channel] = epgdict[channel]
epg_json = json.dumps(sorted_chan_guide, indent=4)
return Response(status=200,
response=epg_json,
mimetype='application/json')
elif method == "current":
nowtime = datetime.datetime.utcnow().timestamp()
chan_guide_list = []
whatson = self.fhdhr.device.epg.whats_on_allchans(source)
# Sort the channels
sorted_channel_list = channel_sort(list(whatson.keys()))
sorted_chan_guide = {}
for channel in sorted_channel_list:
sorted_chan_guide[channel] = whatson[channel]
for channel in list(sorted_chan_guide.keys()):
if sorted_chan_guide[channel]["listing"][0]["time_end"]:
remaining_time = humanized_time(sorted_chan_guide[channel]["listing"][0]["time_end"] - nowtime)
else:
remaining_time = "N/A"
chan_dict = {
"name": sorted_chan_guide[channel]["name"],
"number": sorted_chan_guide[channel]["number"],
"chan_thumbnail": sorted_chan_guide[channel]["thumbnail"],
"listing_title": sorted_chan_guide[channel]["listing"][0]["title"],
"listing_thumbnail": sorted_chan_guide[channel]["listing"][0]["thumbnail"],
"listing_description": sorted_chan_guide[channel]["listing"][0]["description"],
"listing_remaining_time": str(remaining_time)
}
for time_item in ["time_start", "time_end"]:
if not sorted_chan_guide[channel]["listing"][0][time_item]:
chan_dict["listing_%s" % time_item] = "N/A"
elif str(sorted_chan_guide[channel]["listing"][0][time_item]).endswith(tuple(["+0000", "+00:00"])):
chan_dict["listing_%s" % time_item] = str(sorted_chan_guide[channel]["listing"][0][time_item])
else:
chan_dict["listing_%s" % time_item] = str(datetime.datetime.fromtimestamp(sorted_chan_guide[channel]["listing"][0][time_item]))
if source in ["blocks", "origin", self.fhdhr.config.dict["main"]["dictpopname"]]:
chan_obj = self.fhdhr.device.channels.get_channel_obj("origin_id", sorted_chan_guide[channel]["id"])
chan_dict["name"] = chan_obj.dict["name"]
chan_dict["number"] = chan_obj.number
chan_dict["chan_thumbnail"] = chan_obj.thumbnail
chan_dict["enabled"] = chan_obj.dict["enabled"]
chan_dict["m3u_url"] = chan_obj.m3u_url
chan_dict["listing_thumbnail"] = chan_dict["listing_thumbnail"] or chan_obj.thumbnail
else:
if not chan_dict["listing_thumbnail"]:
chan_dict["listing_thumbnail"] = chan_dict["chan_thumbnail"]
if not chan_dict["listing_thumbnail"]:
chan_dict["listing_thumbnail"] = "/api/images?method=generate&type=channel&message=%s" % chan_dict["number"]
chan_guide_list.append(chan_dict)
epg_json = json.dumps(chan_guide_list, indent=4)
epg_json = json.dumps(epgdict, indent=4)
return Response(status=200,
response=epg_json,

View File

@ -16,6 +16,10 @@ class Tuners():
def __init__(self, fhdhr):
self.fhdhr = fhdhr
self.quality = self.fhdhr.config.dict["streaming"]["quality"]
if self.quality:
self.quality = str(self.quality).lower()
def __call__(self, *args):
return self.get(*args)
@ -25,7 +29,7 @@ class Tuners():
accessed_url = request.args.get('accessed', default=request.url, type=str)
method = request.args.get('method', default=self.fhdhr.config.dict["streaming"]["method"], type=str)
method = request.args.get('method', default=self.fhdhr.config.dict["fhdhr"]["stream_type"], type=str)
tuner_number = request.args.get('tuner', default=None, type=str)
@ -52,12 +56,12 @@ class Tuners():
duration = request.args.get('duration', default=0, type=int)
transcode_quality = request.args.get('transcode', default=None, type=str)
transcode = request.args.get('transcode', default=self.quality, type=str)
valid_transcode_types = [
None, "high", "medium", "low"
"heavy", "mobile", "internet720", "internet480", "internet360", "internet240"
]
if transcode_quality not in valid_transcode_types:
if transcode not in valid_transcode_types:
response = Response("Service Unavailable", status=503)
response.headers["X-fHDHR-Error"] = "802 - Unknown Transcode Profile"
self.fhdhr.logger.error(response.headers["X-fHDHR-Error"])
@ -67,8 +71,7 @@ class Tuners():
"channel": channel_number,
"method": method,
"duration": duration,
"origin_quality": self.fhdhr.config.dict["streaming"]["origin_quality"],
"transcode_quality": transcode_quality,
"transcode": transcode,
"accessed": accessed_url,
"client": client_address,
"client_id": session["session_id"]

View File

@ -14,7 +14,7 @@ class Auto():
def get(self, channel, *args):
method = request.args.get('method', default=self.fhdhr.config.dict["streaming"]["method"], type=str)
method = request.args.get('method', default=self.fhdhr.config.dict["fhdhr"]["stream_type"], type=str)
redirect_url = "/api/tuners?method=%s" % (method)
@ -36,9 +36,9 @@ class Auto():
if duration:
redirect_url += "&duration=%s" % str(duration)
transcode_quality = request.args.get('transcode', default=None, type=str)
if transcode_quality:
redirect_url += "&transcode=%s" % str(transcode_quality)
transcode = request.args.get('transcode', default=None, type=str)
if transcode:
redirect_url += "&transcode=%s" % str(transcode)
redirect_url += "&accessed=%s" % urllib.parse.quote(request.url)

View File

@ -14,7 +14,7 @@ class Tuner():
def get(self, tuner_number, channel, *args):
method = request.args.get('method', default=self.fhdhr.config.dict["streaming"]["method"], type=str)
method = request.args.get('method', default=self.fhdhr.config.dict["fhdhr"]["stream_type"], type=str)
redirect_url = "/api/tuners?method=%s" % (method)
@ -38,9 +38,9 @@ class Tuner():
if duration:
redirect_url += "&duration=%s" % str(duration)
transcode_quality = request.args.get('transcode', default=None, type=str)
if transcode_quality:
redirect_url += "&transcode=%s" % str(transcode_quality)
transcode = request.args.get('transcode', default=None, type=str)
if transcode:
redirect_url += "&transcode=%s" % str(transcode)
redirect_url += "&accessed=%s" % urllib.parse.quote(request.url)

View File

@ -18,7 +18,7 @@ class RMG_Devices_DeviceKey_Media():
param = request.args.get('method', default=None, type=str)
self.fhdhr.logger.debug("param:%s" % param)
method = self.fhdhr.config.dict["streaming"]["method"]
method = self.fhdhr.config.dict["fhdhr"]["stream_type"]
redirect_url = "/api/tuners?method=%s" % (method)