Repository: streamlink/streamlink
Pull request #841 (2017-04-25 19:42:16)

[tv1channel.org] New plugin and some changes on [oldlivestream]
Some changes on **oldlivestream** so it will work for **tv1channel**

**oldlivestream**
- Support for `cdn` subdomains
- Support for `embed/` streams

**tv1channel**
- New Plugin for embeded streams on tv1channel.org _(youtube.com and livestream.com)_


Patch:
diff --git a/docs/plugin_matrix.rst b/docs/plugin_matrix.rst
index e9f00af2..ad566792 100644
--- a/docs/plugin_matrix.rst
+++ b/docs/plugin_matrix.rst
@@ -134,7 +134,8 @@ npo                 - npo.nl             Yes   Yes   Streams may be geo-restrict
                     - zappelin.nl
 nrk                 - tv.nrk.no          Yes   Yes   Streams may be geo-restricted to Norway.
                     - radio.nrk.no
-oldlivestream       original.liv... [3]_ Yes   No    Only mobile streams are supported.
+oldlivestream       - original.li.. [3]_ Yes   No    Only mobile streams are supported.
+                    - cdn.livestream.com
 openrectv           openrec.tv           Yes   Yes
 orf_tvthek          tvthek.orf.at        Yes   Yes
 ovvatv              ovva.tv              Yes   No
@@ -193,6 +194,7 @@ turkuvaz            - atv.com.tr         Yes   No
                     - aspor.com.tr
                     - minikago.com.tr
                     - minikacocuk.com.tr
+tv1channel          tv1channel.org       Yes   Yes
 tv3cat              tv3.cat              Yes   Yes   Streams may be geo-restricted to Spain.
 tv4play             - tv4play.se         Yes   Yes   Streams may be geo-restricted to Sweden.
                                                      Only non-premium streams currently supported.
diff --git a/src/streamlink/plugins/oldlivestream.py b/src/streamlink/plugins/oldlivestream.py
index 3170209a..7dfdaa6a 100644
--- a/src/streamlink/plugins/oldlivestream.py
+++ b/src/streamlink/plugins/oldlivestream.py
@@ -5,7 +5,7 @@ from streamlink.stream import HLSStream
 
 PLAYLIST_URL = "http://x{0}x.api.channel.livestream.com/3.0/playlist.m3u8"
 
-_url_re = re.compile(r"http(s)?://original.livestream.com/(?P<channel>[^&?/]+)")
+_url_re = re.compile(r"http(s)?://(cdn|original)\.livestream\.com/(embed/)?(?P<channel>[^&?/]+)")
 
 
 class OldLivestream(Plugin):
diff --git a/src/streamlink/plugins/tv1channel.py b/src/streamlink/plugins/tv1channel.py
new file mode 100644
index 00000000..377e4815
--- /dev/null
+++ b/src/streamlink/plugins/tv1channel.py
@@ -0,0 +1,26 @@
+import re
+
+from streamlink.plugin import Plugin
+from streamlink.plugin.api import http
+
+_url_re = re.compile(r'''https?://(www\.)?tv1channel\.org/''')
+_embed_re = re.compile(r'''<iframe.+src="([^"]+)"''')
+
+
+class TV1Channel(Plugin):
+    @classmethod
+    def can_handle_url(cls, url):
+        return _url_re.match(url)
+
+    def _get_streams(self):
+        res = http.get(self.url)
+        match = _embed_re.search(res.text)
+
+        if match:
+            url = match.group(1)
+            if url.startswith('//'):
+                url = 'https:{0}'.format(url)
+            return self.session.streams(url)
+
+
+__plugin__ = TV1Channel


Test patch:
diff --git a/tests/test_plugin_oldlivestream.py b/tests/test_plugin_oldlivestream.py
new file mode 100644
index 00000000..454b42e3
--- /dev/null
+++ b/tests/test_plugin_oldlivestream.py
@@ -0,0 +1,18 @@
+import unittest
+
+from streamlink.plugins.oldlivestream import OldLivestream
+
+
+class TestPluginOldLivestream(unittest.TestCase):
+    def test_can_handle_url(self):
+        # should match
+        self.assertTrue(OldLivestream.can_handle_url("https://cdn.livestream.com/embed/channel"))
+        self.assertTrue(OldLivestream.can_handle_url("https://original.livestream.com/embed/channel"))
+        self.assertTrue(OldLivestream.can_handle_url("https://original.livestream.com/channel"))
+
+        # shouldn't match
+        self.assertFalse(OldLivestream.can_handle_url("https://cdn.livestream.com"))
+        self.assertFalse(OldLivestream.can_handle_url("https://original.livestream.com"))
+        # other plugin livestream.py
+        self.assertFalse(OldLivestream.can_handle_url("https://livestream.com"))
+        self.assertFalse(OldLivestream.can_handle_url("https://www.livestream.com"))
diff --git a/tests/test_plugin_tv1channel.py b/tests/test_plugin_tv1channel.py
new file mode 100644
index 00000000..982c4259
--- /dev/null
+++ b/tests/test_plugin_tv1channel.py
@@ -0,0 +1,15 @@
+import unittest
+
+from streamlink.plugins.tv1channel import TV1Channel
+
+
+class TestPluginTV1Channel(unittest.TestCase):
+    def test_can_handle_url(self):
+        # should match
+        self.assertTrue(TV1Channel.can_handle_url("http://tv1channel.org/"))
+        self.assertTrue(TV1Channel.can_handle_url("http://tv1channel.org/index.php/livetv"))
+        self.assertTrue(TV1Channel.can_handle_url("http://www.tv1channel.org/play/video.php?id=325"))
+        self.assertTrue(TV1Channel.can_handle_url("http://www.tv1channel.org/play/video.php?id=340"))
+
+        # shouldn't match
+        self.assertFalse(TV1Channel.can_handle_url("https://local.local"))