prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Plugin for Livestream.com not working right?  exit's quickly for hls and not at all for normal streams
  I am trying to get a live stream on livestreamer.com to work and i can't get it to play more then about 35 seconds...
  
  When I run this command:
  streamlink "http://livestream.com/Miraclenet/events/5004281" 270p --fifo --player omxplayer
  
  it gives me an error about an swf being needed.  When I run this command:
  streamlink "http://livestream.com/Miraclenet/events/5004281" 270p_hls --fifo --player omxplayer
  
  it will play the stream but just for about 35 seconds or so...  I kinda don't want to have to restart it every 35 seconds to watch this stream...  I'd like it to run until I stop it myself...
  
  Any help for this non-python, non-linux guy would be very helpful...
  
  btw, this is running on a Raspberry Pi.  Just got a nice little 7 inch lcd for it and set it up on my desk to be able to watch it while I work, but can't get it to play for long at a time...
  
  (edited to correct commands used)
  
  --- 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/livestream.py`
  Content:
  ```
  1 import re
  2 
  3 from streamlink.compat import urljoin
  4 from streamlink.plugin import Plugin
  5 from streamlink.plugin.api import http, validate
  6 from streamlink.plugin.api.utils import parse_json
  7 from streamlink.stream import AkamaiHDStream, HLSStream
  8 
  9 _url_re = re.compile("http(s)?://(www\.)?livestream.com/")
  10 _stream_config_schema = validate.Schema({
  11     "event": {
  12         "stream_info": validate.any({
  13             "is_live": bool,
  14             "qualities": [{
  15                 "bitrate": int,
  16                 "height": int
  17             }],
  18             validate.optional("play_url"): validate.url(scheme="http"),
  19             validate.optional("m3u8_url"): validate.url(
  20                 scheme="http",
  21                 path=validate.endswith(".m3u8")
  22             ),
  23         }, None)
  24     },
  25     validate.optional("playerUri"): validate.text
  26 })
  27 _smil_schema = validate.Schema(validate.union({
  28     "http_base": validate.all(
  29         validate.xml_find("{http://www.w3.org/2001/SMIL20/Language}head/"
  30                           "{http://www.w3.org/2001/SMIL20/Language}meta"
  31                           "[@name='httpBase']"),
  32         validate.xml_element(attrib={
  33             "content": validate.text
  34         }),
  35         validate.get("content")
  36     ),
  37     "videos": validate.all(
  38         validate.xml_findall("{http://www.w3.org/2001/SMIL20/Language}body/"
  39                              "{http://www.w3.org/2001/SMIL20/Language}switch/"
  40                              "{http://www.w3.org/2001/SMIL20/Language}video"),
  41         [
  42             validate.all(
  43                 validate.xml_element(attrib={
  44                     "src": validate.text,
  45                     "system-bitrate": validate.all(
  46                         validate.text,
  47                         validate.transform(int)
  48                     )
  49                 }),
  50                 validate.transform(
  51                     lambda e: (e.attrib["src"], e.attrib["system-bitrate"])
  52                 )
  53             )
  54         ],
  55     )
  56 }))
  57 
  58 
  59 class Livestream(Plugin):
  60     @classmethod
  61     def default_stream_types(cls, streams):
  62         return ["akamaihd", "hls"]
  63 
  64     @classmethod
  65     def can_handle_url(self, url):
  66         return _url_re.match(url)
  67 
  68     def _get_stream_info(self):
  69         res = http.get(self.url)
  70         match = re.search("window.config = ({.+})", res.text)
  71         if match:
  72             config = match.group(1)
  73             return parse_json(config, "config JSON",
  74                               schema=_stream_config_schema)
  75 
  76     def _parse_smil(self, url, swf_url):
  77         res = http.get(url)
  78         smil = http.xml(res, "SMIL config", schema=_smil_schema)
  79 
  80         for src, bitrate in smil["videos"]:
  81             url = urljoin(smil["http_base"], src)
  82             yield bitrate, AkamaiHDStream(self.session, url, swf=swf_url)
  83 
  84     def _get_streams(self):
  85         info = self._get_stream_info()
  86         if not info:
  87             return
  88 
  89         stream_info = info["event"]["stream_info"]
  90         if not (stream_info and stream_info["is_live"]):
  91             # Stream is not live
  92             return
  93 
  94         play_url = stream_info.get("play_url")
  95         if play_url:
  96             swf_url = info.get("playerUri")
  97             if swf_url:
  98                 if not swf_url.startswith("http"):
  99                     swf_url = "http://" + swf_url
  100 
  101                 # Work around broken SSL.
  102                 swf_url = swf_url.replace("https://", "http://")
  103 
  104             qualities = stream_info["qualities"]
  105             for bitrate, stream in self._parse_smil(play_url, swf_url):
  106                 name = "{0:d}k".format(int(bitrate / 1000))
  107                 for quality in qualities:
  108                     if quality["bitrate"] == bitrate:
  109                         name = "{0}p".format(quality["height"])
  110 
  111                 yield name, stream
  112 
  113         m3u8_url = stream_info.get("m3u8_url")
  114         if m3u8_url:
  115             streams = HLSStream.parse_variant_playlist(self.session, m3u8_url,
  116                                                        namekey="pixels")
  117             # TODO: Replace with "yield from" when dropping Python 2.
  118             for stream in streams.items():
  119                 yield stream
  120 
  121 __plugin__ = Livestream
  122
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/src/streamlink/plugins/livestream.py b/src/streamlink/plugins/livestream.py
  --- a/src/streamlink/plugins/livestream.py
  +++ b/src/streamlink/plugins/livestream.py
  @@ -22,7 +22,10 @@
               ),
           }, None)
       },
  -    validate.optional("playerUri"): validate.text
  +    validate.optional("playerUri"): validate.text,
  +    validate.optional("viewerPlusSwfUrl"): validate.url(scheme="http"),
  +    validate.optional("lsPlayerSwfUrl"): validate.text,
  +    validate.optional("hdPlayerSwfUrl"): validate.text
   })
   _smil_schema = validate.Schema(validate.union({
       "http_base": validate.all(
  @@ -93,7 +96,7 @@
   
           play_url = stream_info.get("play_url")
           if play_url:
  -            swf_url = info.get("playerUri")
  +            swf_url = info.get("playerUri") or info.get("hdPlayerSwfUrl") or info.get("lsPlayerSwfUrl") or info.get("viewerPlusSwfUrl")
               if swf_url:
                   if not swf_url.startswith("http"):
                       swf_url = "http://" + swf_url
  
verification_info: {"golden_diff": "diff --git a/src/streamlink/plugins/livestream.py b/src/streamlink/plugins/livestream.py\n--- a/src/streamlink/plugins/livestream.py\n+++ b/src/streamlink/plugins/livestream.py\n@@ -22,7 +22,10 @@\n             ),\n         }, None)\n     },\n-    validate.optional(\"playerUri\"): validate.text\n+    validate.optional(\"playerUri\"): validate.text,\n+    validate.optional(\"viewerPlusSwfUrl\"): validate.url(scheme=\"http\"),\n+    validate.optional(\"lsPlayerSwfUrl\"): validate.text,\n+    validate.optional(\"hdPlayerSwfUrl\"): validate.text\n })\n _smil_schema = validate.Schema(validate.union({\n     \"http_base\": validate.all(\n@@ -93,7 +96,7 @@\n \n         play_url = stream_info.get(\"play_url\")\n         if play_url:\n-            swf_url = info.get(\"playerUri\")\n+            swf_url = info.get(\"playerUri\") or info.get(\"hdPlayerSwfUrl\") or info.get(\"lsPlayerSwfUrl\") or info.get(\"viewerPlusSwfUrl\")\n             if swf_url:\n                 if not swf_url.startswith(\"http\"):\n                     swf_url = \"http://\" + swf_url\n", "issue": "Plugin for Livestream.com not working right?  exit's quickly for hls and not at all for normal streams\nI am trying to get a live stream on livestreamer.com to work and i can't get it to play more then about 35 seconds...\r\n\r\nWhen I run this command:\r\nstreamlink \"http://livestream.com/Miraclenet/events/5004281\" 270p --fifo --player omxplayer\r\n\r\nit gives me an error about an swf being needed.  When I run this command:\r\nstreamlink \"http://livestream.com/Miraclenet/events/5004281\" 270p_hls --fifo --player omxplayer\r\n\r\nit will play the stream but just for about 35 seconds or so...  I kinda don't want to have to restart it every 35 seconds to watch this stream...  I'd like it to run until I stop it myself...\r\n\r\nAny help for this non-python, non-linux guy would be very helpful...\r\n\r\nbtw, this is running on a Raspberry Pi.  Just got a nice little 7 inch lcd for it and set it up on my desk to be able to watch it while I work, but can't get it to play for long at a time...\r\n\r\n(edited to correct commands used)\n", "before_files": [{"content": "import re\n\nfrom streamlink.compat import urljoin\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http, validate\nfrom streamlink.plugin.api.utils import parse_json\nfrom streamlink.stream import AkamaiHDStream, HLSStream\n\n_url_re = re.compile(\"http(s)?://(www\\.)?livestream.com/\")\n_stream_config_schema = validate.Schema({\n    \"event\": {\n        \"stream_info\": validate.any({\n            \"is_live\": bool,\n            \"qualities\": [{\n                \"bitrate\": int,\n                \"height\": int\n            }],\n            validate.optional(\"play_url\"): validate.url(scheme=\"http\"),\n            validate.optional(\"m3u8_url\"): validate.url(\n                scheme=\"http\",\n                path=validate.endswith(\".m3u8\")\n            ),\n        }, None)\n    },\n    validate.optional(\"playerUri\"): validate.text\n})\n_smil_schema = validate.Schema(validate.union({\n    \"http_base\": validate.all(\n        validate.xml_find(\"{http://www.w3.org/2001/SMIL20/Language}head/\"\n                          \"{http://www.w3.org/2001/SMIL20/Language}meta\"\n                          \"[@name='httpBase']\"),\n        validate.xml_element(attrib={\n            \"content\": validate.text\n        }),\n        validate.get(\"content\")\n    ),\n    \"videos\": validate.all(\n        validate.xml_findall(\"{http://www.w3.org/2001/SMIL20/Language}body/\"\n                             \"{http://www.w3.org/2001/SMIL20/Language}switch/\"\n                             \"{http://www.w3.org/2001/SMIL20/Language}video\"),\n        [\n            validate.all(\n                validate.xml_element(attrib={\n                    \"src\": validate.text,\n                    \"system-bitrate\": validate.all(\n                        validate.text,\n                        validate.transform(int)\n                    )\n                }),\n                validate.transform(\n                    lambda e: (e.attrib[\"src\"], e.attrib[\"system-bitrate\"])\n                )\n            )\n        ],\n    )\n}))\n\n\nclass Livestream(Plugin):\n    @classmethod\n    def default_stream_types(cls, streams):\n        return [\"akamaihd\", \"hls\"]\n\n    @classmethod\n    def can_handle_url(self, url):\n        return _url_re.match(url)\n\n    def _get_stream_info(self):\n        res = http.get(self.url)\n        match = re.search(\"window.config = ({.+})\", res.text)\n        if match:\n            config = match.group(1)\n            return parse_json(config, \"config JSON\",\n                              schema=_stream_config_schema)\n\n    def _parse_smil(self, url, swf_url):\n        res = http.get(url)\n        smil = http.xml(res, \"SMIL config\", schema=_smil_schema)\n\n        for src, bitrate in smil[\"videos\"]:\n            url = urljoin(smil[\"http_base\"], src)\n            yield bitrate, AkamaiHDStream(self.session, url, swf=swf_url)\n\n    def _get_streams(self):\n        info = self._get_stream_info()\n        if not info:\n            return\n\n        stream_info = info[\"event\"][\"stream_info\"]\n        if not (stream_info and stream_info[\"is_live\"]):\n            # Stream is not live\n            return\n\n        play_url = stream_info.get(\"play_url\")\n        if play_url:\n            swf_url = info.get(\"playerUri\")\n            if swf_url:\n                if not swf_url.startswith(\"http\"):\n                    swf_url = \"http://\" + swf_url\n\n                # Work around broken SSL.\n                swf_url = swf_url.replace(\"https://\", \"http://\")\n\n            qualities = stream_info[\"qualities\"]\n            for bitrate, stream in self._parse_smil(play_url, swf_url):\n                name = \"{0:d}k\".format(int(bitrate / 1000))\n                for quality in qualities:\n                    if quality[\"bitrate\"] == bitrate:\n                        name = \"{0}p\".format(quality[\"height\"])\n\n                yield name, stream\n\n        m3u8_url = stream_info.get(\"m3u8_url\")\n        if m3u8_url:\n            streams = HLSStream.parse_variant_playlist(self.session, m3u8_url,\n                                                       namekey=\"pixels\")\n            # TODO: Replace with \"yield from\" when dropping Python 2.\n            for stream in streams.items():\n                yield stream\n\n__plugin__ = Livestream\n", "path": "src/streamlink/plugins/livestream.py"}], "after_files": [{"content": "import re\n\nfrom streamlink.compat import urljoin\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http, validate\nfrom streamlink.plugin.api.utils import parse_json\nfrom streamlink.stream import AkamaiHDStream, HLSStream\n\n_url_re = re.compile(\"http(s)?://(www\\.)?livestream.com/\")\n_stream_config_schema = validate.Schema({\n    \"event\": {\n        \"stream_info\": validate.any({\n            \"is_live\": bool,\n            \"qualities\": [{\n                \"bitrate\": int,\n                \"height\": int\n            }],\n            validate.optional(\"play_url\"): validate.url(scheme=\"http\"),\n            validate.optional(\"m3u8_url\"): validate.url(\n                scheme=\"http\",\n                path=validate.endswith(\".m3u8\")\n            ),\n        }, None)\n    },\n    validate.optional(\"playerUri\"): validate.text,\n    validate.optional(\"viewerPlusSwfUrl\"): validate.url(scheme=\"http\"),\n    validate.optional(\"lsPlayerSwfUrl\"): validate.text,\n    validate.optional(\"hdPlayerSwfUrl\"): validate.text\n})\n_smil_schema = validate.Schema(validate.union({\n    \"http_base\": validate.all(\n        validate.xml_find(\"{http://www.w3.org/2001/SMIL20/Language}head/\"\n                          \"{http://www.w3.org/2001/SMIL20/Language}meta\"\n                          \"[@name='httpBase']\"),\n        validate.xml_element(attrib={\n            \"content\": validate.text\n        }),\n        validate.get(\"content\")\n    ),\n    \"videos\": validate.all(\n        validate.xml_findall(\"{http://www.w3.org/2001/SMIL20/Language}body/\"\n                             \"{http://www.w3.org/2001/SMIL20/Language}switch/\"\n                             \"{http://www.w3.org/2001/SMIL20/Language}video\"),\n        [\n            validate.all(\n                validate.xml_element(attrib={\n                    \"src\": validate.text,\n                    \"system-bitrate\": validate.all(\n                        validate.text,\n                        validate.transform(int)\n                    )\n                }),\n                validate.transform(\n                    lambda e: (e.attrib[\"src\"], e.attrib[\"system-bitrate\"])\n                )\n            )\n        ],\n    )\n}))\n\n\nclass Livestream(Plugin):\n    @classmethod\n    def default_stream_types(cls, streams):\n        return [\"akamaihd\", \"hls\"]\n\n    @classmethod\n    def can_handle_url(self, url):\n        return _url_re.match(url)\n\n    def _get_stream_info(self):\n        res = http.get(self.url)\n        match = re.search(\"window.config = ({.+})\", res.text)\n        if match:\n            config = match.group(1)\n            return parse_json(config, \"config JSON\",\n                              schema=_stream_config_schema)\n\n    def _parse_smil(self, url, swf_url):\n        res = http.get(url)\n        smil = http.xml(res, \"SMIL config\", schema=_smil_schema)\n\n        for src, bitrate in smil[\"videos\"]:\n            url = urljoin(smil[\"http_base\"], src)\n            yield bitrate, AkamaiHDStream(self.session, url, swf=swf_url)\n\n    def _get_streams(self):\n        info = self._get_stream_info()\n        if not info:\n            return\n\n        stream_info = info[\"event\"][\"stream_info\"]\n        if not (stream_info and stream_info[\"is_live\"]):\n            # Stream is not live\n            return\n\n        play_url = stream_info.get(\"play_url\")\n        if play_url:\n            swf_url = info.get(\"playerUri\") or info.get(\"hdPlayerSwfUrl\") or info.get(\"lsPlayerSwfUrl\") or info.get(\"viewerPlusSwfUrl\")\n            if swf_url:\n                if not swf_url.startswith(\"http\"):\n                    swf_url = \"http://\" + swf_url\n\n                # Work around broken SSL.\n                swf_url = swf_url.replace(\"https://\", \"http://\")\n\n            qualities = stream_info[\"qualities\"]\n            for bitrate, stream in self._parse_smil(play_url, swf_url):\n                name = \"{0:d}k\".format(int(bitrate / 1000))\n                for quality in qualities:\n                    if quality[\"bitrate\"] == bitrate:\n                        name = \"{0}p\".format(quality[\"height\"])\n\n                yield name, stream\n\n        m3u8_url = stream_info.get(\"m3u8_url\")\n        if m3u8_url:\n            streams = HLSStream.parse_variant_playlist(self.session, m3u8_url,\n                                                       namekey=\"pixels\")\n            # TODO: Replace with \"yield from\" when dropping Python 2.\n            for stream in streams.items():\n                yield stream\n\n__plugin__ = Livestream\n", "path": "src/streamlink/plugins/livestream.py"}]}