def _unwrap_stream(uri, timeout, scanner, requests_session): """ Get a stream URI from a playlist URI, ``uri``. Unwraps nested playlists until something that's not a playlist is found or the ``timeout`` is reached. """ original_uri = uri seen_uris = set() deadline = time.time() + timeout while time.time() < deadline: if uri in seen_uris: logger.info("Unwrapping stream from URI (%s) failed: " "playlist referenced itself", uri) return None, None else: seen_uris.add(uri) logger.debug("Unwrapping stream from URI: %s", uri) try: scan_timeout = deadline - time.time() if scan_timeout < 0: logger.info("Unwrapping stream from URI (%s) failed: " "timed out in %sms", uri, timeout) return None, None scan_result = scanner.scan(uri, timeout=scan_timeout) except exceptions.ScannerError as exc: logger.debug("GStreamer failed scanning URI (%s): %s", uri, exc) scan_result = None if scan_result is not None: if scan_result.playable or ( not scan_result.mime.startswith("text/") and not scan_result.mime.startswith("application/") ): logger.debug("Unwrapped potential %s stream: %s", scan_result.mime, uri) return uri, scan_result download_timeout = deadline - time.time() if download_timeout < 0: logger.info("Unwrapping stream from URI (%s) failed: timed out in %sms", uri, timeout) return None, None content = http.download(requests_session, uri, timeout=download_timeout / 1000) if content is None: logger.info("Unwrapping stream from URI (%s) failed: " "error downloading URI %s", original_uri, uri) return None, None uris = playlists.parse(content) if not uris: logger.debug("Failed parsing URI (%s) as playlist; found potential stream.", uri) return uri, None # TODO Test streams and return first that seems to be playable logger.debug("Parsed playlist (%s) and found new URI: %s", uri, uris[0]) uri = uris[0]
def translate_uri(self, uri): try: scan_result = self._scanner.scan(uri) except exceptions.ScannerError as e: logger.warning('Problem scanning URI %s: %s', uri, e) return None if not (scan_result.mime.startswith('text/') or scan_result.mime.startswith('application/')): return uri content = self._download(uri) if content is None: return None tracks = list(playlists.parse(content)) if tracks: # TODO Test streams and return first that seems to be playable return tracks[0]
def _parse_playlist(self, uri): """Fetch and parse playlist from uri.""" content = http.download(self.backend.session, uri, timeout=self.backend.timeout / 1000) if content is None: logger.warning( "Error downloading URI %s while unwrapping playlist", uri, ) return [] uris = playlists.parse(content) if not uris: logger.warning("Failed playlist from URI %s.", uri) return [] return uris
def translate_uri(self, uri): try: scan_result = self._scanner.scan(uri) except exceptions.ScannerError as e: logger.warning( 'Problem scanning URI %s: %s', uri, e) return None if not (scan_result.mime.startswith('text/') or scan_result.mime.startswith('application/')): return uri content = self._download(uri) if content is None: return None tracks = list(playlists.parse(content)) if tracks: # TODO Test streams and return first that seems to be playable return tracks[0]
def _unwrap_stream(uri, timeout, scanner, requests_session): """ Get a stream URI from a playlist URI, ``uri``. Unwraps nested playlists until something that's not a playlist is found or the ``timeout`` is reached. """ original_uri = uri seen_uris = set() deadline = time.time() + timeout while time.time() < deadline: if uri in seen_uris: logger.info( 'Unwrapping stream from URI (%s) failed: ' 'playlist referenced itself', uri) return None else: seen_uris.add(uri) logger.debug('Unwrapping stream from URI: %s', uri) try: scan_timeout = deadline - time.time() if scan_timeout < 0: logger.info( 'Unwrapping stream from URI (%s) failed: ' 'timed out in %sms', uri, timeout) return None scan_result = scanner.scan(uri, timeout=scan_timeout) except exceptions.ScannerError as exc: logger.debug('GStreamer failed scanning URI (%s): %s', uri, exc) scan_result = None if scan_result is not None: if scan_result.playable or ( not scan_result.mime.startswith('text/') and not scan_result.mime.startswith('application/')): logger.debug('Unwrapped potential %s stream: %s', scan_result.mime, uri) return uri download_timeout = deadline - time.time() if download_timeout < 0: logger.info( 'Unwrapping stream from URI (%s) failed: timed out in %sms', uri, timeout) return None content = http.download(requests_session, uri, timeout=download_timeout) if content is None: logger.info( 'Unwrapping stream from URI (%s) failed: ' 'error downloading URI %s', original_uri, uri) return None uris = playlists.parse(content) if not uris: logger.debug( 'Failed parsing URI (%s) as playlist; found potential stream.', uri) return uri # TODO Test streams and return first that seems to be playable logger.debug('Parsed playlist (%s) and found new URI: %s', uri, uris[0]) uri = uris[0]
def _unwrap_stream(uri, timeout, scanner, requests_session): """ Get a stream URI from a playlist URI, ``uri``. Unwraps nested playlists until something that's not a playlist is found or the ``timeout`` is reached. """ original_uri = uri seen_uris = set() deadline = time.time() + timeout while time.time() < deadline: if uri in seen_uris: logger.info( "Unwrapping stream from URI (%s) failed: " "playlist referenced itself", uri, ) return None, None else: seen_uris.add(uri) logger.debug("Unwrapping stream from URI: %s", uri) try: scan_timeout = deadline - time.time() if scan_timeout < 0: logger.info( "Unwrapping stream from URI (%s) failed: " "timed out in %sms", uri, timeout, ) return None, None scan_result = scanner.scan(uri, timeout=scan_timeout) except exceptions.ScannerError as exc: logger.debug("GStreamer failed scanning URI (%s): %s", uri, exc) scan_result = None if scan_result is not None: has_interesting_mime = ( scan_result.mime is not None and not scan_result.mime.startswith("text/") and not scan_result.mime.startswith("application/")) if scan_result.playable or has_interesting_mime: logger.debug("Unwrapped potential %s stream: %s", scan_result.mime, uri) return uri, scan_result download_timeout = deadline - time.time() if download_timeout < 0: logger.info( "Unwrapping stream from URI (%s) failed: timed out in %sms", uri, timeout, ) return None, None content = http.download(requests_session, uri, timeout=download_timeout / 1000) if content is None: logger.info( "Unwrapping stream from URI (%s) failed: " "error downloading URI %s", original_uri, uri, ) return None, None uris = playlists.parse(content) if not uris: logger.debug( "Failed parsing URI (%s) as playlist; found potential stream.", uri, ) return uri, None # TODO Test streams and return first that seems to be playable new_uri = uris[0] logger.debug("Parsed playlist (%s) and found new URI: %s", uri, new_uri) uri = urllib.parse.urljoin(uri, new_uri)
def test_parse(data, result): assert playlists.parse(data) == result
def _unwrap_stream(uri, timeout, scanner, requests_session): """ Get a stream URI from a playlist URI, ``uri``. Unwraps nested playlists until something that's not a playlist is found or the ``timeout`` is reached. """ original_uri = uri seen_uris = set() deadline = time.time() + timeout while time.time() < deadline: if uri in seen_uris: logger.info( f"Unwrapping stream from URI ({uri!r}) failed: " "playlist referenced itself", ) return None, None else: seen_uris.add(uri) logger.debug(f"Unwrapping stream from URI: {uri!r}") try: scan_timeout = deadline - time.time() if scan_timeout < 0: logger.info( f"Unwrapping stream from URI ({uri!r}) failed: " f"timed out in {timeout}ms", ) return None, None scan_result = scanner.scan(uri, timeout=scan_timeout) except exceptions.ScannerError as exc: logger.debug(f"GStreamer failed scanning URI ({uri!r}): {exc}") scan_result = None if scan_result is not None: if scan_result.playable or ( not scan_result.mime.startswith("text/") and not scan_result.mime.startswith("application/")): logger.debug( f"Unwrapped potential {scan_result.mime} stream: {uri!r}") return uri, scan_result download_timeout = deadline - time.time() if download_timeout < 0: logger.info( f"Unwrapping stream from URI ({uri!r}) failed: timed out in {timeout}ms" ) return None, None content = http.download(requests_session, uri, timeout=download_timeout / 1000) if content is None: logger.info( f"Unwrapping stream from URI ({original_uri!r}) failed: " f"error downloading URI {uri!r}", ) return None, None uris = playlists.parse(content) if not uris: logger.debug( f"Failed parsing URI ({uri!r}) as playlist; " "found potential stream.", ) return uri, None # TODO Test streams and return first that seems to be playable logger.debug( f"Parsed playlist ({uri!r}) and found new URI: {uris[0]!r}") uri = uris[0]