|
| 1 | +# coding=utf-8 |
| 2 | +from __future__ import print_function |
| 3 | +import xml.etree.ElementTree as ET |
| 4 | +import re |
| 5 | + |
| 6 | +from streamlink.plugin import Plugin |
| 7 | +from streamlink.plugin.api import http |
| 8 | +from streamlink.plugin.api import validate |
| 9 | +from streamlink.stream import HLSStream |
| 10 | +from streamlink.compat import urljoin |
| 11 | + |
| 12 | + |
| 13 | +class Dogan(Plugin): |
| 14 | + """ |
| 15 | + Support for the live streams from Doğan Media Group channels |
| 16 | + """ |
| 17 | + url_re = re.compile(r""" |
| 18 | + https?://(?:www.)? |
| 19 | + (?:teve2.com.tr/(?:canli-yayin|filmler/.*|programlar/.*)| |
| 20 | + kanald.com.tr/.*| |
| 21 | + cnnturk.com/canli-yayin| |
| 22 | + dreamtv.com.tr/canli-yayin) |
| 23 | + """, re.VERBOSE) |
| 24 | + playerctrl_re = re.compile(r'''<div[^>]*?ng-controller=(?P<quote>["'])(?:Live)?PlayerCtrl(?P=quote).*?>''', re.DOTALL) |
| 25 | + data_id_re = re.compile(r'''data-id=(?P<quote>["'])(?P<id>\w+)(?P=quote)''') |
| 26 | + content_id_re = re.compile(r'"contentId", "(\w+)"') |
| 27 | + content_api = "/actions/content/media/{id}" |
| 28 | + alt_content_api = "/action/media/{id}" |
| 29 | + content_api_schema = validate.Schema({ |
| 30 | + "Id": validate.text, |
| 31 | + "Media": { |
| 32 | + "Link": { |
| 33 | + "DefaultServiceUrl": validate.url(), |
| 34 | + validate.optional("ServiceUrl"): validate.url(), |
| 35 | + "SecurePath": validate.text, |
| 36 | + } |
| 37 | + } |
| 38 | + }) |
| 39 | + |
| 40 | + @classmethod |
| 41 | + def can_handle_url(cls, url): |
| 42 | + print(url) |
| 43 | + return cls.url_re.match(url) is not None |
| 44 | + |
| 45 | + def _get_content_id(self): |
| 46 | + res = http.get(self.url) |
| 47 | + # find the PlayerCtrl div |
| 48 | + player_ctrl_m = self.playerctrl_re.search(res.text) |
| 49 | + if player_ctrl_m: |
| 50 | + # extract the content id from the player control data |
| 51 | + player_ctrl_div = player_ctrl_m.group(0) |
| 52 | + content_id_m = self.data_id_re.search(player_ctrl_div) |
| 53 | + if content_id_m: |
| 54 | + return content_id_m.group("id") |
| 55 | + |
| 56 | + # use the fall back regex |
| 57 | + content_id_m = self.content_id_re.search(res.text) |
| 58 | + return content_id_m and content_id_m.group(1) |
| 59 | + |
| 60 | + def _get_hls_url(self, content_id): |
| 61 | + # make the api url relative to the current domain |
| 62 | + if "cnnturk" in self.url: |
| 63 | + self.logger.debug("Using alternative content API url") |
| 64 | + api_url = urljoin(self.url, self.alt_content_api.format(id=content_id)) |
| 65 | + else: |
| 66 | + api_url = urljoin(self.url, self.content_api.format(id=content_id)) |
| 67 | + |
| 68 | + apires = http.get(api_url) |
| 69 | + |
| 70 | + stream_data = http.json(apires, schema=self.content_api_schema) |
| 71 | + d = stream_data["Media"]["Link"] |
| 72 | + return urljoin((d["ServiceUrl"] or d["DefaultServiceUrl"]), d["SecurePath"]) |
| 73 | + |
| 74 | + def _get_streams(self): |
| 75 | + content_id = self._get_content_id() |
| 76 | + if content_id: |
| 77 | + self.logger.debug(u"Loading content: {}", content_id) |
| 78 | + hls_url = self._get_hls_url(content_id) |
| 79 | + return HLSStream.parse_variant_playlist(self.session, hls_url) |
| 80 | + else: |
| 81 | + self.logger.error(u"Could not find the contentId for this stream") |
| 82 | + |
| 83 | + |
| 84 | +__plugin__ = Dogan |
0 commit comments