mirror of
https://github.com/fHDHR/fHDHR_NextPVR.git
synced 2025-12-06 16:26:57 -05:00
126 lines
5.4 KiB
Python
126 lines
5.4 KiB
Python
from flask import Response, request, redirect, abort, stream_with_context
|
|
import urllib.parse
|
|
import uuid
|
|
|
|
from fHDHR.exceptions import TunerError
|
|
|
|
|
|
class Tuners():
|
|
endpoints = ["/api/tuners"]
|
|
endpoint_name = "api_tuners"
|
|
endpoint_methods = ["GET", "POST"]
|
|
|
|
def __init__(self, fhdhr):
|
|
self.fhdhr = fhdhr
|
|
|
|
def __call__(self, *args):
|
|
return self.get(*args)
|
|
|
|
def get(self, *args):
|
|
|
|
client_address = request.remote_addr
|
|
|
|
accessed_url = request.args.get('accessed', default=request.url, type=str)
|
|
|
|
method = request.args.get('method', default=self.fhdhr.config.dict["fhdhr"]["stream_type"], type=str)
|
|
|
|
tuner_number = request.args.get('tuner', None, type=str)
|
|
|
|
redirect_url = request.args.get('redirect', default=None, type=str)
|
|
|
|
if method in ["direct", "ffmpeg", "vlc"]:
|
|
|
|
channel_number = request.args.get('channel', None, type=str)
|
|
if not channel_number:
|
|
return "Missing Channel"
|
|
|
|
if str(channel_number) not in [str(x) for x in self.fhdhr.device.channels.get_channel_list("number")]:
|
|
response = Response("Not Found", status=404)
|
|
response.headers["X-fHDHR-Error"] = "801 - Unknown Channel"
|
|
self.fhdhr.logger.error(response.headers["X-fHDHR-Error"])
|
|
abort(response)
|
|
|
|
channel_dict = self.fhdhr.device.channels.get_channel_dict("number", channel_number)
|
|
if not channel_dict["enabled"]:
|
|
response = Response("Service Unavailable", status=503)
|
|
response.headers["X-fHDHR-Error"] = str("806 - Tune Failed")
|
|
self.fhdhr.logger.error(response.headers["X-fHDHR-Error"])
|
|
abort(response)
|
|
|
|
duration = request.args.get('duration', default=0, type=int)
|
|
|
|
transcode = request.args.get('transcode', default=None, type=str)
|
|
valid_transcode_types = [None, "heavy", "mobile", "internet720", "internet480", "internet360", "internet240"]
|
|
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"])
|
|
abort(response)
|
|
|
|
stream_args = {
|
|
"channel": channel_number,
|
|
"method": method,
|
|
"duration": duration,
|
|
"transcode": transcode,
|
|
"accessed": accessed_url,
|
|
"client": client_address,
|
|
"client_id": str(client_address) + "_" + str(uuid.uuid4())
|
|
}
|
|
|
|
try:
|
|
if not tuner_number:
|
|
tunernum = self.fhdhr.device.tuners.first_available(channel_number)
|
|
else:
|
|
tunernum = self.fhdhr.device.tuners.tuner_grab(tuner_number, channel_number)
|
|
except TunerError as e:
|
|
self.fhdhr.logger.info("A %s stream request for channel %s was rejected due to %s"
|
|
% (stream_args["method"], str(stream_args["channel"]), str(e)))
|
|
response = Response("Service Unavailable", status=503)
|
|
response.headers["X-fHDHR-Error"] = str(e)
|
|
self.fhdhr.logger.error(response.headers["X-fHDHR-Error"])
|
|
abort(response)
|
|
tuner = self.fhdhr.device.tuners.tuners[str(tunernum)]
|
|
|
|
try:
|
|
stream_args = self.fhdhr.device.tuners.get_stream_info(stream_args)
|
|
except TunerError as e:
|
|
self.fhdhr.logger.info("A %s stream request for channel %s was rejected due to %s"
|
|
% (stream_args["method"], str(stream_args["channel"]), str(e)))
|
|
response = Response("Service Unavailable", status=503)
|
|
response.headers["X-fHDHR-Error"] = str(e)
|
|
self.fhdhr.logger.error(response.headers["X-fHDHR-Error"])
|
|
tuner.close()
|
|
abort(response)
|
|
|
|
self.fhdhr.logger.info("Tuner #" + str(tunernum) + " to be used for stream.")
|
|
tuner.set_status(stream_args)
|
|
|
|
if stream_args["method"] == "direct":
|
|
return Response(tuner.get_stream(stream_args, tuner), content_type=stream_args["content_type"], direct_passthrough=True)
|
|
elif stream_args["method"] in ["ffmpeg", "vlc"]:
|
|
return Response(stream_with_context(tuner.get_stream(stream_args, tuner)), mimetype=stream_args["content_type"])
|
|
|
|
elif method == "close":
|
|
|
|
if not tuner_number or str(tuner_number) not in list(self.fhdhr.device.tuners.tuners.keys()):
|
|
return "%s Invalid tuner" % str(tuner_number)
|
|
|
|
tuner = self.fhdhr.device.tuners.tuners[str(tuner_number)]
|
|
tuner.close()
|
|
|
|
elif method == "scan":
|
|
|
|
if not tuner_number:
|
|
self.fhdhr.device.tuners.tuner_scan()
|
|
else:
|
|
tuner = self.fhdhr.device.tuners.tuners[str(tuner_number)]
|
|
tuner.channel_scan()
|
|
|
|
else:
|
|
return "%s Invalid Method" % method
|
|
|
|
if redirect_url:
|
|
return redirect(redirect_url + "?retmessage=" + urllib.parse.quote("%s Success" % method))
|
|
else:
|
|
return "%s Success" % method
|