We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
FILMON HLS Problem with Sat1 
- [x] This is a bug report.

### Description

The Channel Sat1 on Filmon can not be played with Streamlink

### Expected / Actual behavior

Normally all streams from FilmOn can be played via the streamlink. The channel Sat1 is played via the HLS protocol

### Reproduction steps / Explicit stream URLs to test

http://www.filmon.com/tv/sat-1-schweiz

### Logs

```
127.0.0.1 - - [25/Mar/2018 21:23:39] "GET /http://www.filmon.com/tv/rts-deux HTTP/1.1" 200 -
127.0.0.1 - - [25/Mar/2018 21:23:39] URL: http://www.filmon.com/tv/rts-deux Quality: best
[streamlinksrv][info] Streams:
[u'low', u'high', 'worst', 'best']
127.0.0.1 - - [25/Mar/2018 21:23:45] "GET /http://www.filmon.com/tv/sat-1-schweiz HTTP/1.1" 200 -
127.0.0.1 - - [25/Mar/2018 21:23:45] URL: http://www.filmon.com/tv/sat-1-schweiz Quality: best
[streamlinksrv][error] Plugin error: Unable to open URL: http://www.filmon.com/api-v2/channel/sat-1-schweiz?protocol=hls (404 Client Error: Not Found for url: http://www.filmon.com/api-v2/channel/sat-1-schweiz?protocol=hls)
[streamlinksrv][info] Closing currently open stream...
[streamlinksrv][error] Got exception: End Of Data!
```



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/streamlink/plugins/filmon.py`
Content:
```
1 import re
2 
3 import time
4 
5 from streamlink import StreamError
6 from streamlink.plugin import Plugin
7 from streamlink.plugin.api import http, validate
8 from streamlink.stream import HLSStream
9 
10 
11 class FilmOnHLS(HLSStream):
12     __shortname__ = "hls-filmon"
13 
14     def __init__(self, session_, channel=None, vod_id=None, quality="high", **args):
15         super(FilmOnHLS, self).__init__(session_, None, **args)
16         self.logger = self.session.logger.new_module("stream.hls-filmon")
17         self.channel = channel
18         self.vod_id = vod_id
19         if self.channel is None and self.vod_id is None:
20             raise ValueError("channel or vod_id must be set")
21         self.quality = quality
22         self.api = FilmOnAPI()
23         self._url = None
24         self.watch_timeout = 0
25 
26     def _get_stream_data(self):
27         if self.channel:
28             self.logger.debug("Reloading FilmOn channel playlist: {0}", self.channel)
29             data = self.api.channel(self.channel)
30             for stream in data["streams"]:
31                 yield stream
32         elif self.vod_id:
33             self.logger.debug("Reloading FilmOn VOD playlist: {0}", self.vod_id)
34             data = self.api.vod(self.vod_id)
35             for _, stream in data["streams"].items():
36                 yield stream
37 
38     @property
39     def url(self):
40         # If the watch timeout has passed then refresh the playlist from the API
41         if int(time.time()) >= self.watch_timeout:
42             for stream in self._get_stream_data():
43                 if stream["quality"] == self.quality:
44                     self.watch_timeout = int(time.time()) + stream["watch-timeout"]
45                     self._url = stream["url"]
46                     return self._url
47             raise StreamError("cannot refresh FilmOn HLS Stream playlist")
48         else:
49             return self._url
50 
51     def to_url(self):
52         url = self.url
53         expires = self.watch_timeout - time.time()
54         if expires < 0:
55             raise TypeError("Stream has expired and cannot be converted to a URL")
56         return url
57 
58 
59 class FilmOnAPI(object):
60     channel_url = "http://www.filmon.com/api-v2/channel/{0}?protocol=hls"
61     vod_url = "http://www.filmon.com/vod/info/{0}"
62 
63     stream_schema = {
64         "quality": validate.text,
65         "url": validate.url(),
66         "watch-timeout": int
67     }
68     api_schema = validate.Schema(
69         {
70             "data": {
71                 "streams": validate.any(
72                     {validate.text: stream_schema},
73                     [stream_schema]
74                 )
75             }
76         },
77         validate.get("data")
78     )
79 
80     def channel(self, channel):
81         res = http.get(self.channel_url.format(channel))
82         return http.json(res, schema=self.api_schema)
83 
84     def vod(self, vod_id):
85         res = http.get(self.vod_url.format(vod_id))
86         return http.json(res, schema=self.api_schema)
87 
88 
89 class Filmon(Plugin):
90     url_re = re.compile(r"""https?://(?:\w+\.)?filmon.(?:tv|com)/
91         (?:
92             (tv|channel)/(?P<channel>[^/]+)|
93             vod/view/(?P<vod_id>\d+)-|
94             group/
95         )
96     """, re.VERBOSE)
97 
98     _channel_id_re = re.compile(r'channel_id\s*?=\s*"(\d+)"')
99     _channel_id_schema = validate.Schema(
100         validate.transform(_channel_id_re.search),
101         validate.any(None, validate.get(1))
102     )
103 
104     quality_weights = {
105         "high": 720,
106         "low": 480
107     }
108 
109     def __init__(self, url):
110         super(Filmon, self).__init__(url)
111         self.api = FilmOnAPI()
112 
113     @classmethod
114     def can_handle_url(cls, url):
115         return cls.url_re.match(url) is not None
116 
117     @classmethod
118     def stream_weight(cls, key):
119         weight = cls.quality_weights.get(key)
120         if weight:
121             return weight, "filmon"
122 
123         return Plugin.stream_weight(key)
124 
125     def _get_streams(self):
126         url_m = self.url_re.match(self.url)
127 
128         channel = url_m and url_m.group("channel")
129         vod_id = url_m and url_m.group("vod_id")
130 
131         if vod_id:
132             data = self.api.vod(vod_id)
133             for _, stream in data["streams"].items():
134                 yield stream["quality"], FilmOnHLS(self.session, vod_id=vod_id, quality=stream["quality"])
135 
136         else:
137             if not channel:
138                 channel = http.get(self.url, schema=self._channel_id_schema)
139             data = self.api.channel(channel)
140             for stream in data["streams"]:
141                 yield stream["quality"], FilmOnHLS(self.session, channel=channel, quality=stream["quality"])
142 
143 
144 __plugin__ = Filmon
145
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/streamlink/plugins/filmon.py b/src/streamlink/plugins/filmon.py
--- a/src/streamlink/plugins/filmon.py
+++ b/src/streamlink/plugins/filmon.py
@@ -89,16 +89,17 @@
 class Filmon(Plugin):
     url_re = re.compile(r"""https?://(?:\w+\.)?filmon.(?:tv|com)/
         (?:
-            (tv|channel)/(?P<channel>[^/]+)|
+            tv/|
+            channel/(?P<channel>\d+)|
             vod/view/(?P<vod_id>\d+)-|
             group/
         )
     """, re.VERBOSE)
 
-    _channel_id_re = re.compile(r'channel_id\s*?=\s*"(\d+)"')
+    _channel_id_re = re.compile(r"""channel_id\s*=\s*(?P<quote>['"]?)(?P<value>\d+)(?P=quote)""")
     _channel_id_schema = validate.Schema(
         validate.transform(_channel_id_re.search),
-        validate.any(None, validate.get(1))
+        validate.any(None, validate.get("value"))
     )
 
     quality_weights = {
@@ -136,6 +137,7 @@
         else:
             if not channel:
                 channel = http.get(self.url, schema=self._channel_id_schema)
+                self.logger.debug("Found channel ID: {0}", channel)
             data = self.api.channel(channel)
             for stream in data["streams"]:
                 yield stream["quality"], FilmOnHLS(self.session, channel=channel, quality=stream["quality"])

{"golden_diff": "diff --git a/src/streamlink/plugins/filmon.py b/src/streamlink/plugins/filmon.py\n--- a/src/streamlink/plugins/filmon.py\n+++ b/src/streamlink/plugins/filmon.py\n@@ -89,16 +89,17 @@\n class Filmon(Plugin):\n     url_re = re.compile(r\"\"\"https?://(?:\\w+\\.)?filmon.(?:tv|com)/\n         (?:\n-            (tv|channel)/(?P<channel>[^/]+)|\n+            tv/|\n+            channel/(?P<channel>\\d+)|\n             vod/view/(?P<vod_id>\\d+)-|\n             group/\n         )\n     \"\"\", re.VERBOSE)\n \n-    _channel_id_re = re.compile(r'channel_id\\s*?=\\s*\"(\\d+)\"')\n+    _channel_id_re = re.compile(r\"\"\"channel_id\\s*=\\s*(?P<quote>['\"]?)(?P<value>\\d+)(?P=quote)\"\"\")\n     _channel_id_schema = validate.Schema(\n         validate.transform(_channel_id_re.search),\n-        validate.any(None, validate.get(1))\n+        validate.any(None, validate.get(\"value\"))\n     )\n \n     quality_weights = {\n@@ -136,6 +137,7 @@\n         else:\n             if not channel:\n                 channel = http.get(self.url, schema=self._channel_id_schema)\n+                self.logger.debug(\"Found channel ID: {0}\", channel)\n             data = self.api.channel(channel)\n             for stream in data[\"streams\"]:\n                 yield stream[\"quality\"], FilmOnHLS(self.session, channel=channel, quality=stream[\"quality\"])\n", "issue": "FILMON HLS Problem with Sat1 \n- [x] This is a bug report.\r\n\r\n### Description\r\n\r\nThe Channel Sat1 on Filmon can not be played with Streamlink\r\n\r\n### Expected / Actual behavior\r\n\r\nNormally all streams from FilmOn can be played via the streamlink. The channel Sat1 is played via the HLS protocol\r\n\r\n### Reproduction steps / Explicit stream URLs to test\r\n\r\nhttp://www.filmon.com/tv/sat-1-schweiz\r\n\r\n### Logs\r\n\r\n```\r\n127.0.0.1 - - [25/Mar/2018 21:23:39] \"GET /http://www.filmon.com/tv/rts-deux HTTP/1.1\" 200 -\r\n127.0.0.1 - - [25/Mar/2018 21:23:39] URL: http://www.filmon.com/tv/rts-deux Quality: best\r\n[streamlinksrv][info] Streams:\r\n[u'low', u'high', 'worst', 'best']\r\n127.0.0.1 - - [25/Mar/2018 21:23:45] \"GET /http://www.filmon.com/tv/sat-1-schweiz HTTP/1.1\" 200 -\r\n127.0.0.1 - - [25/Mar/2018 21:23:45] URL: http://www.filmon.com/tv/sat-1-schweiz Quality: best\r\n[streamlinksrv][error] Plugin error: Unable to open URL: http://www.filmon.com/api-v2/channel/sat-1-schweiz?protocol=hls (404 Client Error: Not Found for url: http://www.filmon.com/api-v2/channel/sat-1-schweiz?protocol=hls)\r\n[streamlinksrv][info] Closing currently open stream...\r\n[streamlinksrv][error] Got exception: End Of Data!\r\n```\r\n\r\n\n", "before_files": [{"content": "import re\n\nimport time\n\nfrom streamlink import StreamError\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http, validate\nfrom streamlink.stream import HLSStream\n\n\nclass FilmOnHLS(HLSStream):\n    __shortname__ = \"hls-filmon\"\n\n    def __init__(self, session_, channel=None, vod_id=None, quality=\"high\", **args):\n        super(FilmOnHLS, self).__init__(session_, None, **args)\n        self.logger = self.session.logger.new_module(\"stream.hls-filmon\")\n        self.channel = channel\n        self.vod_id = vod_id\n        if self.channel is None and self.vod_id is None:\n            raise ValueError(\"channel or vod_id must be set\")\n        self.quality = quality\n        self.api = FilmOnAPI()\n        self._url = None\n        self.watch_timeout = 0\n\n    def _get_stream_data(self):\n        if self.channel:\n            self.logger.debug(\"Reloading FilmOn channel playlist: {0}\", self.channel)\n            data = self.api.channel(self.channel)\n            for stream in data[\"streams\"]:\n                yield stream\n        elif self.vod_id:\n            self.logger.debug(\"Reloading FilmOn VOD playlist: {0}\", self.vod_id)\n            data = self.api.vod(self.vod_id)\n            for _, stream in data[\"streams\"].items():\n                yield stream\n\n    @property\n    def url(self):\n        # If the watch timeout has passed then refresh the playlist from the API\n        if int(time.time()) >= self.watch_timeout:\n            for stream in self._get_stream_data():\n                if stream[\"quality\"] == self.quality:\n                    self.watch_timeout = int(time.time()) + stream[\"watch-timeout\"]\n                    self._url = stream[\"url\"]\n                    return self._url\n            raise StreamError(\"cannot refresh FilmOn HLS Stream playlist\")\n        else:\n            return self._url\n\n    def to_url(self):\n        url = self.url\n        expires = self.watch_timeout - time.time()\n        if expires < 0:\n            raise TypeError(\"Stream has expired and cannot be converted to a URL\")\n        return url\n\n\nclass FilmOnAPI(object):\n    channel_url = \"http://www.filmon.com/api-v2/channel/{0}?protocol=hls\"\n    vod_url = \"http://www.filmon.com/vod/info/{0}\"\n\n    stream_schema = {\n        \"quality\": validate.text,\n        \"url\": validate.url(),\n        \"watch-timeout\": int\n    }\n    api_schema = validate.Schema(\n        {\n            \"data\": {\n                \"streams\": validate.any(\n                    {validate.text: stream_schema},\n                    [stream_schema]\n                )\n            }\n        },\n        validate.get(\"data\")\n    )\n\n    def channel(self, channel):\n        res = http.get(self.channel_url.format(channel))\n        return http.json(res, schema=self.api_schema)\n\n    def vod(self, vod_id):\n        res = http.get(self.vod_url.format(vod_id))\n        return http.json(res, schema=self.api_schema)\n\n\nclass Filmon(Plugin):\n    url_re = re.compile(r\"\"\"https?://(?:\\w+\\.)?filmon.(?:tv|com)/\n        (?:\n            (tv|channel)/(?P<channel>[^/]+)|\n            vod/view/(?P<vod_id>\\d+)-|\n            group/\n        )\n    \"\"\", re.VERBOSE)\n\n    _channel_id_re = re.compile(r'channel_id\\s*?=\\s*\"(\\d+)\"')\n    _channel_id_schema = validate.Schema(\n        validate.transform(_channel_id_re.search),\n        validate.any(None, validate.get(1))\n    )\n\n    quality_weights = {\n        \"high\": 720,\n        \"low\": 480\n    }\n\n    def __init__(self, url):\n        super(Filmon, self).__init__(url)\n        self.api = FilmOnAPI()\n\n    @classmethod\n    def can_handle_url(cls, url):\n        return cls.url_re.match(url) is not None\n\n    @classmethod\n    def stream_weight(cls, key):\n        weight = cls.quality_weights.get(key)\n        if weight:\n            return weight, \"filmon\"\n\n        return Plugin.stream_weight(key)\n\n    def _get_streams(self):\n        url_m = self.url_re.match(self.url)\n\n        channel = url_m and url_m.group(\"channel\")\n        vod_id = url_m and url_m.group(\"vod_id\")\n\n        if vod_id:\n            data = self.api.vod(vod_id)\n            for _, stream in data[\"streams\"].items():\n                yield stream[\"quality\"], FilmOnHLS(self.session, vod_id=vod_id, quality=stream[\"quality\"])\n\n        else:\n            if not channel:\n                channel = http.get(self.url, schema=self._channel_id_schema)\n            data = self.api.channel(channel)\n            for stream in data[\"streams\"]:\n                yield stream[\"quality\"], FilmOnHLS(self.session, channel=channel, quality=stream[\"quality\"])\n\n\n__plugin__ = Filmon\n", "path": "src/streamlink/plugins/filmon.py"}], "after_files": [{"content": "import re\n\nimport time\n\nfrom streamlink import StreamError\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http, validate\nfrom streamlink.stream import HLSStream\n\n\nclass FilmOnHLS(HLSStream):\n    __shortname__ = \"hls-filmon\"\n\n    def __init__(self, session_, channel=None, vod_id=None, quality=\"high\", **args):\n        super(FilmOnHLS, self).__init__(session_, None, **args)\n        self.logger = self.session.logger.new_module(\"stream.hls-filmon\")\n        self.channel = channel\n        self.vod_id = vod_id\n        if self.channel is None and self.vod_id is None:\n            raise ValueError(\"channel or vod_id must be set\")\n        self.quality = quality\n        self.api = FilmOnAPI()\n        self._url = None\n        self.watch_timeout = 0\n\n    def _get_stream_data(self):\n        if self.channel:\n            self.logger.debug(\"Reloading FilmOn channel playlist: {0}\", self.channel)\n            data = self.api.channel(self.channel)\n            for stream in data[\"streams\"]:\n                yield stream\n        elif self.vod_id:\n            self.logger.debug(\"Reloading FilmOn VOD playlist: {0}\", self.vod_id)\n            data = self.api.vod(self.vod_id)\n            for _, stream in data[\"streams\"].items():\n                yield stream\n\n    @property\n    def url(self):\n        # If the watch timeout has passed then refresh the playlist from the API\n        if int(time.time()) >= self.watch_timeout:\n            for stream in self._get_stream_data():\n                if stream[\"quality\"] == self.quality:\n                    self.watch_timeout = int(time.time()) + stream[\"watch-timeout\"]\n                    self._url = stream[\"url\"]\n                    return self._url\n            raise StreamError(\"cannot refresh FilmOn HLS Stream playlist\")\n        else:\n            return self._url\n\n    def to_url(self):\n        url = self.url\n        expires = self.watch_timeout - time.time()\n        if expires < 0:\n            raise TypeError(\"Stream has expired and cannot be converted to a URL\")\n        return url\n\n\nclass FilmOnAPI(object):\n    channel_url = \"http://www.filmon.com/api-v2/channel/{0}?protocol=hls\"\n    vod_url = \"http://www.filmon.com/vod/info/{0}\"\n\n    stream_schema = {\n        \"quality\": validate.text,\n        \"url\": validate.url(),\n        \"watch-timeout\": int\n    }\n    api_schema = validate.Schema(\n        {\n            \"data\": {\n                \"streams\": validate.any(\n                    {validate.text: stream_schema},\n                    [stream_schema]\n                )\n            }\n        },\n        validate.get(\"data\")\n    )\n\n    def channel(self, channel):\n        res = http.get(self.channel_url.format(channel))\n        return http.json(res, schema=self.api_schema)\n\n    def vod(self, vod_id):\n        res = http.get(self.vod_url.format(vod_id))\n        return http.json(res, schema=self.api_schema)\n\n\nclass Filmon(Plugin):\n    url_re = re.compile(r\"\"\"https?://(?:\\w+\\.)?filmon.(?:tv|com)/\n        (?:\n            tv/|\n            channel/(?P<channel>\\d+)|\n            vod/view/(?P<vod_id>\\d+)-|\n            group/\n        )\n    \"\"\", re.VERBOSE)\n\n    _channel_id_re = re.compile(r\"\"\"channel_id\\s*=\\s*(?P<quote>['\"]?)(?P<value>\\d+)(?P=quote)\"\"\")\n    _channel_id_schema = validate.Schema(\n        validate.transform(_channel_id_re.search),\n        validate.any(None, validate.get(\"value\"))\n    )\n\n    quality_weights = {\n        \"high\": 720,\n        \"low\": 480\n    }\n\n    def __init__(self, url):\n        super(Filmon, self).__init__(url)\n        self.api = FilmOnAPI()\n\n    @classmethod\n    def can_handle_url(cls, url):\n        return cls.url_re.match(url) is not None\n\n    @classmethod\n    def stream_weight(cls, key):\n        weight = cls.quality_weights.get(key)\n        if weight:\n            return weight, \"filmon\"\n\n        return Plugin.stream_weight(key)\n\n    def _get_streams(self):\n        url_m = self.url_re.match(self.url)\n\n        channel = url_m and url_m.group(\"channel\")\n        vod_id = url_m and url_m.group(\"vod_id\")\n\n        if vod_id:\n            data = self.api.vod(vod_id)\n            for _, stream in data[\"streams\"].items():\n                yield stream[\"quality\"], FilmOnHLS(self.session, vod_id=vod_id, quality=stream[\"quality\"])\n\n        else:\n            if not channel:\n                channel = http.get(self.url, schema=self._channel_id_schema)\n                self.logger.debug(\"Found channel ID: {0}\", channel)\n            data = self.api.channel(channel)\n            for stream in data[\"streams\"]:\n                yield stream[\"quality\"], FilmOnHLS(self.session, channel=channel, quality=stream[\"quality\"])\n\n\n__plugin__ = Filmon\n", "path": "src/streamlink/plugins/filmon.py"}]}