Repository: streamlink/streamlink
Pull request #1224 (2017-09-15 21:00:32)

Add support for webcast.gov.in
As issued in https://github.com/streamlink/streamlink/issues/1222


Patch:
diff --git a/docs/plugin_matrix.rst b/docs/plugin_matrix.rst
index 4f2f1a8b..44fe7537 100644
--- a/docs/plugin_matrix.rst
+++ b/docs/plugin_matrix.rst
@@ -259,6 +259,7 @@ vidio               vidio.com            Yes   Yes
 vk                  vk.com               Yes   Yes
 vrtbe               vrt.be/vrtnu         Yes   Yes
 wattv               wat.tv               --    Yes
+webcast_india_gov   webcast.gov.in       Yes   No    You can use #Channel to indicate CH number.
 webtv               web.tv               Yes   --
 weeb                weeb.tv              Yes   --    Requires rtmpdump with K-S-V patches.
 wwenetwork          network.wwe.com      Yes   Yes   Requires an account to access any content.
diff --git a/script/makeinstaller.sh b/script/makeinstaller.sh
index 38b92e54..d2bc44bf 100755
--- a/script/makeinstaller.sh
+++ b/script/makeinstaller.sh
@@ -52,7 +52,7 @@ format=bundled
 ;           - certifi
 ;           - idna
 ;           - urllib3
-;           - socks / sockshandler
+;           - PySocks
 ;       - websocket-client
 packages=streamlink
          streamlink_cli
@@ -66,8 +66,6 @@ packages=streamlink
          chardet
          certifi
          websocket
-         socks
-         sockshandler
 pypi_wheels=pycryptodome==3.4.3
 
 files=../win32/LICENSE.txt > \$INSTDIR
diff --git a/src/streamlink/plugins/eltrecetv.py b/src/streamlink/plugins/eltrecetv.py
index 761eaa22..d922a3a7 100644
--- a/src/streamlink/plugins/eltrecetv.py
+++ b/src/streamlink/plugins/eltrecetv.py
@@ -1,8 +1,8 @@
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import http, useragents
-from streamlink.stream import HLSStream
+from streamlink.plugin.api import http, useragents, validate
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import parse_json
 
 class ElTreceTV(Plugin):
@@ -13,29 +13,27 @@ class ElTreceTV(Plugin):
         return cls._url_re.match(url)
 
     def _get_streams(self):
+
+        video_url_found_hls = ""
+
         if "eltrecetv.com.ar/vivo" in self.url.lower():
-            try:
-                http.headers = {'Referer': self.url,
-                'User-Agent': useragents.ANDROID}
-                res = http.get('https://api.iamat.com/metadata/atcodes/eltrece')
-                yt_id = parse_json(res.text)["atcodes"][0]["context"]["ahora"]["vivo"]["youtubeVideo"]
-                yt_url = "https://www.youtube.com/watch?v={0}".format(yt_id)
-                return self.session.streams(yt_url)
-            except:
-                self.logger.info("Live content is temporarily unavailable. Please try again later.")
+            http.headers = {'Referer': self.url,
+            'User-Agent': "ArtearPlayer/3.2.42 (Linux;Android 4.4.2) ExoPlayerLib/1.5.9"}
+            video_url_found_hls = "http://stream.eltrecetv.com.ar/live13/13tv/13tv1/playlist.m3u8"
         else:
-            try:
-                http.headers = {'Referer': self.url,
-                'User-Agent': useragents.CHROME}
-                res = http.get(self.url)
-                _player_re = re.compile(r'''data-kaltura="([^"]+)"''')
-                match = _player_re.search(res.text)
-                if not match:
-                    return
-                entry_id = parse_json(match.group(1).replace("&quot;", '"'))["entryId"]
-                hls_url = "https://vodgc.com/p/111/sp/11100/playManifest/entryId/{0}/format/applehttp/protocol/https/a.m3u8".format(entry_id)
-                return HLSStream.parse_variant_playlist(self.session, hls_url)
-            except:
-                self.logger.error("The requested VOD content is unavailable.")
+            http.headers = {'Referer': self.url,
+            'User-Agent': useragents.CHROME}
+            res = http.get(self.url)
+            _player_re = re.compile(r'''data-kaltura="([^"]+)"''')
+            match = _player_re.search(res.text)
+            if not match:
+                return
+            json_video_search = parse_json(match.group(1).replace("&quot;", '"'))
+            video_url_found_hls = "https://vodgc.com/p/111/sp/11100/playManifest/entryId/" + json_video_search["entryId"] + "/format/applehttp/protocol/https/a.m3u8"
+
+        if video_url_found_hls:
+            hls_streams = HLSStream.parse_variant_playlist(self.session, video_url_found_hls)
+            for s in hls_streams.items():
+                yield s
 
 __plugin__ = ElTreceTV
diff --git a/src/streamlink/plugins/webcast_india_gov.py b/src/streamlink/plugins/webcast_india_gov.py
new file mode 100644
index 00000000..4069fb09
--- /dev/null
+++ b/src/streamlink/plugins/webcast_india_gov.py
@@ -0,0 +1,29 @@
+import re
+
+from streamlink.plugin import Plugin
+from streamlink.plugin.api import http, useragents
+from streamlink.stream import HLSStream
+
+class WebcastIndiaGov(Plugin):
+    _url_re = re.compile(r'https?://(?:www\.)?webcast.gov.in/.+')
+
+    @classmethod
+    def can_handle_url(cls, url):
+        return cls._url_re.match(url)
+
+    def _get_streams(self):
+        try:
+            url_content = ""
+            http.headers = {'User-Agent': useragents.ANDROID}
+            if "#channel" in self.url.lower():
+                requested_channel = self.url.lower()[self.url.lower().index('#channel')+8 :]
+                url_content = http.get('http://webcast.gov.in/mobilevideo.asp?id=div' + requested_channel).text
+            else:
+                url_content = http.get(self.url).text
+            hls_url = url_content[: url_content.rindex('master.m3u8') +11]
+            hls_url = hls_url[hls_url.rindex('"')+1 :]
+            return HLSStream.parse_variant_playlist(self.session, hls_url)
+        except:
+            self.logger.error("The requested channel is unavailable.")
+
+__plugin__ = WebcastIndiaGov
\ No newline at end of file


Test patch:
diff --git a/tests/test_webcast_india_gov.py b/tests/test_webcast_india_gov.py
new file mode 100644
index 00000000..1790c127
--- /dev/null
+++ b/tests/test_webcast_india_gov.py
@@ -0,0 +1,16 @@
+import unittest
+
+from streamlink.plugins.webcast_india_gov import WebcastIndiaGov
+
+
+class TestPluginWebcastIndiaGov(unittest.TestCase):
+    def test_can_handle_url(self):
+        # should match
+        self.assertTrue(WebcastIndiaGov.can_handle_url("http://webcast.gov.in/ddpunjabi/"))
+        self.assertTrue(WebcastIndiaGov.can_handle_url("http://webcast.gov.in/#Channel1"))
+        self.assertTrue(WebcastIndiaGov.can_handle_url("http://webcast.gov.in/#Channel3"))
+
+        # shouldn't match
+        self.assertFalse(WebcastIndiaGov.can_handle_url("http://meity.gov.in/"))
+        self.assertFalse(WebcastIndiaGov.can_handle_url("http://www.nic.in/"))
+        self.assertFalse(WebcastIndiaGov.can_handle_url("http://digitalindiaawards.gov.in/"))
\ No newline at end of file