Пример #1
0
    def tuner_scan(self):
        """Temporarily use a tuner for a scan"""
        if not self.available_tuner_count():
            raise TunerError("805 - All Tuners In Use")

        tunernumber = self.get_available_tuner()
        self.tuners[str(tunernumber)].channel_scan()

        if not tunernumber:
            raise TunerError("805 - All Tuners In Use")
Пример #2
0
    def first_available(self, origin, channel_number, dograb=True):

        if not self.available_tuner_count(origin):
            raise TunerError("805 - All Tuners In Use")

        tunernumber = self.get_available_tuner(origin)

        if not tunernumber:
            raise TunerError("805 - All Tuners In Use")
        else:
            self.tuners[origin][str(tunernumber)].grab(origin, channel_number)
            return tunernumber
Пример #3
0
    def first_available(self):

        if not self.available_tuner_count():
            raise TunerError("805 - All Tuners In Use")

        for tunernum in list(self.tuners.keys()):
            try:
                self.tuners[int(tunernum)].grab()
            except TunerError:
                continue
            else:
                return tunernum

        raise TunerError("805 - All Tuners In Use")
Пример #4
0
 def grab(self):
     if self.tuner_lock.locked():
         self.fhdhr.logger.error("Tuner #" + str(self.number) + " is not available.")
         raise TunerError("804 - Tuner In Use")
     self.tuner_lock.acquire()
     self.status["status"] = "Acquired"
     self.fhdhr.logger.info("Tuner #" + str(self.number) + " Acquired.")
Пример #5
0
    def __init__(self, fhdhr, stream_args, tuner):
        self.fhdhr = fhdhr
        self.stream_args = stream_args
        self.tuner = tuner

        if not os.path.isfile(self.stream_args["stream_info"]["url"]):
            raise TunerError("806 - Tune Failed: %s PATH does not seem to exist" % self.stream_args["stream_info"]["url"])
Пример #6
0
    def __init__(self, fhdhr, stream_args, tuner):
        self.fhdhr = fhdhr
        self.stream_args = stream_args
        self.tuner = tuner

        try:

            self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.udp_socket.bind((self.address, 0))
            self.udp_socket_address = self.udp_socket.getsockname()[0]
            self.udp_socket_port = self.udp_socket.getsockname()[1]
            self.udp_socket.settimeout(5)
            self.fhdhr.logger.info(
                "Created UDP socket at %s:%s." %
                (self.udp_socket_address, self.udp_socket_port))

        except Exception as exerror:
            error_out = self.fhdhr.logger.lazy_exception(
                exerror, "806 - Tune Failed")
            raise TunerError(error_out)

        finally:
            self.fhdhr.logger.info(
                "Closing UDP socket at %s:%s." %
                (self.udp_socket_address, self.udp_socket_port))
            self.udp_socket.close()
Пример #7
0
    def tuner_scan(self, origin="all"):
        """Temporarily use a tuner for a scan"""

        if origin == "all":
            origins = list(self.tuners.keys())
        else:
            origins = [origin]

        for origin in origins:

            if not self.available_tuner_count(origin):
                raise TunerError("805 - All Tuners In Use")

            tunernumber = self.get_available_tuner(origin)
            self.tuners[origin][str(tunernumber)].channel_scan(origin)

            if not tunernumber:
                raise TunerError("805 - All Tuners In Use")
Пример #8
0
    def __init__(self, fhdhr, plugin_utils, stream_args, tuner):
        self.fhdhr = fhdhr
        self.plugin_utils = plugin_utils
        self.stream_args = stream_args
        self.tuner = tuner

        if self.plugin_utils.versions.dict["vlc"]["version"] == "Missing":
            raise TunerError("806 - Tune Failed: VLC Missing")

        self.vlc_command = self.vlc_command_assemble(stream_args)
Пример #9
0
    def tuner_grab(self, tuner_number, origin, channel_number):

        if str(tuner_number) not in list(self.tuners[origin].keys()):
            self.fhdhr.logger.error("Tuner %s does not exist for %s." %
                                    (tuner_number, origin))
            raise TunerError("806 - Tune Failed")

        # TunerError will raise if unavailable
        self.tuners[origin][str(tuner_number)].grab(origin, channel_number)

        return tuner_number
Пример #10
0
 def grab(self, origin, channel_number):
     if self.tuner_lock.locked():
         self.fhdhr.logger.error("Tuner #%s is not available." %
                                 self.number)
         raise TunerError("804 - Tuner In Use")
     self.tuner_lock.acquire()
     self.status["status"] = "Acquired"
     self.status["origin"] = origin
     self.status["channel"] = channel_number
     self.status["time_start"] = datetime.datetime.utcnow()
     self.fhdhr.logger.info("Tuner #%s Acquired." % str(self.number))
Пример #11
0
    def __init__(self, fhdhr, plugin_utils, stream_args, tuner):
        self.fhdhr = fhdhr
        self.plugin_utils = plugin_utils
        self.stream_args = stream_args
        self.tuner = tuner

        if self.plugin_utils.config.internal["versions"]["ffmpeg"]["version"] == "Missing":
            raise TunerError("806 - Tune Failed: FFMPEG Missing")

        self.bytes_per_read = int(plugin_utils.config.dict["streaming"]["bytes_per_read"])
        self.ffmpeg_command = self.ffmpeg_command_assemble(stream_args)
Пример #12
0
    def tuner_grab(self, tuner_number):

        if int(tuner_number) not in list(self.tuners.keys()):
            self.fhdhr.logger.error("Tuner %s does not exist." %
                                    str(tuner_number))
            raise TunerError("806 - Tune Failed")

        # TunerError will raise if unavailable
        self.tuners[int(tuner_number)].grab()

        return tuner_number
Пример #13
0
    def __init__(self, fhdhr, plugin_utils, stream_args, tuner):
        self.fhdhr = fhdhr
        self.plugin_utils = plugin_utils
        self.stream_args = stream_args
        self.tuner = tuner

        if self.plugin_utils.versions.dict["webwatch_ffmpeg"][
                "version"] == "Missing":
            raise TunerError("806 - Tune Failed: FFMPEG Missing")

        self.bytes_per_read = 1024
        self.ffmpeg_command = self.ffmpeg_command_assemble(stream_args)
Пример #14
0
    def __init__(self, fhdhr, plugin_utils, stream_args, tuner):
        self.fhdhr = fhdhr
        self.plugin_utils = plugin_utils
        self.stream_args = stream_args
        self.tuner = tuner

        self.ffmpeg_path = self.plugin_utils.config.dict["ffmpeg"]["path"]
        self.buffsize = self.plugin_utils.config.dict["ffmpeg"]["buffsize"]

        if self.plugin_utils.versions.dict["ffmpeg"]["version"] == "Missing":
            raise TunerError("806 - Tune Failed: FFMPEG Missing")

        self.ffmpeg_command = self.ffmpeg_command_assemble(stream_args)
Пример #15
0
    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"],
            "time_start": datetime.datetime.utcnow(),
        }
Пример #16
0
    def get_stream_info(self, stream_args):

        stream_info = self.channels.get_channel_stream(stream_args,
                                                       stream_args["origin"])
        if not stream_info:
            raise TunerError("806 - Tune Failed")

        if isinstance(stream_info, str):
            stream_info = {"url": stream_info, "headers": None}
        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"
        else:

            channel_stream_url_headers = self.fhdhr.web.session.head(
                stream_args["stream_info"]["url"]).headers
            stream_args["true_content_type"] = channel_stream_url_headers[
                'Content-Type']

            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
Пример #17
0
    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.")
        else:
            return tunerselected
Пример #18
0
    def get_origin_stream_info(self):
        """
        Pull Stream Information from Origin Plugin
        """
        stream_info_defaults = {"headers": None}

        # Pull Stream Info from Origin Plugin
        self.fhdhr.logger.debug(
            "Attempting to gather stream information for %s channel %s %s %s."
            % (self.stream_args["origin_name"], self.stream_args["channel"],
               self.stream_args["channel_name"],
               self.stream_args["channel_callsign"]))

        stream_info = self.fhdhr.origins.origins_dict[
            self.stream_args["origin_name"]].get_channel_stream(
                self.chan_dict, self.stream_args)
        if not stream_info:
            raise TunerError("806 - Tune Failed")

        if not stream_info:
            raise TunerError("806 - Tune Failed")

        # Format Information from Origin Plugin
        if isinstance(stream_info, str):
            stream_info = {"url": stream_info}

        # Fail if no url present
        if not stream_info["url"]:
            raise TunerError("806 - Tune Failed")

        # Add keys/values to stream_info if missing
        for default_key in list(stream_info_defaults.keys()):
            if default_key not in list(stream_info.keys()):
                stream_info[default_key] = stream_info_defaults[default_key]

        self.stream_args["stream_info"] = stream_info
Пример #19
0
    def channel_scan(self, grabbed=False):
        if self.tuner_lock.locked() and not grabbed:
            self.fhdhr.logger.error("Tuner #%s is not available." % str(self.number))
            raise TunerError("804 - Tuner In Use")

        if self.status["status"] == "Scanning":
            self.fhdhr.logger.info("Channel Scan Already In Progress!")
        else:

            if not grabbed:
                self.tuner_lock.acquire()
            self.status["status"] = "Scanning"
            self.fhdhr.logger.info("Tuner #%s Performing Channel Scan." % str(self.number))

            chanscan = threading.Thread(target=self.runscan)
            chanscan.start()
Пример #20
0
    def get_stream_info(self, stream_args):

        stream_args["channelUri"] = self.channels.get_channel_stream(
            str(stream_args["channel"]))
        if not stream_args["channelUri"]:
            raise TunerError("806 - Tune Failed")

        channelUri_headers = self.fhdhr.web.session.head(
            stream_args["channelUri"]).headers
        stream_args["true_content_type"] = channelUri_headers['Content-Type']

        if stream_args["true_content_type"].startswith(
                tuple(["application/", "text/"])):
            stream_args["content_type"] = "video/mpeg"
        else:
            stream_args["content_type"] = stream_args["true_content_type"]

        return stream_args
Пример #21
0
    def channel_scan(self, origin, grabbed=False):
        if self.tuner_lock.locked() and not grabbed:
            self.fhdhr.logger.error("%s Tuner #%s is not available." %
                                    (self.origin, self.number))
            raise TunerError("804 - Tuner In Use")

        if self.status["status"] == "Scanning":
            self.fhdhr.logger.info("Channel Scan Already In Progress!")
        else:

            if not grabbed:
                self.tuner_lock.acquire()
            self.status["status"] = "Scanning"
            self.status["origin"] = origin
            self.status["time_start"] = datetime.datetime.utcnow()
            self.fhdhr.logger.info(
                "Tuner #%s Performing Channel Scan for %s origin." %
                (self.number, origin))

            chanscan = threading.Thread(target=self.runscan, args=(origin, ))
            chanscan.start()
Пример #22
0
    def validate_stream_url(self):
        """
        Validate Stream URL from Origin
        """

        # Make sure URL is not empty
        if "://" in self.stream_args["stream_info"]["url"]:
            if (not len(
                    self.stream_args["stream_info"]["url"].split("://")[-1])
                    or self.stream_args["stream_info"]["url"].split("://")[-1]
                    == "None"):
                raise TunerError("806 - Tune Failed")

        # Set parameters for HTTP/s protocols
        if self.stream_args["stream_info"]["url"].startswith(
                tuple(["http://", "https://"])):

            try:
                channel_stream_url_headers = self.fhdhr.web.session.head(
                    self.stream_args["stream_info"]["url"]).headers
                self.stream_args[
                    "true_content_type"] = channel_stream_url_headers[
                        'Content-Type']

            except self.fhdhr.web.exceptions.MissingSchema:
                raise TunerError("806 - Tune Failed")

            except self.fhdhr.web.exceptions.ConnectionError:
                raise TunerError("806 - Tune Failed")

            except KeyError:

                # Set for M3U8
                if self.stream_args["stream_info"]["url"].endswith(
                        tuple([".m3u8", ".m3u"])):
                    self.fhdhr.logger.warning(
                        "Stream Headers couldn't be properly determined, defaulting to application/text as content_type."
                    )
                    self.stream_args["true_content_type"] = "application/text"

                else:
                    self.fhdhr.logger.warning(
                        "Stream Headers couldn't be properly determined, defaulting to video/mpeg as content_type."
                    )
                    self.stream_args["true_content_type"] = "video/mpeg"

            if self.stream_args["true_content_type"].startswith(
                    tuple(["application/", "text/"])):

                self.stream_args["content_type"] = "video/mpeg"
                if self.stream_args["origin_quality"] != -1:
                    self.stream_args["stream_info"]["url"] = m3u8_quality(
                        self.fhdhr, self.stream_args)

            else:
                self.stream_args["content_type"] = self.stream_args[
                    "true_content_type"]

        # Set parameters for Hardware Devices
        elif self.stream_args["stream_info"]["url"].startswith(
                tuple(["/dev/", "file://dev/"])):
            # TODO some attempt to determine this information properly
            self.stream_args["true_content_type"] = "video/mpeg"

        # Set parameters for file://
        elif self.stream_args["stream_info"]["url"].startswith(
                tuple(["file://"])):

            # Set for M3U8
            if self.stream_args["stream_info"]["url"].endswith(
                    tuple([".m3u8", ".m3u"])):
                self.stream_args["true_content_type"] = "application/text"

            else:
                # TODO some attempt to determine this information properly
                self.stream_args["true_content_type"] = "video/mpeg"

        # Set parameters for RTP/s protocols
        elif self.stream_args["stream_info"]["url"].startswith(
                tuple(["rtp://", "rtsp://"])):
            # TODO some attempt to determine this information properly
            self.stream_args["true_content_type"] = "video/mpeg"

        # Set parameters for UDP protocol
        elif self.stream_args["stream_info"]["url"].startswith(
                tuple(["udp://"])):
            # TODO some attempt to determine this information properly
            self.stream_args["true_content_type"] = "video/mpeg"

        # Set parameters for fallback
        else:
            self.fhdhr.logger.warning(
                "Content Type couldn't be properly determined, defaulting to video/mpeg as content_type."
            )
            self.stream_args["true_content_type"] = "video/mpeg"

        if self.stream_args["true_content_type"].startswith(
                tuple(["application/", "text/"])):

            self.stream_args["content_type"] = "video/mpeg"
            if self.stream_args["origin_quality"] != -1:
                self.stream_args["stream_info"]["url"] = m3u8_quality(
                    self.fhdhr, self.stream_args)

        else:
            self.stream_args["content_type"] = self.stream_args[
                "true_content_type"]
Пример #23
0
    def stream_setup(self):

        if self.stream_obj.stream_args["method"] == "direct":

            # Select the HTTP stream method for HTTP/s addresses
            if (self.stream_obj.stream_args["stream_info"]["url"].startswith(tuple(["http://", "https://"]))
               and not self.stream_obj.stream_args["true_content_type"].startswith(tuple(["application/", "text/"]))):
                self.fhdhr.logger.info("Stream Method Detected as HTTP/s.")
                self.method = Direct_HTTP_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

            # Select the FILE method for file:// PATHS
            elif (self.stream_obj.stream_args["stream_info"]["url"].startswith(tuple(["file://"]))
                  and not self.stream_obj.stream_args["true_content_type"].startswith(tuple(["file://dev/"]))):
                self.fhdhr.logger.info("Stream Method Detected as file://.")
                self.method = Direct_FILE_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

            # Select the M3U8 stream method for hadnling M3U/8 streams
            elif self.stream_obj.stream_args["true_content_type"].startswith(tuple(["application/", "text/"])):
                self.fhdhr.logger.info("Stream Method Detected as M3U8.")
                self.method = Direct_M3U8_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

            # Select the RTP stream method for RTP/s addresses
            elif self.stream_obj.stream_args["stream_info"]["url"].startswith(tuple(["rtp://", "rtsp://"])):
                self.fhdhr.logger.info("Stream Method Detected as RTP/s.")
                self.method = Direct_RTP_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

            # Select the UDP stream method for UDP addresses
            elif self.stream_obj.stream_args["stream_info"]["url"].startswith(tuple(["udp://"])):
                self.fhdhr.logger.info("Stream Method Detected as UDP.")
                self.method = Direct_UDP_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

            # Select the HardWare stream method for /dev/ hardware devices
            elif self.stream_obj.stream_args["stream_info"]["url"].startswith(tuple(["/dev/", "file://dev/"])):
                self.fhdhr.logger.info("Stream Method Detected as a /dev/ hardware device.")
                self.method = Direct_HardWare_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

            # Select the Direct HTTP stream method as a fallback
            else:
                self.fhdhr.logger.warning("Stream Method couldn't be properly determined, defaulting to HTTP method.")
                self.method = Direct_HTTP_Stream(self.fhdhr, self.stream_obj.stream_args, self.tuner)

        else:

            if self.stream_obj.stream_args["method"] not in list(self.alt_stream_handlers.keys()):
                raise TunerError("806 - Tune Failed: %s Plugin Not Found." % self.stream_obj.stream_args["method"])

            stream_args = self.stream_obj.stream_args

            plugin = self.alt_stream_handlers[self.stream_obj.stream_args["method"]]
            plugin_utils = plugin.plugin_utils

            try:
                self.method = plugin.Plugin_OBJ(self.fhdhr, plugin_utils, stream_args, self.tuner)

            except TunerError as exerror:
                error_out = self.fhdhr.logger.lazy_exception(exerror, "Tuner Setup Failed")
                raise TunerError(error_out)

            except Exception as exerror:
                error_out = self.fhdhr.logger.lazy_exception(exerror, "Tuner Setup Failed (lazily handled)")
                raise TunerError(error_out)
Пример #24
0
    def __init__(self, fhdhr, stream_args, tuner):
        self.fhdhr = fhdhr
        self.stream_args = stream_args
        self.tuner = tuner

        self.fhdhr.logger.info("Attempting to create socket to listen on.")
        self.address = self.get_sock_address()
        if not self.address:
            raise TunerError("806 - Tune Failed: Could Not Create Socket")

        # TODO determine if the RTP stream is TCP or UDP

        try:
            self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.tcp_socket.bind((self.address, 0))
            self.tcp_socket_address = self.tcp_socket.getsockname()[0]
            self.tcp_socket_port = self.tcp_socket.getsockname()[1]
            self.fhdhr.logger.info(
                "Created TCP socket at %s:%s." %
                (self.tcp_socket_address, self.tcp_socket_port))

            self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.udp_socket.bind((self.address, 0))
            self.udp_socket_address = self.udp_socket.getsockname()[0]
            self.udp_socket_port = self.udp_socket.getsockname()[1]
            self.udp_socket.settimeout(5)
            self.fhdhr.logger.info(
                "Created UDP socket at %s:%s." %
                (self.udp_socket_address, self.udp_socket_port))

            credentials = "%s:%s" % (
                self.stream_args["stream_info"]["username"],
                self.stream_args["stream_info"]["password"])
            credentials_bytes = credentials.encode("ascii")
            credentials_base64_bytes = base64.b64encode(credentials_bytes)
            credentials_base64_string = credentials_base64_bytes.decode(
                "ascii")

            self.describe = "DESCRIBE %s RTSP/1.0\r\nCSeq: 2\r\nUser-Agent: python\r\nAccept: application/sdp\r\nAuthorization: Basic %s\r\n\r\n" % (
                self.stream_args["stream_info"]["url"],
                credentials_base64_string)
            self.setup = "SETUP %s/trackID=1 RTSP/1.0\r\nCSeq: 3\r\nUser-Agent: python\r\nTransport: RTP/AVP;unicast;client_port=%s\r\nAuthorization: Basic %s\r\n\r\n" % (
                self.stream_args["stream_info"]["url"], self.udp_socket_port,
                credentials_base64_string)

            self.fhdhr.logger.info("Connecting to Socket")
            self.tcp_socket.connect(
                (self.stream_args["stream_info"]["address"],
                 self.stream_args["stream_info"]["port"]))

            self.fhdhr.logger.info("Sending DESCRIBE")
            self.tcp_socket.send(self.describe.encode("utf-8"))
            recst = self.tcp_socket.recv(4096).decode()
            self.fhdhr.logger.info("Got response: %s" % recst)

            self.fhdhr.logger.info("Sending SETUP")
            self.tcp_socket.send(self.setup.encode("utf-8"))
            recst = self.tcp_socket.recv(4096).decode()
            self.fhdhr.logger.info("Got response: %s" % recst)

            self.sessionid = self.sessionid(recst)
            self.fhdhr.logger.info("SessionID=%s" % self.sessionid)
            self.play = "PLAY %s RTSP/1.0\r\nCSeq: 5\r\nUser-Agent: python\r\nSession: %s\r\nRange: npt=0.000-\r\nAuthorization: Basic %s\r\n\r\n" % (
                self.stream_args["stream_info"]["url"], self.sessionid,
                credentials_base64_string)

        except Exception as exerror:
            self.fhdhr.logger.info(
                "Closing UDP socket at %s:%s." %
                (self.udp_socket_address, self.udp_socket_port))
            self.udp_socket.close()
            self.fhdhr.logger.info(
                "Closing TCP socket at %s:%s." %
                (self.tcp_socket_address, self.tcp_socket_port))
            self.tcp_socket.close()
            error_out = self.fhdhr.logger.lazy_exception(
                exerror, "806 - Tune Failed: Could Not Create Socket")
            raise TunerError(error_out)