Repository: streamlink/streamlink

Issue:
Problem with live.russia.tv
I have  Problem with the Plugin live.russia.tv : 
```
#SERVICE 4097:0:1:0:0:0:224:0:0:0:http%3a//127.0.0.1%3a8088/https%3a//live.russia.tv/index/index/channel_id/76:Москва 24 HD
#DESCRIPTION Москва 24 HD
#SERVICE 4097:0:1:0:0:0:449:0:0:0:http%3a//127.0.0.1%3a8088/https%3a//live.russia.tv/index/index/channel_id/1:Rossija 1 HD
#DESCRIPTION Rossija 1 HD
#SERVICE 4097:0:1:0:0:0:445:0:0:0:http%3a//127.0.0.1%3a8088/https%3a//live.russia.tv/index/index/channel_id/82:Rossija RTR HD
#DESCRIPTION Rossija RTR HD
#SERVICE 4097:0:1:0:0:0:447:0:0:0:http%3a//127.0.0.1%3a8088/https%3a//live.russia.tv/index/index/channel_id/3:Rossija 24 HD
#DESCRIPTION Rossija 24 HD
```
The Channels not working on streamlink - from PC work the channels ok.


Discussion:
You have not provided any logs, or an description of your set up. Please include the required information. 
I wanted to watch the following Russian channels via streramlink available at https://live.russia.tv:


Rossija 1
Mockba24
Rossiya RTR

and others available on this page. And then I pasted into the channel list and I have neither image nor sound - channels just do not work.
You have to provide the debug log which the issue template is asking for, otherwise it is impossible for anyone else to understand your issue. What you have posted is no Streamlink log output.

Here is the issue template again:
https://raw.githubusercontent.com/streamlink/streamlink/master/ISSUE_TEMPLATE.md

> And then I pasted into the channel list and I have neither image nor sound - channels just do not work.

?
Are you even using Streamlink, or are you using something else?

Resolving patch:
diff --git a/src/streamlink/plugins/live_russia_tv.py b/src/streamlink/plugins/live_russia_tv.py
--- a/src/streamlink/plugins/live_russia_tv.py
+++ b/src/streamlink/plugins/live_russia_tv.py
@@ -1,33 +1,81 @@
+import logging
 import re
+
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import http
-from streamlink.stream import HLSStream
+from streamlink.plugin.api import http, validate
+from streamlink.plugin.api.utils import itertags
+from streamlink.stream import HLSStream, HTTPStream
+
+log = logging.getLogger(__name__)
+
 
 class LiveRussia(Plugin):
-    url_re = re.compile(r"https?://(?:www.)?live.russia.tv/index/index/channel_id/")
-    iframe_re = re.compile(r"""<iframe[^>]*src=["']([^'"]+)["'][^>]*>""")
-    stream_re = re.compile(r"""window.pl.data.*m3u8":"(.*)"}.*};""")
+    url_re = re.compile(r"https?://(?:www\.|live\.)?russia.tv")
+    _data_re = re.compile(r"""window\.pl\.data\.([\w_]+)\s*=\s*['"]?(.*?)['"]?;""")
 
     @classmethod
     def can_handle_url(cls, url):
         return cls.url_re.match(url) is not None
 
+    def _get_iframe_url(self, url):
+        res = http.get(url)
+        for iframe in itertags(res.text, 'iframe'):
+            src = iframe.attributes.get("src")
+            if src:
+                return src
+
+    def _get_stream_info_url(self, url):
+        data = {}
+        res = http.get(url)
+        for m in self._data_re.finditer(res.text):
+            data[m.group(1)] = m.group(2)
+
+        log.debug("Got pl_data={0}".format(data))
+
+        if data:
+            if data["isVod"] == '0':
+                return "https:{domain}/iframe/datalive/id/{id}/sid/{sid}".format(**data)
+            else:
+                return "https:{domain}/iframe/datavideo/id/{id}/sid/{sid}".format(**data)
+
     def _get_streams(self):
-        res = http.get(self.url)
-        iframe_result = re.search(self.iframe_re, res.text)
+        iframe_url = self._get_iframe_url(self.url)
+
+        if iframe_url:
+            log.debug("Found iframe URL={0}".format(iframe_url))
+            info_url = self._get_stream_info_url(iframe_url)
+
+            if info_url:
+                log.debug("Getting info from URL: {0}".format(info_url))
+                res = http.get(info_url, headers={"Referer": iframe_url})
+                data = http.json(res)
+
+                if data['status'] == 200:
+                    for media in data['data']['playlist']['medialist']:
+                        if media['errors']:
+                            log.error(media['errors'].replace('\n', '').replace('\r', ''))
+
+                        for media_type in media.get('sources', []):
+
+                            if media_type == "m3u8":
+                                hls_url = media['sources'][media_type]['auto']
+                                for s in HLSStream.parse_variant_playlist(self.session, hls_url).items():
+                                    yield s
+
+                            if media_type == "http":
+                                for pix, url in media['sources'][media_type].items():
+                                    yield "{0}p".format(pix), HTTPStream(self.session, url)
+                else:
+                    log.error("An error occurred: {0}".format(data['errors'].replace('\n', '').replace('\r', '')))
+            else:
+                log.error("Unable to get stream info URL")
+        else:
+            log.error("Could not find video iframe")
+
 
-        if not iframe_result:
-            self.logger.error("The requested content is unavailable.")
-            return
 
-        res = http.get(iframe_result.group(1))
-        stream_url_result = re.search(self.stream_re, res.text)
 
-        if not stream_url_result:
-            self.logger.error("The requested content is unavailable.")
-            return
 
-        return HLSStream.parse_variant_playlist(self.session, stream_url_result.group(1))
 
 
-__plugin__ = LiveRussia
\ No newline at end of file
+__plugin__ = LiveRussia


Test patch:
diff --git a/tests/test_plugin_liverussiatv.py b/tests/test_plugin_liverussiatv.py
--- a/tests/test_plugin_liverussiatv.py
+++ b/tests/test_plugin_liverussiatv.py
@@ -2,12 +2,16 @@
 
 from streamlink.plugins.live_russia_tv import LiveRussia
 
+
 class TestPluginLiveRussiaTv(unittest.TestCase):
     def test_can_handle_url(self):
         # should match
         self.assertTrue(LiveRussia.can_handle_url('https://live.russia.tv/index/index/channel_id/1'))
         self.assertTrue(LiveRussia.can_handle_url('https://live.russia.tv/index/index/channel_id/199'))
+        self.assertTrue(LiveRussia.can_handle_url('https://live.russia.tv/'))
+        self.assertTrue(LiveRussia.can_handle_url('http://live.russia.tv/somethingelse'))
+        self.assertTrue(LiveRussia.can_handle_url('https://russia.tv/fifaworldcup/games/1832668/video/1800840'))
 
-        # shouldn't match
-        self.assertFalse(LiveRussia.can_handle_url('https://live.russia.tv/'))
-        self.assertFalse(LiveRussia.can_handle_url('http://live.russia.tv/wrongURI'))
\ No newline at end of file
+    def test_can_handle_url_negative(self):
+        self.assertFalse(LiveRussia.can_handle_url('http://live.france.tv/somethingelse'))
+        self.assertFalse(LiveRussia.can_handle_url('https://youtube.com/watch?v=4567uj'))