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)
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
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)
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 _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