Repository: streamlink/streamlink
Pull request #2030 (2018-08-25 00:53:40)

Update steam plugin to work with steam.tv urls
See also:  #2020


Patch:
diff --git a/src/streamlink/plugins/steam.py b/src/streamlink/plugins/steam.py
index 6a5182ab..7c33470b 100644
--- a/src/streamlink/plugins/steam.py
+++ b/src/streamlink/plugins/steam.py
@@ -10,8 +10,10 @@ import streamlink
 from streamlink.exceptions import FatalPluginError
 from streamlink.plugin import Plugin, PluginArguments, PluginArgument
 from streamlink.plugin.api import validate
+from streamlink.plugin.api.utils import itertags, parse_json
 from streamlink.plugin.api.validate import Schema
 from streamlink.stream.dash import DASHStream
+from streamlink.compat import html_unescape
 
 log = logging.getLogger(__name__)
 
@@ -22,6 +24,8 @@ class SteamLoginFailed(Exception):
 
 class SteamBroadcastPlugin(Plugin):
     _url_re = re.compile(r"https?://steamcommunity.com/broadcast/watch/(\d+)")
+    _steamtv_url_re = re.compile(r"https?://steam.tv/(\w+)")
+    _watch_broadcast_url = "https://steamcommunity.com/broadcast/watch/"
     _get_broadcast_url = "https://steamcommunity.com/broadcast/getbroadcastmpd/"
     _user_agent = "streamlink/{}".format(streamlink.__version__)
     _broadcast_schema = Schema({
@@ -77,7 +81,7 @@ class SteamBroadcastPlugin(Plugin):
 
     @classmethod
     def can_handle_url(cls, url):
-        return cls._url_re.match(url) is not None
+        return cls._url_re.match(url) is not None or cls._steamtv_url_re.match(url) is not None
 
     @property
     def donotcache(self):
@@ -191,6 +195,16 @@ class SteamBroadcastPlugin(Plugin):
                 log.info("Logged in as {0}".format(self.get_option("email")))
                 self.save_cookies(lambda c: "steamMachineAuth" in c.name)
 
+        # Handle steam.tv URLs
+        if self._steamtv_url_re.match(self.url) is not None:
+            # extract the steam ID from the page
+            res = self.session.http.get(self.url)
+            for div in itertags(res.text, 'div'):
+                if div.attributes.get("id") == "webui_config":
+                    broadcast_data = html_unescape(div.attributes.get("data-broadcast"))
+                    steamid = parse_json(broadcast_data).get("steamid")
+                    self.url = self._watch_broadcast_url + steamid
+
         # extract the steam ID from the URL
         steamid = self._url_re.match(self.url).group(1)
         res = self.session.http.get(self.url)  # get the page to set some cookies


Test patch:
diff --git a/tests/plugins/test_steam.py b/tests/plugins/test_steam.py
index db16601f..0f362f1e 100644
--- a/tests/plugins/test_steam.py
+++ b/tests/plugins/test_steam.py
@@ -7,6 +7,8 @@ class TestPluginSteamBroadcastPlugin(unittest.TestCase):
     def test_can_handle_url(self):
         self.assertTrue(SteamBroadcastPlugin.can_handle_url('https://steamcommunity.com/broadcast/watch/12432432'))
         self.assertTrue(SteamBroadcastPlugin.can_handle_url('http://steamcommunity.com/broadcast/watch/342342'))
+        self.assertTrue(SteamBroadcastPlugin.can_handle_url('https://steam.tv/dota2'))
+        self.assertTrue(SteamBroadcastPlugin.can_handle_url('http://steam.tv/dota2'))
 
     def test_can_handle_url_negative(self):
         # shouldn't match