(self, pyfile)
| 741 | limit=5000000) |
| 742 | |
| 743 | def process(self, pyfile): |
| 744 | pyfile.url = replace_patterns(pyfile.url, self.URL_REPLACEMENTS) |
| 745 | self.data = self.load(pyfile.url) |
| 746 | |
| 747 | if re.search(r'<div id="player-unavailable" class="\s*player-width player-height\s*(?:player-unavailable\s*)?">', |
| 748 | self.data) or '"playabilityStatus":{"status":"ERROR"' in self.data: |
| 749 | self.offline() |
| 750 | |
| 751 | if "We have been receiving a large volume of requests from your network." in self.data: |
| 752 | self.temp_offline() |
| 753 | |
| 754 | m = re.search(r'ytplayer.config = ({.+?});', self.data) |
| 755 | if m is None: |
| 756 | self.fail(_("Player config pattern not found")) |
| 757 | |
| 758 | self.player_config = json.loads(m.group(1)) |
| 759 | |
| 760 | self.ffmpeg = Ffmpeg(self.config.get('priority'), self) |
| 761 | |
| 762 | #: Set file name |
| 763 | self.file_name = decode(json.loads(self.player_config['args']['player_response'])['videoDetails']['title']) |
| 764 | |
| 765 | #: Check for start time |
| 766 | self.start_time = (0, 0) |
| 767 | m = re.search(r't=(?:(\d+)m)?(\d+)s', pyfile.url) |
| 768 | if self.ffmpeg and m: |
| 769 | self.start_time = tuple(map(lambda _x: 0 if _x is None else int(_x), m.groups())) |
| 770 | self.file_name += " (starting at %sm%ss)" % (self.start_time[0], self.start_time[1]) |
| 771 | |
| 772 | #: Cleaning invalid characters from the file name |
| 773 | self.file_name = safename(self.file_name) |
| 774 | |
| 775 | #: Parse available streams |
| 776 | self.streams = [] |
| 777 | |
| 778 | for path in [('args', 'url_encoded_fmt_stream_map'), |
| 779 | ('args', 'adaptive_fmts')]: |
| 780 | item = try_get(self.player_config, *path) |
| 781 | if item is not None: |
| 782 | streams = [urlparse.parse_qs(_s) for _s in item.split(',')] |
| 783 | streams = [dict((k, v[0]) for k,v in _d.items()) for _d in streams] |
| 784 | self.streams.extend(streams) |
| 785 | |
| 786 | player_response = json.loads(self.player_config['args']['player_response']) |
| 787 | self.streams.extend(try_get(player_response, 'streamingData', 'formats') or []) |
| 788 | self.streams.extend(try_get(player_response, 'streamingData', 'adaptiveFormats') or []) |
| 789 | |
| 790 | streams = self.streams |
| 791 | self.streams = [] |
| 792 | for _s in streams: |
| 793 | itag = int(_s['itag']) |
| 794 | url_data = _s |
| 795 | url = _s.get('url', None) |
| 796 | if url is None: |
| 797 | cipher = _s.get('cipher', None) |
| 798 | if cipher is None: |
| 799 | continue |
| 800 |
nothing calls this directly
no test coverage detected