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

Merge pull request #35 from deathbybandaid/dev

Improve Tuner Grabbing
This commit is contained in:
Deathbybandaid 2020-10-14 19:32:00 -04:00 committed by GitHub
commit 17daf80b1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 26 deletions

View File

@ -4,7 +4,7 @@ class TunerError(Exception):
self.value = value self.value = value
def __str__(self): def __str__(self):
return 'LoginError: %s' % self.value return 'TunerError: %s' % self.value
class LoginError(Exception): class LoginError(Exception):

View File

@ -57,7 +57,7 @@ class HDHR_Hub():
return self.lineupjson.get_lineup_json(base_url) return self.lineupjson.get_lineup_json(base_url)
def get_debug_json(self, base_url): def get_debug_json(self, base_url):
return self.debug.get_debug_json(base_url, self.tuners.tuners) return self.debug.get_debug_json(base_url, self.tuners)
def get_html_error(self, message): def get_html_error(self, message):
return self.htmlerror.get_html_error(message) return self.htmlerror.get_html_error(message)
@ -184,6 +184,7 @@ class HDHR_HTTP_Server():
"channel": channel.replace('v', ''), "channel": channel.replace('v', ''),
"method": request.args.get('method', default=hdhr.config.dict["fhdhr"]["stream_type"], type=str), "method": request.args.get('method', default=hdhr.config.dict["fhdhr"]["stream_type"], type=str),
"duration": request.args.get('duration', default=0, type=int), "duration": request.args.get('duration', default=0, type=int),
"accessed": str(request.headers["host"]) + str(request.url_rule),
} }
stream_args = hdhr.get_stream_info(stream_args) stream_args = hdhr.get_stream_info(stream_args)
if stream_args["channelUri"]: if stream_args["channelUri"]:

View File

@ -10,7 +10,7 @@ class Debug_JSON():
def get_debug_json(self, base_url, tuners): def get_debug_json(self, base_url, tuners):
debugjson = { debugjson = {
"base_url": base_url, "base_url": base_url,
"available tuners": tuners, "total channels": self.origserv.get_station_total(),
"total channels": self.origserv.get_station_total() "tuner status": tuners.status(),
} }
return json.dumps(debugjson, indent=4) return json.dumps(debugjson, indent=4)

View File

@ -3,24 +3,75 @@ import threading
from fHDHR.fHDHRerrors import TunerError from fHDHR.fHDHRerrors import TunerError
class Tuner():
def __init__(self, inum):
self.number = inum
self.tuner_lock = threading.Lock()
self.status = {}
def grab(self, stream_args):
if self.tuner_lock.locked():
raise TunerError("Tuner #" + str(self.number) + " is not available.")
print("Tuner #" + str(self.number) + " to be used for stream.")
self.tuner_lock.acquire()
self.status = {
"status": "Active",
"method": stream_args["method"],
"accessed": stream_args["accessed"],
"proxied_url": stream_args["channelUri"],
}
def close(self):
print("Tuner #" + str(self.number) + " Shutting Down.")
self.status = {}
self.tuner_lock.release()
def get_status(self):
if not self.tuner_lock.locked():
return {"status": "Inactive"}
return self.status
class Tuners(): class Tuners():
def __init__(self, settings): def __init__(self, settings):
self.config = settings self.config = settings
self.max_tuners = int(self.config.dict["fhdhr"]["tuner_count"]) self.max_tuners = int(self.config.dict["fhdhr"]["tuner_count"])
self.tuners = self.max_tuners
self.tuner_lock = threading.Lock()
def tuner_grab(self): for i in range(1, self.max_tuners + 1):
self.tuner_lock.acquire() exec("%s = %s" % ("self.tuner_" + str(i), "Tuner(i)"))
if self.tuners == 0:
self.tuner_lock.release() def tuner_grab(self, stream_args, tunernum=None):
tunerselected = None
if tunernum:
if tunernum not in range(1, self.max_tuners + 1):
raise TunerError("Tuner " + str(tunernum) + " does not exist.")
eval("self.tuner_" + str(tunernum) + ".grab(stream_args)")
tunerselected = tunernum
else:
for tunernum in range(1, self.max_tuners + 1):
try:
eval("self.tuner_" + str(tunernum) + ".grab(stream_args)")
except TunerError:
continue
else:
tunerselected = tunernum
break
if not tunerselected:
raise TunerError("No Available Tuners.") raise TunerError("No Available Tuners.")
self.tuners -= 1 else:
self.tuner_lock.release() return tunerselected
def tuner_close(self): def tuner_close(self, tunernum):
self.tuner_lock.acquire() eval("self.tuner_" + str(tunernum) + ".close()")
self.tuners += 1
self.tuner_lock.release() def status(self):
all_status = {}
for tunernum in range(1, self.max_tuners + 1):
all_status[tunernum] = eval("self.tuner_" + str(tunernum) + ".get_status()")
return all_status

View File

@ -13,7 +13,7 @@ class WatchStream():
self.tuners = tuners self.tuners = tuners
self.web = fHDHR.tools.WebReq() self.web = fHDHR.tools.WebReq()
def direct_stream(self, stream_args): def direct_stream(self, stream_args, tunernum):
chunksize = int(self.tuners.config.dict["direct_stream"]['chunksize']) chunksize = int(self.tuners.config.dict["direct_stream"]['chunksize'])
@ -36,11 +36,11 @@ class WatchStream():
except GeneratorExit: except GeneratorExit:
req.close() req.close()
print("Connection Closed.") print("Connection Closed.")
self.tuners.tuner_close() self.tuners.tuner_close(tunernum)
return generate() return generate()
def ffmpeg_stream(self, stream_args): def ffmpeg_stream(self, stream_args, tunernum):
bytes_per_read = int(self.config.dict["ffmpeg"]["bytes_per_read"]) bytes_per_read = int(self.config.dict["ffmpeg"]["bytes_per_read"])
@ -84,25 +84,25 @@ class WatchStream():
ffmpeg_proc.terminate() ffmpeg_proc.terminate()
ffmpeg_proc.communicate() ffmpeg_proc.communicate()
print("Connection Closed.") print("Connection Closed.")
self.tuners.tuner_close() self.tuners.tuner_close(tunernum)
return generate() return generate()
def get_stream(self, stream_args): def get_stream(self, stream_args):
try: try:
self.tuners.tuner_grab() tunernum = self.tuners.tuner_grab(stream_args)
except TunerError: except TunerError as e:
print("A " + stream_args["method"] + " stream request for channel " + print("A " + stream_args["method"] + " stream request for channel " +
str(stream_args["channel"]) + " was rejected do to a lack of available tuners.") str(stream_args["channel"]) + " was rejected do to " + str(e))
return return
print("Attempting a " + stream_args["method"] + " stream request for channel " + str(stream_args["channel"])) print("Attempting a " + stream_args["method"] + " stream request for channel " + str(stream_args["channel"]))
if stream_args["method"] == "ffmpeg": if stream_args["method"] == "ffmpeg":
return self.ffmpeg_stream(stream_args) return self.ffmpeg_stream(stream_args, tunernum)
elif stream_args["method"] == "direct": elif stream_args["method"] == "direct":
return self.direct_stream(stream_args) return self.direct_stream(stream_args, tunernum)
def get_stream_info(self, stream_args): def get_stream_info(self, stream_args):