import re

from livestreamer.plugin import Plugin
from livestreamer.plugin.api import http, validate
from livestreamer.plugin.api.utils import parse_json
from livestreamer.stream import HDSStream, HLSStream

PLAYER_EMBED_URL = "http://www.majorleaguegaming.com/player/embed/{0}"
STREAM_API_URL = "http://streamapi.majorleaguegaming.com/service/streams/playback/{0}"
STREAM_TYPES = {
    "hls": HLSStream.parse_variant_playlist,
    "hds": HDSStream.parse_manifest
}

_stream_id_re = re.compile(r"<meta content='.+/([\w_-]+).+' property='og:video'>")
_player_config_re = re.compile(r"var playerConfig = (.+);")
_url_re = re.compile("http(s)?://(\w+\.)?(majorleaguegaming\.com|mlg\.tv)")

_player_config_schema = validate.Schema(
    {
        "media": {
            "stream_name": validate.text
        }
    },
    validate.get("media", {}),
    validate.get("stream_name")
)
_stream_schema = validate.Schema(
    {
        "data": {
            "items": validate.all(
                [{
                    "format": validate.text,
                    "url": validate.text
                }],
                validate.filter(lambda s: s["format"] in STREAM_TYPES)
            )
        }
    },
    validate.get("data", {}),
    validate.get("items", [])
)


class MLGTV(Plugin):
    @classmethod
    def can_handle_url(self, url):
        return _url_re.match(url)

    def _find_channel_id(self, text):
        match = _stream_id_re.search(text)
        if match:
            return match.group(1)

    def _find_stream_id(self, text):
        match = _player_config_re.search(text)
        if match:
            stream_id = parse_json(match.group(1),
                                   schema=_player_config_schema)
            return stream_id

    def _get_streams(self):
        res = http.get(self.url)
        channel_id = self._find_channel_id(res.text)
        if not channel_id:
            return

        res = http.get(PLAYER_EMBED_URL.format(channel_id))
        stream_id = self._find_stream_id(res.text)
        if not stream_id:
            return

        res = http.get(STREAM_API_URL.format(stream_id),
                       params=dict(format="all"))
        items = http.json(res, schema=_stream_schema)
        streams = {}
        for stream in items:
            parser = STREAM_TYPES[stream["format"]]

            try:
                streams.update(parser(self.session, stream["url"]))
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      stream["format"].upper(), err)

        return streams

__plugin__ = MLGTV

@@ -78,16 +78,30 @@
 i import
+ StreamMapper,
  http, v
@@ -1757,16 +1757,406 @@
 eam_id%0A%0A
+    def _create_streams(self, parser, stream):%0A%0A        try:%0A            streams = parser(self.session, stream%5B%22url%22%5D)%0A            return streams.items()%0A        except IOError as err:%0A            if not re.search(r%22(404%7C400) Client Error%22, str(err)):%0A                self.logger.error(%22Failed to extract %7B0%7D streams: %7B1%7D%22,%0A                                  stream%5B%22format%22%5D.upper(), err)%0A%0A
     def 
@@ -2626,24 +2626,25 @@
 schema)%0A
+%0A
         
 streams 
@@ -2639,119 +2639,92 @@
     
-streams = %7B%7D%0A        for stream in items:%0A            parser = STREAM_TYPES%5Bstream%5B%22format%22%5D%5D%0A%0A            try:
+mapper = StreamMapper(%0A            cmp=lambda type, stream: stream%5B%22format%22%5D == type
 %0A   
@@ -2724,32 +2724,34 @@
 ype%0A        
+)%0A
         
 streams.upda
@@ -2742,309 +2742,154 @@
     
-streams.update(parser(self.session, stream%5B%22url%22%5D))%0A            except IOError as err:%0A                if not re.search(r%22(404%7C400) Client Error%22, str(err)):%0A                    self.logger.error(%22Failed to extract %7B0%7D streams: %7B1%7D%22,%0A                                      stream%5B%22format%22%5D.upper(), err
+mapper.map(%22hls%22, self._create_streams, HLSStream.parse_variant_playlist)%0A        mapper.map(%22hds%22, self._create_streams, HDSStream.parse_manifest
 )%0A%0A 
@@ -2902,23 +2902,29 @@
  return 
-strea
+mapper(ite
 ms
+)
 %0A%0A__plug

Make use of the StreamMapper.