1
0
mirror of https://github.com/fHDHR/fHDHR_NextPVR.git synced 2025-12-06 15:26:57 -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
def __str__(self):
return 'LoginError: %s' % self.value
return 'TunerError: %s' % self.value
class LoginError(Exception):

View File

@ -57,7 +57,7 @@ class HDHR_Hub():
return self.lineupjson.get_lineup_json(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):
return self.htmlerror.get_html_error(message)
@ -184,6 +184,7 @@ class HDHR_HTTP_Server():
"channel": channel.replace('v', ''),
"method": request.args.get('method', default=hdhr.config.dict["fhdhr"]["stream_type"], type=str),
"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)
if stream_args["channelUri"]:

View File

@ -10,7 +10,7 @@ class Debug_JSON():
def get_debug_json(self, base_url, tuners):
debugjson = {
"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)

View File

@ -3,24 +3,75 @@ import threading
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():
def __init__(self, settings):
self.config = settings
self.max_tuners = int(self.config.dict["fhdhr"]["tuner_count"])
self.tuners = self.max_tuners
self.tuner_lock = threading.Lock()
def tuner_grab(self):
self.tuner_lock.acquire()
if self.tuners == 0:
self.tuner_lock.release()
for i in range(1, self.max_tuners + 1):
exec("%s = %s" % ("self.tuner_" + str(i), "Tuner(i)"))
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.")
self.tuners -= 1
self.tuner_lock.release()
else:
return tunerselected
def tuner_close(self):
self.tuner_lock.acquire()
self.tuners += 1
self.tuner_lock.release()
def tuner_close(self, tunernum):
eval("self.tuner_" + str(tunernum) + ".close()")
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.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'])
@ -36,11 +36,11 @@ class WatchStream():
except GeneratorExit:
req.close()
print("Connection Closed.")
self.tuners.tuner_close()
self.tuners.tuner_close(tunernum)
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"])
@ -84,25 +84,25 @@ class WatchStream():
ffmpeg_proc.terminate()
ffmpeg_proc.communicate()
print("Connection Closed.")
self.tuners.tuner_close()
self.tuners.tuner_close(tunernum)
return generate()
def get_stream(self, stream_args):
try:
self.tuners.tuner_grab()
except TunerError:
tunernum = self.tuners.tuner_grab(stream_args)
except TunerError as e:
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
print("Attempting a " + stream_args["method"] + " stream request for channel " + str(stream_args["channel"]))
if stream_args["method"] == "ffmpeg":
return self.ffmpeg_stream(stream_args)
return self.ffmpeg_stream(stream_args, tunernum)
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):