def test_info_json(self): expected = list( EXPECTED_ANNOTATIONS) # Two annotations could have the same text. ie = yt_dlp.extractor.YoutubeIE() ydl = YoutubeDL(params) ydl.add_info_extractor(ie) ydl.download([TEST_ID]) self.assertTrue(os.path.exists(ANNOTATIONS_FILE)) annoxml = None with io.open(ANNOTATIONS_FILE, 'r', encoding='utf-8') as annof: annoxml = xml.etree.ElementTree.parse(annof) self.assertTrue(annoxml is not None, 'Failed to parse annotations XML') root = annoxml.getroot() self.assertEqual(root.tag, 'document') annotationsTag = root.find('annotations') self.assertEqual(annotationsTag.tag, 'annotations') annotations = annotationsTag.findall('annotation') # Not all the annotations have TEXT children and the annotations are returned unsorted. for a in annotations: self.assertEqual(a.tag, 'annotation') if a.get('type') == 'text': textTag = a.find('TEXT') text = textTag.text self.assertTrue( text in expected) # assertIn only added in python 2.7 # remove the first occurrence, there could be more than one annotation with the same text expected.remove(text) # We should have seen (and removed) all the expected annotation texts. self.assertEqual(len(expected), 0, 'Not all expected annotations were found.')
def test_post_hooks(self): self.params['post_hooks'] = [self.hook_one, self.hook_two] ydl = YoutubeDL(self.params) ydl.download([TEST_ID]) self.assertEqual(self.stored_name_1, EXPECTED_NAME, 'Not the expected name from hook 1') self.assertEqual(self.stored_name_2, EXPECTED_NAME, 'Not the expected name from hook 2')
def _download_restricted(url, filename, age): """ Returns true if the file has been downloaded """ params = { 'age_limit': age, 'skip_download': True, 'writeinfojson': True, 'outtmpl': '%(id)s.%(ext)s', } ydl = YoutubeDL(params) ydl.add_default_info_extractors() json_filename = os.path.splitext(filename)[0] + '.info.json' try_rm(json_filename) ydl.download([url]) res = os.path.exists(json_filename) try_rm(json_filename) return res
def impl(): if on_dl_starting: on_dl_starting(self._logger) options = { "format": "bestvideo[ext=mp4]+bestaudio[ext=m4a]/" "bestvideo+bestaudio/best", "noplaylist": True, "merge_output_format": "mp4", "outtmpl": dest, "quiet": True, "progress_hooks": [ self._dl_logger.log_download_progress, dispatch_dl_events, ], } ydl = YoutubeDL(options) with ydl: # Download the video try: ydl.download([source]) except Exception as e: self._logger.error( "Download error", video=dest, source=source, error=e ) self._evt_dispatcher.dispatch(DownloadError(op_id, str(e))) return if not Path(dest).exists(): error = "video path points to non existent file" self._logger.error( "Download error", video=dest, source=source, error=error, ) self._evt_dispatcher.dispatch(DownloadError(op_id, error)) return self._evt_dispatcher.dispatch(DownloadSuccess(op_id))
def download_subtitle(self, url: str, dest: str, lang: str, exts: List[str]): self._logger.info("Downloading subtitle", subtitle=dest, lang=lang) lang = ISO639Utils.long2short(lang) for ext in exts: options = { "skip_download": True, "subtitleslangs": [lang], "subtitlesformat": ext, "writeautomaticsub": False, "outtmpl": dest, "progress_hooks": [self._dl_logger.log_download_progress], "quiet": True, } ydl = YoutubeDL(options) with ydl: try: ydl.download([url]) return f"{dest}.{lang}.{ext}" except Exception as e: self._logger.error( "Subtitle download error", subtitle=dest, ext=ext, error=e ) return None
def do_GET(self): url = urlparse(self.path) qs = parse_qs(url.query) ydl_opts = { 'forcejson': True, 'logger': self, 'quiet': True, 'simulate': True } if url.path == '/process': ydl_opts[ 'format'] = '(best[height = 1080][fps <= 30]/best[height <=? 720])[format_id!=source][vcodec!*=av01][vcodec!*=vp9]' ydl_opts['noplaylist'] = True ydl_opts['restrictfilenames'] = True ydl_opts['writeautomaticsub'] = True ydl_opts['writesubtitles'] = True elif url.path == '/process_playlist': ydl_opts['extract_flat'] = True else: self.fail("no matching path: {}".format(url.path)) return ydl = YoutubeDL(ydl_opts) try: retcode = ydl.download(qs['url']) except Exception as ex: self.fail("ydl exception: {}".format(repr(ex))) return if retcode != 0: self.fail("ydl exit: {}".format(retcode)) return response_bytes = self.response.encode() self.send_response(200) self.send_header('Content-Type', 'text/plain') self.send_header('Content-Length', len(response_bytes)) self.end_headers() self.wfile.write(response_bytes)