Repository: streamlink/streamlink

Issue:
Huomao plugin not work
<!--
Thanks for reporting a plugin issue!
USE THE TEMPLATE. Otherwise your plugin issue may be rejected.

First, see the contribution guidelines:
https://github.com/streamlink/streamlink/blob/master/CONTRIBUTING.md#contributing-to-streamlink

Also check the list of open and closed plugin issues:
https://github.com/streamlink/streamlink/issues?q=is%3Aissue+label%3A%22plugin+issue%22

Please see the text preview to avoid unnecessary formatting errors.
-->


## Plugin Issue

<!-- Replace [ ] with [x] in order to check the box -->
- [x] This is a plugin issue and I have read the contribution guidelines.


### Description
I found huomao plugin seems not work, i can use browser to watch stream but
streamlink says no playable stream


<!-- Explain the plugin issue as thoroughly as you can. -->


### Reproduction steps / Explicit stream URLs to test

<!-- How can we reproduce this? Please note the exact steps below using the list format supplied. If you need more steps please add them. -->

1. https://www.huomao.com/9755
2. https://www.huomao.com/777777
3. https://www.huomao.com/888


### Log output

<!--
TEXT LOG OUTPUT IS REQUIRED for a plugin issue!
Use the `--loglevel debug` parameter and avoid using parameters which suppress log output.
https://streamlink.github.io/cli.html#cmdoption-l

Make sure to **remove usernames and passwords**
You can copy the output to https://gist.github.com/ or paste it below.
-->

```
[cli][info] Found matching plugin huomao for URL https://www.huomao.com/888
[plugin.huomao][error] Failed to extract stream_info.
error: No playable streams found on this URL: https://www.huomao.com/888
```




Discussion:
gravyboat: Changes look good, thanks @qkolj.

Patch:
diff --git a/src/streamlink/plugins/huomao.py b/src/streamlink/plugins/huomao.py
index aee762b3..e0d5770f 100644
--- a/src/streamlink/plugins/huomao.py
+++ b/src/streamlink/plugins/huomao.py
@@ -4,8 +4,8 @@ simply extracts the videos stream_id, stream_url and stream_quality by
 scraping the HTML and JS of one of Huomaos mobile webpages.
 
 When viewing a stream on huomao.com, the base URL references a room_id. This
-room_id is mapped one-to-one to a stream_id which references the actual .flv
-video. Both stream_id, stream_url and stream_quality can be found in the
+room_id is mapped one-to-one to a stream_id which references the actual .m3u8
+file. Both stream_id, stream_url and stream_quality can be found in the
 HTML and JS source of the mobile_page. Since one stream can occur in many
 different qualities, we scrape all stream_url and stream_quality occurrences
 and return each option to the user.
@@ -14,7 +14,7 @@ and return each option to the user.
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.stream import HTTPStream
+from streamlink.stream import HLSStream
 
 # URL pattern for recognizing inputed Huomao.tv / Huomao.com URL.
 url_re = re.compile(r"""
@@ -35,18 +35,15 @@ mobile_url = "http://www.huomao.com/mobile/mob_live/{0}"
 #   <input id="html_stream" value="efmrCH" type="hidden">
 stream_id_pattern = re.compile(r'id=\"html_stream\" value=\"(?P<stream_id>\w+)\"')
 
-# Pattern for extracting each stream_url, stream_quality_url and a prettified
+# Pattern for extracting each stream_url and
 # stream_quality_name used for quality naming.
 #
 # Example from HTML:
-#   "2: 'http://live-ws.huomaotv.cn/live/'+stream+'_720/playlist.m3u8'"
+#   src="http://live-ws-hls.huomaotv.cn/live/<stream_id>_720/playlist.m3u8"
 stream_info_pattern = re.compile(r"""
-    [1-9]:
-    \s+
-    '(?P<stream_url>(?:\w|\.|:|-|/)+)
-    '\+stream\+'
-    (?P<stream_quality_url>_?(?P<stream_quality_name>\d*))
-    /playlist.m3u8'
+    (?P<stream_url>(?:[\w\/\.\-:]+)
+    \/[^_\"]+(?:_(?P<stream_quality_name>\d+))
+    ?/playlist.m3u8)
 """, re.VERBOSE)
 
 
@@ -65,11 +62,11 @@ class Huomao(Plugin):
         return stream_id.group("stream_id")
 
     def get_stream_info(self, html):
-        """Returns a nested list of different stream options.
+        """
+        Returns a nested list of different stream options.
 
-        Each entry in the list will contain a stream_url, stream_quality_url
-        and stream_quality_name for each stream occurrence that was found in
-        the JS.
+        Each entry in the list will contain a stream_url and stream_quality_name
+        for each stream occurrence that was found in the JS.
         """
         stream_info = stream_info_pattern.findall(html)
 
@@ -80,8 +77,8 @@ class Huomao(Plugin):
         # list and reassigning.
         stream_info_list = []
         for info in stream_info:
-            if not info[2]:
-                stream_info_list.append([info[0], info[1], "source"])
+            if not info[1]:
+                stream_info_list.append([info[0], "source"])
             else:
                 stream_info_list.append(list(info))
 
@@ -95,8 +92,8 @@ class Huomao(Plugin):
 
         streams = {}
         for info in stream_info:
-            streams[info[2]] = HTTPStream(self.session,
-                                          info[0] + stream_id + info[1] + ".flv")
+            if stream_id in info[0]:
+                streams[info[1]] = HLSStream(self.session, info[0])
 
         return streams
 


Test patch:
diff --git a/tests/plugins/test_huomao.py b/tests/plugins/test_huomao.py
index a27efdcb..1261680f 100644
--- a/tests/plugins/test_huomao.py
+++ b/tests/plugins/test_huomao.py
@@ -15,15 +15,12 @@ class TestPluginHuomao(unittest.TestCase):
         #   room_id             = 123456
         #   stream_id           = 9qsvyF24659
         #   stream_url          = http://live-ws.huomaotv.cn/live/
-        #   stream_quality      = source, _720 and _480
         #   stream_quality_name = source, 720 and 480
         self.mock_html = """
             <input id="html_stream" value="9qsvyF24659" type="hidden">
-            <!--            urls:{-->
-            <!--                1: 'http://live-ws.huomaotv.cn/live/'+stream+'/playlist.m3u8',-->
-            <!--                2: 'http://live-ws.huomaotv.cn/live/'+stream+'_720/playlist.m3u8',-->
-            <!--                3: 'http://live-ws.huomaotv.cn/live/'+stream+'_480/playlist.m3u8'-->
-            <!--            },-->
+            <source  src="http://live-ws-hls.huomaotv.cn/live/9qsvyF24659/playlist.m3u8">
+            <source  src="http://live-ws-hls.huomaotv.cn/live/9qsvyF24659_720/playlist.m3u8">
+            <source  src="http://live-ws-hls.huomaotv.cn/live/9qsvyF24659_480/playlist.m3u8">
         """
 
         # Create a mock Huomao object.
@@ -43,9 +40,9 @@ class TestPluginHuomao(unittest.TestCase):
         # Assert that the stream_url, stream_quality and stream_quality_name
         # is correctly extracted from the mock HTML.
         self.assertEqual(self.mock_huomao.get_stream_info(self.mock_html), [
-            ["http://live-ws.huomaotv.cn/live/", "", "source"],
-            ["http://live-ws.huomaotv.cn/live/", "_720", "720"],
-            ["http://live-ws.huomaotv.cn/live/", "_480", "480"]
+            ["http://live-ws-hls.huomaotv.cn/live/9qsvyF24659/playlist.m3u8", "source"],
+            ["http://live-ws-hls.huomaotv.cn/live/9qsvyF24659_720/playlist.m3u8", "720"],
+            ["http://live-ws-hls.huomaotv.cn/live/9qsvyF24659_480/playlist.m3u8", "480"]
         ])
 
     def test_can_handle_url(self):