Exemple #1
0
    def _get_video_streams(self):
        self.logger.debug("Getting video steams for {0} (type={1})".format(
            self.video_id, self.video_type))
        self._authenticate()

        if self.video_type == "b":
            self.video_type = "a"

        try:
            videos = self.api.videos(self.video_type + self.video_id,
                                     schema=_video_schema)
        except PluginError as err:
            if "HTTP/1.1 0 ERROR" in str(err):
                raise NoStreamsError(self.url)
            else:
                raise

        # Parse the "t" query parameter on broadcasts and adjust
        # start offset if needed.
        time_offset = self.params.get("t")
        if time_offset:
            try:
                time_offset = hours_minutes_seconds(time_offset)
            except ValueError:
                time_offset = 0

            videos["start_offset"] += time_offset

        return self._create_playlist_streams(videos)
Exemple #2
0
    def _get_hls_streams(self, url, restricted_bitrates, **extra_params):
        time_offset = self.params.get("t", 0)
        if time_offset:
            try:
                time_offset = hours_minutes_seconds(time_offset)
            except ValueError:
                time_offset = 0

        try:
            streams = TwitchHLSStream.parse_variant_playlist(
                self.session, url, start_offset=time_offset, **extra_params)
        except OSError as err:
            err = str(err)
            if "404 Client Error" in err or "Failed to parse playlist" in err:
                return
            else:
                raise PluginError(err)

        for name in restricted_bitrates:
            if name not in streams:
                log.warning(
                    "The quality '{0}' is not available since it requires a subscription."
                    .format(name))

        return streams
Exemple #3
0
    def _get_video_streams(self):
        self.logger.debug("Getting video steams for {0} (type={1})".format(self.video_id, self.video_type))
        self._authenticate()

        if self.video_type == "b":
            self.video_type = "a"

        try:
            videos = self.api.videos(self.video_type + self.video_id,
                                     schema=_video_schema)
        except PluginError as err:
            if "HTTP/1.1 0 ERROR" in str(err):
                raise NoStreamsError(self.url)
            else:
                raise

        # Parse the "t" query parameter on broadcasts and adjust
        # start offset if needed.
        time_offset = self.params.get("t")
        if time_offset:
            try:
                time_offset = hours_minutes_seconds(time_offset)
            except ValueError:
                time_offset = 0

            videos["start_offset"] += time_offset

        return self._create_playlist_streams(videos)
Exemple #4
0
    def _get_hls_streams(self, stream_type="live"):
        self.logger.debug("Getting {0} HLS streams for {1}".format(
            stream_type, self.channel))
        self._authenticate()
        self._hosted_chain.append(self.channel)

        if stream_type == "live":
            hosted_channel = self._check_for_host()
            if hosted_channel and self.options.get("disable_hosting"):
                self.logger.info("hosting was disabled by command line option")
            elif hosted_channel:
                self.logger.info("switching to {0}", hosted_channel)
                if hosted_channel in self._hosted_chain:
                    self.logger.error(
                        u"A loop of hosted channels has been detected, "
                        "cannot find a playable stream. ({0})".format(
                            u" -> ".join(self._hosted_chain +
                                         [hosted_channel])))
                    return {}
                self.channel = hosted_channel
                return self._get_hls_streams(stream_type)

            # only get the token once the channel has been resolved
            sig, token = self._access_token(stream_type)
            url = self.usher.channel(self.channel,
                                     sig=sig,
                                     token=token,
                                     fast_bread=True)
        elif stream_type == "video":
            sig, token = self._access_token(stream_type)
            url = self.usher.video(self.video_id, nauthsig=sig, nauth=token)
        else:
            self.logger.debug(
                "Unknown HLS stream type: {0}".format(stream_type))
            return {}

        time_offset = self.params.get("t", 0)
        if time_offset:
            try:
                time_offset = hours_minutes_seconds(time_offset)
            except ValueError:
                time_offset = 0

        try:
            # If the stream is a VOD that is still being recorded the stream should start at the
            # beginning of the recording
            streams = TwitchHLSStream.parse_variant_playlist(
                self.session,
                url,
                start_offset=time_offset,
                force_restart=not stream_type == "live")
        except IOError as err:
            err = str(err)
            if "404 Client Error" in err or "Failed to parse playlist" in err:
                return
            else:
                raise PluginError(err)

        try:
            token = parse_json(token, schema=_token_schema)
            for name in token["restricted_bitrates"]:
                if name not in streams:
                    self.logger.warning(
                        "The quality '{0}' is not available "
                        "since it requires a subscription.", name)
        except PluginError:
            pass

        return streams
    def test_hours_minutes_seconds(self):
        self.assertEqual(hours_minutes_seconds("00:01:30"), 90)
        self.assertEqual(hours_minutes_seconds("01:20:15"), 4815)
        self.assertEqual(hours_minutes_seconds("26:00:00"), 93600)

        self.assertEqual(hours_minutes_seconds("07"), 7)
        self.assertEqual(hours_minutes_seconds("444"), 444)
        self.assertEqual(hours_minutes_seconds("8888"), 8888)

        self.assertEqual(hours_minutes_seconds("01h"), 3600)
        self.assertEqual(hours_minutes_seconds("01h22m33s"), 4953)
        self.assertEqual(hours_minutes_seconds("01H22M37S"), 4957)
        self.assertEqual(hours_minutes_seconds("01h30s"), 3630)
        self.assertEqual(hours_minutes_seconds("1m33s"), 93)
        self.assertEqual(hours_minutes_seconds("55s"), 55)

        self.assertEqual(hours_minutes_seconds("-00:01:40"), 100)
        self.assertEqual(hours_minutes_seconds("-00h02m30s"), 150)

        self.assertEqual(hours_minutes_seconds("02:04"), 124)
        self.assertEqual(hours_minutes_seconds("1:10"), 70)
        self.assertEqual(hours_minutes_seconds("10:00"), 600)

        with self.assertRaises(ValueError):
            hours_minutes_seconds("FOO")

        with self.assertRaises(ValueError):
            hours_minutes_seconds("BAR")

        with self.assertRaises(ValueError):
            hours_minutes_seconds("11:ERR:00")
    def test_hours_minutes_seconds(self):
        self.assertEqual(hours_minutes_seconds("00:01:30"), 90)
        self.assertEqual(hours_minutes_seconds("01:20:15"), 4815)
        self.assertEqual(hours_minutes_seconds("26:00:00"), 93600)

        self.assertEqual(hours_minutes_seconds("07"), 7)
        self.assertEqual(hours_minutes_seconds("444"), 444)
        self.assertEqual(hours_minutes_seconds("8888"), 8888)

        self.assertEqual(hours_minutes_seconds("01h"), 3600)
        self.assertEqual(hours_minutes_seconds("01h22m33s"), 4953)
        self.assertEqual(hours_minutes_seconds("01H22M37S"), 4957)
        self.assertEqual(hours_minutes_seconds("01h30s"), 3630)
        self.assertEqual(hours_minutes_seconds("1m33s"), 93)
        self.assertEqual(hours_minutes_seconds("55s"), 55)

        self.assertEqual(hours_minutes_seconds("-00:01:40"), 100)
        self.assertEqual(hours_minutes_seconds("-00h02m30s"), 150)

        self.assertEqual(hours_minutes_seconds("02:04"), 124)
        self.assertEqual(hours_minutes_seconds("1:10"), 70)
        self.assertEqual(hours_minutes_seconds("10:00"), 600)


        with self.assertRaises(ValueError):
            hours_minutes_seconds("FOO")

        with self.assertRaises(ValueError):
            hours_minutes_seconds("BAR")

        with self.assertRaises(ValueError):
            hours_minutes_seconds("11:ERR:00")
Exemple #7
0
    def _get_hls_streams(self, stream_type="live"):
        self.logger.debug("Getting {0} HLS streams for {1}".format(stream_type, self.channel))
        self._authenticate()
        self._hosted_chain.append(self.channel)

        if stream_type == "live":
            hosted_channel = self._check_for_host()
            if hosted_channel and self.options.get("disable_hosting"):
                self.logger.info("hosting was disabled by command line option")
            elif hosted_channel:
                self.logger.info("switching to {0}", hosted_channel)
                if hosted_channel in self._hosted_chain:
                    self.logger.error(
                        u"A loop of hosted channels has been detected, "
                        "cannot find a playable stream. ({0})".format(
                            u" -> ".join(self._hosted_chain + [hosted_channel])))
                    return {}
                self.channel = hosted_channel
                return self._get_hls_streams(stream_type)

            # only get the token once the channel has been resolved
            sig, token = self._access_token(stream_type)
            url = self.usher.channel(self.channel, sig=sig, token=token, fast_bread=True)
        elif stream_type == "video":
            sig, token = self._access_token(stream_type)
            url = self.usher.video(self.video_id, nauthsig=sig, nauth=token)
        else:
            self.logger.debug("Unknown HLS stream type: {0}".format(stream_type))
            return {}

        time_offset = self.params.get("t", 0)
        if time_offset:
            try:
                time_offset = hours_minutes_seconds(time_offset)
            except ValueError:
                time_offset = 0

        try:
            # If the stream is a VOD that is still being recorded the stream should start at the
            # beginning of the recording
            streams = HLSStream.parse_variant_playlist(self.session, url,
                                                       start_offset=time_offset,
                                                       force_restart=not stream_type == "live")
        except IOError as err:
            err = str(err)
            if "404 Client Error" in err or "Failed to parse playlist" in err:
                return
            else:
                raise PluginError(err)

        try:
            token = parse_json(token, schema=_token_schema)
            for name in token["restricted_bitrates"]:
                if name not in streams:
                    self.logger.warning("The quality '{0}' is not available "
                                        "since it requires a subscription.",
                                        name)
        except PluginError:
            pass

        return streams