Repository: streamlink/streamlink
Pull request #699 (2017-03-12 16:37:41)

plugins.canlitv - Added new plugin canlitv
Most of the streams works, sometimes there are two iframes.
Just use the link from the iframe and it will works most of the time.

Works only for HLS streams, won't work if the HLS file is broken.

```
canlitv.com
http://www.canlitv.com/24-tv

canlitv.life
http://www.canlitv.life/trt-haber

canlitvlive.co
http://www.canlitvlive.co/izle/ntv.html

canlitvlive.live
http://www.canlitvlive.live/izle/atv.html

ecanlitvizle.net
http://www.ecanlitvizle.net/trt-1-izle/
```

Fixed streamlink/streamlink#145


Patch:
diff --git a/docs/plugin_matrix.rst b/docs/plugin_matrix.rst
index e3e4dfe2..6d1f6c80 100644
--- a/docs/plugin_matrix.rst
+++ b/docs/plugin_matrix.rst
@@ -39,6 +39,11 @@ btv                 btv.bg               Yes   No    Requires login, and geo-res
 canalplus           - canalplus.fr       Yes   Yes   Streams may be geo-restricted to France.
                     - c8.fr
                     - cstar.fr
+canlitv             - canlitv.com        Yes   --
+                    - canlitv.life
+                    - canlitvlive.co
+                    - canlitvlive.live
+                    - ecanlitvizle.net
 cdnbg               - tv.bnt.bg          Yes   No    Streams may be geo-restricted to Bulgaria.
                     - bgonair.bg
                     - kanal3.bg
diff --git a/src/streamlink/plugins/canlitv.py b/src/streamlink/plugins/canlitv.py
new file mode 100644
index 00000000..4ff9877b
--- /dev/null
+++ b/src/streamlink/plugins/canlitv.py
@@ -0,0 +1,61 @@
+import re
+
+from streamlink.plugin import Plugin
+from streamlink.plugin.api import http
+from streamlink.plugin.api import useragents
+from streamlink.stream import HLSStream
+
+EMBED_URL_1 = "http://www.canlitv.life/kanallar.php?kanal={0}"
+EMBED_URL_2 = "http://www.ecanlitvizle.net/embed.php?kanal={0}"
+
+_m3u8_re = re.compile(r"file:(?:\s+)?(?:\'|\")(?P<url>[^\"']+)(?:\'|\")")
+_url_re = re.compile(r"""http(s)?://(?:www\.)?(?P<domain>
+    canlitv\.(com|life)
+    |
+    canlitvlive\.(co|live)
+    |
+    ecanlitvizle\.net
+    )
+    /(izle/|(?:onizleme|tv)\.php\?kanal=)?
+    (?P<channel>[\w\-\=]+)""", re.VERBOSE)
+
+
+class Canlitv(Plugin):
+    @classmethod
+    def can_handle_url(cls, url):
+        return _url_re.match(url)
+
+    def _get_streams(self):
+        match = _url_re.match(self.url)
+        channel = match.group("channel")
+        domain = match.group("domain")
+
+        headers = {
+            "Referer": self.url,
+            "User-Agent": useragents.FIREFOX
+        }
+
+        if domain == "canlitv.life":
+            res = http.get(EMBED_URL_1.format(channel), headers=headers)
+        elif domain == "ecanlitvizle.net":
+            res = http.get(EMBED_URL_2.format(channel), headers=headers)
+        else:
+            res = http.get(self.url, headers=headers)
+
+        url_match = _m3u8_re.search(res.text)
+
+        if url_match:
+            hls_url = url_match.group("url")
+
+            self.logger.debug("Found URL: {0}".format(hls_url))
+
+            try:
+                s = []
+                for s in HLSStream.parse_variant_playlist(self.session, hls_url).items():
+                    yield s
+                if not s:
+                    yield "live", HLSStream(self.session, hls_url)
+            except IOError as err:
+                self.logger.error("Failed to extract streams: {0}", err)
+
+__plugin__ = Canlitv


Test patch:
diff --git a/tests/test_plugin_canlitv.py b/tests/test_plugin_canlitv.py
new file mode 100644
index 00000000..30c27155
--- /dev/null
+++ b/tests/test_plugin_canlitv.py
@@ -0,0 +1,18 @@
+import unittest
+
+from streamlink.plugins.canlitv import Canlitv
+
+
+class TestPluginCanlitv(unittest.TestCase):
+    def test_can_handle_url(self):
+        # should match
+        self.assertTrue(Canlitv.can_handle_url("http://www.canlitv.com/channel"))
+        self.assertTrue(Canlitv.can_handle_url("http://www.canlitv.life/channel"))
+        self.assertTrue(Canlitv.can_handle_url("http://www.canlitvlive.co/izle/channel.html"))
+        self.assertTrue(Canlitv.can_handle_url("http://www.canlitvlive.live/izle/channel.html"))
+        self.assertTrue(Canlitv.can_handle_url("http://www.ecanlitvizle.net/channel/"))
+        self.assertTrue(Canlitv.can_handle_url("http://www.ecanlitvizle.net/onizleme.php?kanal=channel"))
+        self.assertTrue(Canlitv.can_handle_url("http://www.ecanlitvizle.net/tv.php?kanal=channel"))
+        # shouldn't match
+        self.assertFalse(Canlitv.can_handle_url("http://www.canlitv.com"))
+        self.assertFalse(Canlitv.can_handle_url("http://www.ecanlitvizle.net"))