Repository: streamlink/streamlink
Pull request #3295 (2020-10-26 18:19:36)

ci.github: install latest version of pynsist
This installs the latest version of pynsist instead of pinning it to `2.4`. It was pinned to `2.4` because of #2655.

According to the [pynsist release notes](https://pynsist.readthedocs.io/en/latest/releasenotes.html), the newer versions (current one is `2.5.1`) assemble the executables during build-time rather than run-time/install-time. This cleans up the install directory by a bit and is less confusing for the enduser.

The NSIS GUI has also been improved with proper DPI scaling, but that requires NSIS 3.0 which is currently unavailable on the `ubuntu-18.04` CI image and `ubuntu-latest` still points towards `18.04`. That will change soon though, and once it does, the installer will see those improvements automatically. We could also manually set it to `ubuntu-20.04`.

----

While building the installer locally, I also tried bumping the included Python version, but there's currently an issue in pynsist and it doesn't recognize the new wheel naming scheme since py38 and pycryptodome can't be found. I will see if I can submit a PR there and fix it when I get the time. There's already a PR for it, but it's stale since April and just a hack rather than a proper fix.

beardypig: I'd be fine with using `ubuntu-20.04`... 
bastimeyer: > I'd be fine with using `ubuntu-20.04`...

According to `actions/virtual-environments`, the switch will happen automatically during 2020-11-30 and the following weeks excluding holidays, but if you don't want to wait for this, we can change it now.

This should be changed in a separate PR though. The used Python version for the docs, installer and release jobs could be changed as well in one go.


Patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 47f6b70e..0b14e704 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -35,12 +35,12 @@ jobs:
       - name: Install dependencies
         continue-on-error: ${{ matrix.continue || false }}
         run: bash ./script/install-dependencies.sh
+      - name: Lint
+        continue-on-error: ${{ matrix.continue || false }}
+        run: flake8 --count
       - name: Test
         continue-on-error: ${{ matrix.continue || false }}
         run: pytest -r a --cov --cov-branch --cov-report=xml
-      - name: Lint
-        continue-on-error: ${{ matrix.continue || false }}
-        run: flake8
       - name: Upload coverage data
         if: github.event_name != 'schedule'
         continue-on-error: ${{ matrix.continue || false }}
@@ -83,7 +83,7 @@ jobs:
       - name: Install dependencies
         run: |
           ./script/install-dependencies.sh
-          python -m pip install pynsist==2.4
+          python -m pip install pynsist
           sudo apt update
           sudo apt install -y nsis imagemagick inkscape
       - name: Installer file name
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 3480881d..c626ae84 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -6,3 +6,4 @@ mock
 requests-mock
 freezegun>=1.0.0
 flake8
+flake8-import-order
diff --git a/setup.cfg b/setup.cfg
index 4b06350c..f5f74603 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -28,7 +28,9 @@ exclude =
   versioneer.py,
   win32/,
 per-file-ignores =
-  src/streamlink/__init__.py:E402,F401,
+  src/streamlink/__init__.py:E402,F401,I100,I101,I201,I202,I666,
+  src/streamlink/packages/*:I100,I101,I201,I202,I666,
+  src/streamlink/packages/**/*:I100,I101,I201,I202,I666,
   src/streamlink/plugin/api/useragents.py:E501,
   src/streamlink/plugins/__init__.py:F401,
   src/streamlink/stream/__init__.py:F401,
@@ -43,3 +45,9 @@ builtins =
   raw_input,
   unicode,
   xrange,
+import-order-style = pycharm
+application-import-names =
+  streamlink,
+  streamlink_cli,
+  tests,
+  versioneer,
diff --git a/setup.py b/setup.py
index ba29b54a..d532a4a9 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ import codecs
 from os import environ, path
 from sys import argv, path as sys_path
 
-from setuptools import setup, find_packages
+from setuptools import find_packages, setup
 
 import versioneer
 
diff --git a/src/streamlink/__init__.py b/src/streamlink/__init__.py
index fc11947b..a3fbbc21 100644
--- a/src/streamlink/__init__.py
+++ b/src/streamlink/__init__.py
@@ -8,7 +8,8 @@ An API is also provided that allows direct access to stream data.
 Full documentation is available at https://streamlink.github.io.
 
 """
-from ._version import get_versions
+from streamlink._version import get_versions
+
 __version__ = get_versions()['version']
 del get_versions
 __title__ = "streamlink"
@@ -17,7 +18,7 @@ __author__ = "Streamlink"
 __copyright__ = "Copyright 2020 Streamlink"
 __credits__ = ["https://github.com/streamlink/streamlink/blob/master/AUTHORS"]
 
-from .api import streams
-from .exceptions import (StreamlinkError, PluginError, NoStreamsError,
-                         NoPluginError, StreamError)
-from .session import Streamlink
+from streamlink.api import streams
+from streamlink.exceptions import (StreamlinkError, PluginError, NoStreamsError,
+                                   NoPluginError, StreamError)
+from streamlink.session import Streamlink
diff --git a/src/streamlink/api.py b/src/streamlink/api.py
index 2b0b6c89..e97894c6 100644
--- a/src/streamlink/api.py
+++ b/src/streamlink/api.py
@@ -1,4 +1,4 @@
-from .session import Streamlink
+from streamlink.session import Streamlink
 
 
 def streams(url, **params):
diff --git a/src/streamlink/cache.py b/src/streamlink/cache.py
index 4bde3e58..280068f0 100644
--- a/src/streamlink/cache.py
+++ b/src/streamlink/cache.py
@@ -2,9 +2,9 @@ import json
 import os
 import shutil
 import tempfile
-from time import time, mktime
+from time import mktime, time
 
-from .compat import is_win32
+from streamlink.compat import is_win32
 
 if is_win32:
     xdg_cache = os.environ.get("APPDATA", os.path.expanduser("~"))
diff --git a/src/streamlink/logger.py b/src/streamlink/logger.py
index 64985bec..71ec7b4c 100644
--- a/src/streamlink/logger.py
+++ b/src/streamlink/logger.py
@@ -1,9 +1,8 @@
-from datetime import datetime
 import logging
-from logging import NOTSET, ERROR, WARN, INFO, DEBUG, CRITICAL
+from datetime import datetime
+from logging import CRITICAL, DEBUG, ERROR, INFO, NOTSET, WARN
 from threading import Lock
 
-
 TRACE = 5
 _levelToName = dict([(CRITICAL, "critical"), (ERROR, "error"), (WARN, "warning"), (INFO, "info"), (DEBUG, "debug"),
                      (TRACE, "trace"), (NOTSET, "none")])
diff --git a/src/streamlink/plugin/__init__.py b/src/streamlink/plugin/__init__.py
index 0c59bd04..f5f3bc3f 100644
--- a/src/streamlink/plugin/__init__.py
+++ b/src/streamlink/plugin/__init__.py
@@ -1,6 +1,5 @@
-from .plugin import Plugin
-from ..exceptions import PluginError
-from ..options import Options as PluginOptions
-from ..options import Arguments as PluginArguments, Argument as PluginArgument
+from streamlink.exceptions import PluginError
+from streamlink.options import Argument as PluginArgument, Arguments as PluginArguments, Options as PluginOptions
+from streamlink.plugin.plugin import Plugin
 
 __all__ = ["Plugin", "PluginError", "PluginOptions", "PluginArguments", "PluginArgument"]
diff --git a/src/streamlink/plugin/api/__init__.py b/src/streamlink/plugin/api/__init__.py
index 0e5c5972..9da36b33 100644
--- a/src/streamlink/plugin/api/__init__.py
+++ b/src/streamlink/plugin/api/__init__.py
@@ -1,10 +1,9 @@
 import sys
-
 from types import ModuleType as module
 
-from .http_session import HTTPSession
-from .mapper import StreamMapper
-from .support_plugin import load_support_plugin
+from streamlink.plugin.api.http_session import HTTPSession
+from streamlink.plugin.api.mapper import StreamMapper
+from streamlink.plugin.api.support_plugin import load_support_plugin
 
 __all__ = ["HTTPSession", "StreamMapper", "load_support_plugin", "http"]
 
diff --git a/src/streamlink/plugin/api/http_session.py b/src/streamlink/plugin/api/http_session.py
index 97a7762c..55aa2ce6 100644
--- a/src/streamlink/plugin/api/http_session.py
+++ b/src/streamlink/plugin/api/http_session.py
@@ -1,9 +1,12 @@
 import time
+
 from requests import Session, __build__ as requests_version
 from requests.adapters import HTTPAdapter
 
+from streamlink.exceptions import PluginError
 from streamlink.packages.requests_file import FileAdapter
 from streamlink.plugin.api import useragents
+from streamlink.utils import parse_json, parse_xml
 
 try:
     from requests.packages.urllib3.util import Timeout
@@ -21,9 +24,6 @@ try:
 except (ImportError, AttributeError):
     pass
 
-from ...exceptions import PluginError
-from ...utils import parse_json, parse_xml
-
 __all__ = ["HTTPSession"]
 
 
diff --git a/src/streamlink/plugin/api/support_plugin.py b/src/streamlink/plugin/api/support_plugin.py
index 827a463d..bf16b88b 100644
--- a/src/streamlink/plugin/api/support_plugin.py
+++ b/src/streamlink/plugin/api/support_plugin.py
@@ -1,5 +1,6 @@
-import os
 import inspect
+import os
+
 from streamlink.utils import load_module
 
 __all__ = ["load_support_plugin"]
diff --git a/src/streamlink/plugin/api/utils.py b/src/streamlink/plugin/api/utils.py
index ca9c1893..d64f11ba 100644
--- a/src/streamlink/plugin/api/utils.py
+++ b/src/streamlink/plugin/api/utils.py
@@ -2,7 +2,7 @@
 import re
 from collections import namedtuple
 
-from ...utils import parse_qsd as parse_query, parse_json, parse_xml
+from streamlink.utils import parse_json, parse_qsd as parse_query, parse_xml
 
 __all__ = ["parse_json", "parse_xml", "parse_query"]
 
diff --git a/src/streamlink/plugin/api/validate.py b/src/streamlink/plugin/api/validate.py
index ab0301ba..1edf3550 100644
--- a/src/streamlink/plugin/api/validate.py
+++ b/src/streamlink/plugin/api/validate.py
@@ -21,7 +21,7 @@ from functools import singledispatch
 from urllib.parse import urlparse
 from xml.etree import ElementTree as ET
 
-from ...exceptions import PluginError
+from streamlink.exceptions import PluginError
 
 __all__ = [
     "any", "all", "filter", "get", "getattr", "hasattr", "length", "optional",
diff --git a/src/streamlink/plugin/plugin.py b/src/streamlink/plugin/plugin.py
index 96704cff..11484dc2 100644
--- a/src/streamlink/plugin/plugin.py
+++ b/src/streamlink/plugin/plugin.py
@@ -3,14 +3,14 @@ import logging
 import operator
 import re
 import time
-import requests.cookies
-
-from functools import partial
 from collections import OrderedDict
+from functools import partial
+
+import requests.cookies
 
 from streamlink.cache import Cache
-from streamlink.exceptions import PluginError, NoStreamsError, FatalPluginError
-from streamlink.options import Options, Arguments
+from streamlink.exceptions import FatalPluginError, NoStreamsError, PluginError
+from streamlink.options import Arguments, Options
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/__init__.py b/src/streamlink/plugins/__init__.py
index cea42a0a..6d07cb9e 100644
--- a/src/streamlink/plugins/__init__.py
+++ b/src/streamlink/plugins/__init__.py
@@ -4,5 +4,7 @@
     compatibility.
 """
 
-from ..exceptions import PluginError, NoStreamsError, NoPluginError
-from ..plugin import Plugin
+from streamlink.exceptions import NoPluginError, NoStreamsError, PluginError
+from streamlink.plugin.plugin import Plugin
+
+__all__ = ['Plugin', 'PluginError', 'NoStreamsError', 'NoPluginError']
diff --git a/src/streamlink/plugins/abematv.py b/src/streamlink/plugins/abematv.py
index 3f880c11..cd044c75 100644
--- a/src/streamlink/plugins/abematv.py
+++ b/src/streamlink/plugins/abematv.py
@@ -5,19 +5,16 @@ import re
 import struct
 import time
 import uuid
-
 from base64 import urlsafe_b64encode
 from binascii import unhexlify
 
 from Crypto.Cipher import AES
-
 from requests import Response
 from requests.adapters import BaseAdapter
 
 from streamlink.exceptions import NoStreamsError
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 from streamlink.utils.url import update_qsd
 
diff --git a/src/streamlink/plugins/abweb.py b/src/streamlink/plugins/abweb.py
index da601a91..9fdfcc53 100644
--- a/src/streamlink/plugins/abweb.py
+++ b/src/streamlink/plugins/abweb.py
@@ -4,13 +4,11 @@ import time
 
 from streamlink.cache import Cache
 from streamlink.exceptions import PluginError
-from streamlink.plugin import Plugin
-from streamlink.plugin import PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/afreeca.py b/src/streamlink/plugins/afreeca.py
index e3d59a26..be998f5b 100644
--- a/src/streamlink/plugins/afreeca.py
+++ b/src/streamlink/plugins/afreeca.py
@@ -1,12 +1,10 @@
 import logging
 import re
 
-from streamlink.plugin import Plugin
-from streamlink.plugin import PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 CHANNEL_API_URL = "http://live.afreecatv.com:8057/afreeca/player_live_api.php"
diff --git a/src/streamlink/plugins/akamaihd.py b/src/streamlink/plugins/akamaihd.py
index ebdb0dd7..80dea142 100644
--- a/src/streamlink/plugins/akamaihd.py
+++ b/src/streamlink/plugins/akamaihd.py
@@ -6,7 +6,6 @@ from streamlink.plugin.plugin import parse_url_params
 from streamlink.stream import AkamaiHDStream
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/animelab.py b/src/streamlink/plugins/animelab.py
index c7ed423c..430e789a 100644
--- a/src/streamlink/plugins/animelab.py
+++ b/src/streamlink/plugins/animelab.py
@@ -1,12 +1,11 @@
 import logging
 import re
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.stream import HTTPStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/app17.py b/src/streamlink/plugins/app17.py
index 63642673..33b598cc 100644
--- a/src/streamlink/plugins/app17.py
+++ b/src/streamlink/plugins/app17.py
@@ -3,7 +3,7 @@ import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents, validate
-from streamlink.stream import HLSStream, RTMPStream, HTTPStream
+from streamlink.stream import HLSStream, HTTPStream, RTMPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/atresplayer.py b/src/streamlink/plugins/atresplayer.py
index 3c08a99d..8278fa21 100644
--- a/src/streamlink/plugins/atresplayer.py
+++ b/src/streamlink/plugins/atresplayer.py
@@ -4,8 +4,8 @@ from functools import partial
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import HLSStream, DASHStream
-from streamlink.utils import parse_json, update_scheme, search_dict
+from streamlink.stream import DASHStream, HLSStream
+from streamlink.utils import parse_json, search_dict, update_scheme
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/bbciplayer.py b/src/streamlink/plugins/bbciplayer.py
index e20d8a12..de730087 100644
--- a/src/streamlink/plugins/bbciplayer.py
+++ b/src/streamlink/plugins/bbciplayer.py
@@ -1,15 +1,14 @@
 import base64
-from collections import defaultdict
-from hashlib import sha1
 import logging
 import re
+from collections import defaultdict
+from hashlib import sha1
 from urllib.parse import urlparse
 
 from streamlink.exceptions import PluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
-from streamlink.stream import HDSStream
-from streamlink.stream import HLSStream
+from streamlink.stream import HDSStream, HLSStream
 from streamlink.stream.dash import DASHStream
 from streamlink.utils import parse_json
 
diff --git a/src/streamlink/plugins/bilibili.py b/src/streamlink/plugins/bilibili.py
index a11163b4..619c27ce 100644
--- a/src/streamlink/plugins/bilibili.py
+++ b/src/streamlink/plugins/bilibili.py
@@ -3,7 +3,7 @@ import re
 from urllib.parse import urlparse
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import validate, useragents
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HTTPStream
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/bloomberg.py b/src/streamlink/plugins/bloomberg.py
index 0c79e762..31026aca 100644
--- a/src/streamlink/plugins/bloomberg.py
+++ b/src/streamlink/plugins/bloomberg.py
@@ -3,7 +3,7 @@ import re
 from functools import partial
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import validate, useragents
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HDSStream, HLSStream, HTTPStream
 from streamlink.utils import parse_json, update_scheme
 
diff --git a/src/streamlink/plugins/brightcove.py b/src/streamlink/plugins/brightcove.py
index 824cc515..6edb9cb7 100644
--- a/src/streamlink/plugins/brightcove.py
+++ b/src/streamlink/plugins/brightcove.py
@@ -1,17 +1,16 @@
-from io import BytesIO
 import logging
 import random
 import re
-from urllib.parse import urlparse, parse_qsl
+from io import BytesIO
+from urllib.parse import parse_qsl, urlparse
 
 from streamlink import PluginError
 from streamlink.packages.flashmedia import AMFMessage, AMFPacket
 from streamlink.packages.flashmedia.types import AMF3ObjectBase
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import validate, useragents
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream, HTTPStream, RTMPStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/btsports.py b/src/streamlink/plugins/btsports.py
index 3c87df32..0277390d 100644
--- a/src/streamlink/plugins/btsports.py
+++ b/src/streamlink/plugins/btsports.py
@@ -4,7 +4,7 @@ import time
 from urllib.parse import quote
 from uuid import uuid4
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 
diff --git a/src/streamlink/plugins/canalplus.py b/src/streamlink/plugins/canalplus.py
index 47604d32..02892787 100644
--- a/src/streamlink/plugins/canalplus.py
+++ b/src/streamlink/plugins/canalplus.py
@@ -5,7 +5,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HDSStream, HLSStream, HTTPStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/cdnbg.py b/src/streamlink/plugins/cdnbg.py
index 1d17e221..38f77cd3 100644
--- a/src/streamlink/plugins/cdnbg.py
+++ b/src/streamlink/plugins/cdnbg.py
@@ -3,8 +3,7 @@ import re
 from urllib.parse import urlparse
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 from streamlink.utils import update_scheme
 
diff --git a/src/streamlink/plugins/ceskatelevize.py b/src/streamlink/plugins/ceskatelevize.py
index 94d41999..63a4c45a 100644
--- a/src/streamlink/plugins/ceskatelevize.py
+++ b/src/streamlink/plugins/ceskatelevize.py
@@ -11,16 +11,16 @@ Following channels are working:
 
 Additionally, videos from iVysilani archive should work as well.
 """
-from html import unescape as html_unescape
 import json
 import logging
 import re
+from html import unescape as html_unescape
 from urllib.parse import quote
 
+from streamlink.exceptions import PluginError
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents, validate
-from streamlink.stream import HLSStream, DASHStream
-from streamlink.exceptions import PluginError
+from streamlink.stream import DASHStream, HLSStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/common_jwplayer.py b/src/streamlink/plugins/common_jwplayer.py
index 4724b1ed..8e73c6b7 100644
--- a/src/streamlink/plugins/common_jwplayer.py
+++ b/src/streamlink/plugins/common_jwplayer.py
@@ -1,5 +1,4 @@
 import re
-
 from functools import partial
 
 from streamlink.plugin.api import validate
diff --git a/src/streamlink/plugins/common_swf.py b/src/streamlink/plugins/common_swf.py
index 0082840c..6d444085 100644
--- a/src/streamlink/plugins/common_swf.py
+++ b/src/streamlink/plugins/common_swf.py
@@ -1,8 +1,8 @@
 from collections import namedtuple
 from io import BytesIO
 
-from streamlink.utils import swfdecompress
 from streamlink.packages.flashmedia.types import U16LE, U32LE
+from streamlink.utils import swfdecompress
 
 __all__ = ["parse_swf"]
 
diff --git a/src/streamlink/plugins/crunchyroll.py b/src/streamlink/plugins/crunchyroll.py
index 31ca0f4d..1900dd0a 100644
--- a/src/streamlink/plugins/crunchyroll.py
+++ b/src/streamlink/plugins/crunchyroll.py
@@ -1,9 +1,9 @@
 import datetime
-import re
 import logging
+import re
 from uuid import uuid4
 
-from streamlink.plugin import Plugin, PluginError, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments, PluginError
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 
diff --git a/src/streamlink/plugins/cubetv.py b/src/streamlink/plugins/cubetv.py
index ad22026c..c8639dcd 100644
--- a/src/streamlink/plugins/cubetv.py
+++ b/src/streamlink/plugins/cubetv.py
@@ -1,9 +1,9 @@
 import re
 
+from streamlink import NoStreamsError
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
-from streamlink import NoStreamsError
 
 
 class CubeTV(Plugin):
diff --git a/src/streamlink/plugins/dailymotion.py b/src/streamlink/plugins/dailymotion.py
index de70e48d..4f384b54 100644
--- a/src/streamlink/plugins/dailymotion.py
+++ b/src/streamlink/plugins/dailymotion.py
@@ -6,7 +6,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream, HTTPStream
 
-
 log = logging.getLogger(__name__)
 
 COOKIES = {
diff --git a/src/streamlink/plugins/dash.py b/src/streamlink/plugins/dash.py
index 6b941638..0d8aec90 100644
--- a/src/streamlink/plugins/dash.py
+++ b/src/streamlink/plugins/dash.py
@@ -3,8 +3,7 @@ import re
 from urllib.parse import urlparse
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.plugin import stream_weight
-from streamlink.plugin.plugin import LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY
+from streamlink.plugin.plugin import LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY, stream_weight
 from streamlink.stream.dash import DASHStream
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/delfi.py b/src/streamlink/plugins/delfi.py
index 8594adb5..88e5b739 100644
--- a/src/streamlink/plugins/delfi.py
+++ b/src/streamlink/plugins/delfi.py
@@ -3,14 +3,13 @@ Plugin to support the videos from Delfi.lt
 
 https://en.wikipedia.org/wiki/Delfi_(web_portal)
 """
-import re
-import logging
-
 import itertools
+import logging
+import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api.utils import itertags
-from streamlink.stream import HTTPStream, HLSStream, DASHStream
+from streamlink.stream import DASHStream, HLSStream, HTTPStream
 from streamlink.utils import update_scheme
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/deutschewelle.py b/src/streamlink/plugins/deutschewelle.py
index cc3e4188..1cc712de 100644
--- a/src/streamlink/plugins/deutschewelle.py
+++ b/src/streamlink/plugins/deutschewelle.py
@@ -1,12 +1,11 @@
 import logging
 import re
-from urllib.parse import urlparse, parse_qsl
+from urllib.parse import parse_qsl, urlparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream, HTTPStream, RTMPStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/dlive.py b/src/streamlink/plugins/dlive.py
index d98606f4..5afdc7f7 100644
--- a/src/streamlink/plugins/dlive.py
+++ b/src/streamlink/plugins/dlive.py
@@ -7,7 +7,6 @@ from streamlink.plugin import Plugin, PluginError
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/dogan.py b/src/streamlink/plugins/dogan.py
index f396c2d8..cf50185b 100644
--- a/src/streamlink/plugins/dogan.py
+++ b/src/streamlink/plugins/dogan.py
@@ -6,7 +6,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/dogus.py b/src/streamlink/plugins/dogus.py
index e23c4462..38cbff3d 100644
--- a/src/streamlink/plugins/dogus.py
+++ b/src/streamlink/plugins/dogus.py
@@ -1,5 +1,5 @@
-import re
 import logging
+import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api.utils import itertags
diff --git a/src/streamlink/plugins/earthcam.py b/src/streamlink/plugins/earthcam.py
index f941d1a2..108b6622 100644
--- a/src/streamlink/plugins/earthcam.py
+++ b/src/streamlink/plugins/earthcam.py
@@ -6,7 +6,6 @@ from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream, RTMPStream
 from streamlink.utils import parse_json, update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/ellobo.py b/src/streamlink/plugins/ellobo.py
index b722b0e3..5f815e0e 100644
--- a/src/streamlink/plugins/ellobo.py
+++ b/src/streamlink/plugins/ellobo.py
@@ -1,7 +1,6 @@
 import re
 
-from streamlink import NoPluginError
-from streamlink import PluginError
+from streamlink import NoPluginError, PluginError
 from streamlink.plugin import Plugin
 
 
diff --git a/src/streamlink/plugins/eltrecetv.py b/src/streamlink/plugins/eltrecetv.py
index 7a4cad70..21051b26 100644
--- a/src/streamlink/plugins/eltrecetv.py
+++ b/src/streamlink/plugins/eltrecetv.py
@@ -6,7 +6,6 @@ from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/facebook.py b/src/streamlink/plugins/facebook.py
index c625928f..e7dd2f5f 100644
--- a/src/streamlink/plugins/facebook.py
+++ b/src/streamlink/plugins/facebook.py
@@ -1,6 +1,6 @@
-from html import unescape as html_unescape
 import logging
 import re
+from html import unescape as html_unescape
 from urllib.parse import unquote_plus, urlencode
 
 from streamlink.plugin import Plugin
diff --git a/src/streamlink/plugins/filmon.py b/src/streamlink/plugins/filmon.py
index 31f6a278..35a08c65 100644
--- a/src/streamlink/plugins/filmon.py
+++ b/src/streamlink/plugins/filmon.py
@@ -1,5 +1,5 @@
-import re
 import logging
+import re
 import time
 from urllib.parse import urlparse, urlunparse
 
@@ -7,7 +7,7 @@ from streamlink.exceptions import PluginError, StreamError
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream, hls_playlist
-from streamlink.stream.hls import HLSStreamWorker, HLSStreamReader, Sequence
+from streamlink.stream.hls import HLSStreamReader, HLSStreamWorker, Sequence
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/funimationnow.py b/src/streamlink/plugins/funimationnow.py
index 7f4e1238..49b8fc4c 100644
--- a/src/streamlink/plugins/funimationnow.py
+++ b/src/streamlink/plugins/funimationnow.py
@@ -2,12 +2,10 @@ import logging
 import random
 import re
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
+from streamlink.plugin.api import useragents, validate
 from streamlink.plugin.api.utils import itertags
-from streamlink.stream import HLSStream
-from streamlink.stream import HTTPStream
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.stream.ffmpegmux import MuxedStream
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/gardenersworld.py b/src/streamlink/plugins/gardenersworld.py
index 669ed52c..6b96c723 100644
--- a/src/streamlink/plugins/gardenersworld.py
+++ b/src/streamlink/plugins/gardenersworld.py
@@ -6,7 +6,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api.utils import itertags
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/goodgame.py b/src/streamlink/plugins/goodgame.py
index 1fa0e858..f1cbaf38 100644
--- a/src/streamlink/plugins/goodgame.py
+++ b/src/streamlink/plugins/goodgame.py
@@ -1,5 +1,5 @@
-import re
 import logging
+import re
 
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
diff --git a/src/streamlink/plugins/googledrive.py b/src/streamlink/plugins/googledrive.py
index f9eb8f02..fe71c84a 100644
--- a/src/streamlink/plugins/googledrive.py
+++ b/src/streamlink/plugins/googledrive.py
@@ -5,7 +5,6 @@ from urllib.parse import parse_qsl
 from streamlink.plugin import Plugin
 from streamlink.stream import HTTPStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/gulli.py b/src/streamlink/plugins/gulli.py
index 50b7306c..00f86d6a 100644
--- a/src/streamlink/plugins/gulli.py
+++ b/src/streamlink/plugins/gulli.py
@@ -6,7 +6,6 @@ from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/hds.py b/src/streamlink/plugins/hds.py
index 4adad3b0..16299987 100644
--- a/src/streamlink/plugins/hds.py
+++ b/src/streamlink/plugins/hds.py
@@ -2,7 +2,7 @@ import re
 from urllib.parse import urlparse
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.plugin import parse_url_params, LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY
+from streamlink.plugin.plugin import LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY, parse_url_params
 from streamlink.stream import HDSStream
 from streamlink.utils import update_scheme
 
diff --git a/src/streamlink/plugins/hitbox.py b/src/streamlink/plugins/hitbox.py
index a512bcff..ada776d5 100644
--- a/src/streamlink/plugins/hitbox.py
+++ b/src/streamlink/plugins/hitbox.py
@@ -1,6 +1,6 @@
-from itertools import chain
 import logging
 import re
+from itertools import chain
 from urllib.parse import urlparse
 
 from streamlink.plugin import Plugin
@@ -8,7 +8,6 @@ from streamlink.plugin.api import StreamMapper, validate
 from streamlink.stream import HLSStream, HTTPStream, RTMPStream
 from streamlink.utils import absolute_url
 
-
 log = logging.getLogger(__name__)
 
 HLS_PLAYLIST_BASE = "http://www.smashcast.tv{0}"
diff --git a/src/streamlink/plugins/hls.py b/src/streamlink/plugins/hls.py
index 7431ba7b..99db3963 100644
--- a/src/streamlink/plugins/hls.py
+++ b/src/streamlink/plugins/hls.py
@@ -3,11 +3,10 @@ import re
 from urllib.parse import urlparse
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.plugin import parse_url_params, LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY
+from streamlink.plugin.plugin import LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY, parse_url_params
 from streamlink.stream import HLSStream
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/http.py b/src/streamlink/plugins/http.py
index 939d12cc..ff4bf63b 100644
--- a/src/streamlink/plugins/http.py
+++ b/src/streamlink/plugins/http.py
@@ -6,7 +6,6 @@ from streamlink.plugin.plugin import parse_url_params
 from streamlink.stream import HTTPStream
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/huajiao.py b/src/streamlink/plugins/huajiao.py
index 8aab15d7..fa2c6c34 100644
--- a/src/streamlink/plugins/huajiao.py
+++ b/src/streamlink/plugins/huajiao.py
@@ -1,14 +1,14 @@
 import base64
+import json
+import random
 import re
 import time
 import uuid
-import random
-import json
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.plugin.api.useragents import CHROME as USER_AGENT
-from streamlink.stream import (HTTPStream, HLSStream)
+from streamlink.stream import (HLSStream, HTTPStream)
 
 HUAJIAO_URL = "http://www.huajiao.com/l/{}"
 LAPI_URL = "http://g2.live.360.cn/liveplay?stype=flv&channel={}&bid=huajiao&sn={}&sid={}&_rate=xd&ts={}&r={}" \
diff --git a/src/streamlink/plugins/huya.py b/src/streamlink/plugins/huya.py
index 05383304..f2ed8100 100644
--- a/src/streamlink/plugins/huya.py
+++ b/src/streamlink/plugins/huya.py
@@ -1,9 +1,8 @@
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
-from streamlink.plugin.api import useragents
 from streamlink.utils import update_scheme
 
 HUYA_URL = "http://m.huya.com/%s"
diff --git a/src/streamlink/plugins/ine.py b/src/streamlink/plugins/ine.py
index 2475d25e..d875250c 100644
--- a/src/streamlink/plugins/ine.py
+++ b/src/streamlink/plugins/ine.py
@@ -7,7 +7,6 @@ from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/invintus.py b/src/streamlink/plugins/invintus.py
index 26629b98..c28c8128 100644
--- a/src/streamlink/plugins/invintus.py
+++ b/src/streamlink/plugins/invintus.py
@@ -1,8 +1,8 @@
-import re
 import json
+import re
 
-from streamlink.plugin.api import validate
 from streamlink.plugin import Plugin
+from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 from streamlink.utils.url import update_scheme
 
diff --git a/src/streamlink/plugins/kingkong.py b/src/streamlink/plugins/kingkong.py
index 4a4c1945..86161661 100644
--- a/src/streamlink/plugins/kingkong.py
+++ b/src/streamlink/plugins/kingkong.py
@@ -3,8 +3,7 @@ import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import HTTPStream, HLSStream
-
+from streamlink.stream import HLSStream, HTTPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/liveedu.py b/src/streamlink/plugins/liveedu.py
index 54b477aa..071b9f28 100644
--- a/src/streamlink/plugins/liveedu.py
+++ b/src/streamlink/plugins/liveedu.py
@@ -3,11 +3,9 @@ import re
 from urllib.parse import urljoin
 
 from streamlink import PluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
-from streamlink.stream import HLSStream
-from streamlink.stream import RTMPStream
-
+from streamlink.stream import HLSStream, RTMPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/liveme.py b/src/streamlink/plugins/liveme.py
index 420decc0..c8bbb260 100644
--- a/src/streamlink/plugins/liveme.py
+++ b/src/streamlink/plugins/liveme.py
@@ -1,13 +1,11 @@
 import logging
 import random
 import re
-from urllib.parse import urlparse, parse_qsl
+from urllib.parse import parse_qsl, urlparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import HLSStream
-from streamlink.stream import HTTPStream
-
+from streamlink.stream import HLSStream, HTTPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/mitele.py b/src/streamlink/plugins/mitele.py
index 8e0d62f1..602b888d 100644
--- a/src/streamlink/plugins/mitele.py
+++ b/src/streamlink/plugins/mitele.py
@@ -2,8 +2,7 @@ import logging
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 from streamlink.utils import parse_json
 
diff --git a/src/streamlink/plugins/mjunoon.py b/src/streamlink/plugins/mjunoon.py
index d22c1ac6..1497403c 100644
--- a/src/streamlink/plugins/mjunoon.py
+++ b/src/streamlink/plugins/mjunoon.py
@@ -1,6 +1,6 @@
 import logging
 import re
-from urllib.parse import urlparse, parse_qsl
+from urllib.parse import parse_qsl, urlparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
diff --git a/src/streamlink/plugins/nicolive.py b/src/streamlink/plugins/nicolive.py
index 6a641723..1399cfde 100644
--- a/src/streamlink/plugins/nicolive.py
+++ b/src/streamlink/plugins/nicolive.py
@@ -1,16 +1,16 @@
 import json
 import logging
 import re
-import websocket
 import threading
 import time
-from urllib.parse import urlparse, unquote_plus
+from urllib.parse import unquote_plus, urlparse
+
+import websocket
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 
-
 _log = logging.getLogger(__name__)
 
 _url_re = re.compile(
diff --git a/src/streamlink/plugins/nownews.py b/src/streamlink/plugins/nownews.py
index 759b9a7c..3d4a6f03 100644
--- a/src/streamlink/plugins/nownews.py
+++ b/src/streamlink/plugins/nownews.py
@@ -1,6 +1,6 @@
+import json
 import logging
 import re
-import json
 
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
diff --git a/src/streamlink/plugins/ntv.py b/src/streamlink/plugins/ntv.py
index f9ffe5d9..b41da234 100644
--- a/src/streamlink/plugins/ntv.py
+++ b/src/streamlink/plugins/ntv.py
@@ -1,4 +1,5 @@
 import re
+
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
 
diff --git a/src/streamlink/plugins/okru.py b/src/streamlink/plugins/okru.py
index 5f0c3e5e..d3538f7d 100644
--- a/src/streamlink/plugins/okru.py
+++ b/src/streamlink/plugins/okru.py
@@ -1,6 +1,6 @@
-from html import unescape as html_unescape
 import logging
 import re
+from html import unescape as html_unescape
 from urllib.parse import unquote
 
 from streamlink.exceptions import PluginError
diff --git a/src/streamlink/plugins/olympicchannel.py b/src/streamlink/plugins/olympicchannel.py
index 7ee38e54..7ea41a80 100644
--- a/src/streamlink/plugins/olympicchannel.py
+++ b/src/streamlink/plugins/olympicchannel.py
@@ -2,7 +2,7 @@ import json
 import logging
 import re
 from time import time
-from urllib.parse import urlparse, urljoin
+from urllib.parse import urljoin, urlparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
diff --git a/src/streamlink/plugins/oneplusone.py b/src/streamlink/plugins/oneplusone.py
index 0d0b7262..d0cb9b37 100644
--- a/src/streamlink/plugins/oneplusone.py
+++ b/src/streamlink/plugins/oneplusone.py
@@ -1,13 +1,12 @@
-from base64 import b64decode
-from html.parser import HTMLParser
 import logging
 import re
+from base64 import b64decode
+from html.parser import HTMLParser
 from urllib.parse import urlparse
 
 from streamlink.exceptions import PluginError
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 from streamlink.utils import parse_json
 
diff --git a/src/streamlink/plugins/onetv.py b/src/streamlink/plugins/onetv.py
index 389139ef..e6e6dcb9 100644
--- a/src/streamlink/plugins/onetv.py
+++ b/src/streamlink/plugins/onetv.py
@@ -1,14 +1,13 @@
 import logging
 import random
 import re
-from urllib.parse import urlencode, unquote, urljoin
+from urllib.parse import unquote, urlencode, urljoin
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.plugin import stream_weight
-from streamlink.stream import HLSStream, HTTPStream, DASHStream
+from streamlink.stream import DASHStream, HLSStream, HTTPStream
 from streamlink.utils import update_scheme
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/orf_tvthek.py b/src/streamlink/plugins/orf_tvthek.py
index 32369802..bf0df907 100644
--- a/src/streamlink/plugins/orf_tvthek.py
+++ b/src/streamlink/plugins/orf_tvthek.py
@@ -1,5 +1,5 @@
-import re
 import json
+import re
 
 from streamlink.plugin import Plugin, PluginError
 from streamlink.stream import HLSStream
diff --git a/src/streamlink/plugins/periscope.py b/src/streamlink/plugins/periscope.py
index 13264e00..80849847 100644
--- a/src/streamlink/plugins/periscope.py
+++ b/src/streamlink/plugins/periscope.py
@@ -6,7 +6,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 STREAM_INFO_URL = "https://api.periscope.tv/api/v2/getAccessPublic"
diff --git a/src/streamlink/plugins/picarto.py b/src/streamlink/plugins/picarto.py
index 8e7b1e4e..fa270e1d 100644
--- a/src/streamlink/plugins/picarto.py
+++ b/src/streamlink/plugins/picarto.py
@@ -4,11 +4,9 @@ import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import HLSStream
-from streamlink.stream import RTMPStream
+from streamlink.stream import HLSStream, RTMPStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/pixiv.py b/src/streamlink/plugins/pixiv.py
index 0a6b6771..6d9e5286 100644
--- a/src/streamlink/plugins/pixiv.py
+++ b/src/streamlink/plugins/pixiv.py
@@ -2,7 +2,7 @@ import logging
 import re
 
 from streamlink.exceptions import FatalPluginError, NoStreamsError, PluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 
diff --git a/src/streamlink/plugins/playtv.py b/src/streamlink/plugins/playtv.py
index 34db9c64..c0906f01 100644
--- a/src/streamlink/plugins/playtv.py
+++ b/src/streamlink/plugins/playtv.py
@@ -7,7 +7,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HDSStream, HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/pluzz.py b/src/streamlink/plugins/pluzz.py
index e2335334..19e38022 100644
--- a/src/streamlink/plugins/pluzz.py
+++ b/src/streamlink/plugins/pluzz.py
@@ -3,7 +3,7 @@ import re
 import sys
 import time
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.stream import DASHStream, HDSStream, HLSStream, HTTPStream
 from streamlink.stream.ffmpegmux import MuxedStream
diff --git a/src/streamlink/plugins/qq.py b/src/streamlink/plugins/qq.py
index 3154da6f..74c3fc26 100644
--- a/src/streamlink/plugins/qq.py
+++ b/src/streamlink/plugins/qq.py
@@ -7,7 +7,6 @@ from streamlink.plugin.api import validate
 from streamlink.plugin.api.utils import parse_json
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/radiko.py b/src/streamlink/plugins/radiko.py
index 33f69593..752b112d 100644
--- a/src/streamlink/plugins/radiko.py
+++ b/src/streamlink/plugins/radiko.py
@@ -3,8 +3,8 @@ import datetime
 import hashlib
 import random
 import re
-from urllib.parse import urlencode
 import xml.etree.ElementTree as ET
+from urllib.parse import urlencode
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
diff --git a/src/streamlink/plugins/radionet.py b/src/streamlink/plugins/radionet.py
index f54810c9..8d87d9a8 100644
--- a/src/streamlink/plugins/radionet.py
+++ b/src/streamlink/plugins/radionet.py
@@ -4,7 +4,7 @@ from urllib.parse import urlparse, urlunparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import HTTPStream, HLSStream
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import parse_json
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/raiplay.py b/src/streamlink/plugins/raiplay.py
index 4166bfb6..2f6d7767 100644
--- a/src/streamlink/plugins/raiplay.py
+++ b/src/streamlink/plugins/raiplay.py
@@ -7,7 +7,6 @@ from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/rtbf.py b/src/streamlink/plugins/rtbf.py
index 14dc0fe7..d8727c4e 100644
--- a/src/streamlink/plugins/rtbf.py
+++ b/src/streamlink/plugins/rtbf.py
@@ -1,14 +1,13 @@
 import datetime
-from html import unescape as html_unescape
 import logging
 import re
+from html import unescape as html_unescape
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import DASHStream, HLSStream, HTTPStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/rtlxl.py b/src/streamlink/plugins/rtlxl.py
index 8323e3fa..3cfaaae2 100644
--- a/src/streamlink/plugins/rtlxl.py
+++ b/src/streamlink/plugins/rtlxl.py
@@ -1,28 +1,28 @@
-import re
-import json
-
-from streamlink.plugin import Plugin
-from streamlink.stream import HLSStream
-
-_url_re = re.compile(r"http(?:s)?://(?:\w+\.)?rtl.nl/video/(?P<uuid>.*?)\Z", re.IGNORECASE)
-
-
-class rtlxl(Plugin):
-    @classmethod
-    def can_handle_url(cls, url):
-        return _url_re.match(url)
-
-    def _get_streams(self):
-        match = _url_re.match(self.url)
-        uuid = match.group("uuid")
-        videourlfeed = self.session.http.get(
-            'https://tm-videourlfeed.rtl.nl/api/url/{}?device=pc&drm&format=hls'.format(uuid)
-        ).text
-
-        videourlfeedjson = json.loads(videourlfeed)
-        playlist_url = videourlfeedjson["url"]
-
-        return HLSStream.parse_variant_playlist(self.session, playlist_url)
-
-
-__plugin__ = rtlxl
+import json
+import re
+
+from streamlink.plugin import Plugin
+from streamlink.stream import HLSStream
+
+_url_re = re.compile(r"http(?:s)?://(?:\w+\.)?rtl.nl/video/(?P<uuid>.*?)\Z", re.IGNORECASE)
+
+
+class rtlxl(Plugin):
+    @classmethod
+    def can_handle_url(cls, url):
+        return _url_re.match(url)
+
+    def _get_streams(self):
+        match = _url_re.match(self.url)
+        uuid = match.group("uuid")
+        videourlfeed = self.session.http.get(
+            'https://tm-videourlfeed.rtl.nl/api/url/{}?device=pc&drm&format=hls'.format(uuid)
+        ).text
+
+        videourlfeedjson = json.loads(videourlfeed)
+        playlist_url = videourlfeedjson["url"]
+
+        return HLSStream.parse_variant_playlist(self.session, playlist_url)
+
+
+__plugin__ = rtlxl
diff --git a/src/streamlink/plugins/rtmp.py b/src/streamlink/plugins/rtmp.py
index 6b902d3f..b4cdf11f 100644
--- a/src/streamlink/plugins/rtmp.py
+++ b/src/streamlink/plugins/rtmp.py
@@ -5,7 +5,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.plugin import parse_url_params
 from streamlink.stream import RTMPStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/rtve.py b/src/streamlink/plugins/rtve.py
index b8160999..c1f5b83e 100644
--- a/src/streamlink/plugins/rtve.py
+++ b/src/streamlink/plugins/rtve.py
@@ -5,12 +5,10 @@ from functools import partial
 
 from Crypto.Cipher import Blowfish
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
+from streamlink.plugin.api import useragents, validate
 from streamlink.plugin.api.utils import itertags
-from streamlink.stream import HLSStream
-from streamlink.stream import HTTPStream
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.stream.ffmpegmux import MuxedStream
 from streamlink.utils import parse_xml
 
diff --git a/src/streamlink/plugins/rtvs.py b/src/streamlink/plugins/rtvs.py
index 67cbedb3..40e344bc 100644
--- a/src/streamlink/plugins/rtvs.py
+++ b/src/streamlink/plugins/rtvs.py
@@ -2,7 +2,7 @@ import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import RTMPStream, HLSStream
+from streamlink.stream import HLSStream, RTMPStream
 
 RUURL = "b=chrome&p=win&v=56&f=0&d=1"
 
diff --git a/src/streamlink/plugins/sbscokr.py b/src/streamlink/plugins/sbscokr.py
index 543905ca..1c571704 100644
--- a/src/streamlink/plugins/sbscokr.py
+++ b/src/streamlink/plugins/sbscokr.py
@@ -2,7 +2,7 @@ import logging
 import random
 import re
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 
diff --git a/src/streamlink/plugins/schoolism.py b/src/streamlink/plugins/schoolism.py
index 4585d613..910c3ee7 100644
--- a/src/streamlink/plugins/schoolism.py
+++ b/src/streamlink/plugins/schoolism.py
@@ -2,9 +2,8 @@ import logging
 import re
 from functools import partial
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import parse_json
 
diff --git a/src/streamlink/plugins/senategov.py b/src/streamlink/plugins/senategov.py
index fc9fd3bf..b615a38e 100644
--- a/src/streamlink/plugins/senategov.py
+++ b/src/streamlink/plugins/senategov.py
@@ -1,6 +1,6 @@
 import logging
 import re
-from urllib.parse import urlparse, parse_qsl
+from urllib.parse import parse_qsl, urlparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
diff --git a/src/streamlink/plugins/showroom.py b/src/streamlink/plugins/showroom.py
index f0b41d9e..6e0aba55 100644
--- a/src/streamlink/plugins/showroom.py
+++ b/src/streamlink/plugins/showroom.py
@@ -2,11 +2,10 @@ import logging
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import validate, useragents
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream, RTMPStream
 from streamlink.stream.hls import HLSStreamReader, HLSStreamWorker
 
-
 log = logging.getLogger(__name__)
 
 _url_re = re.compile(r'''^https?://
diff --git a/src/streamlink/plugins/skai.py b/src/streamlink/plugins/skai.py
index 32083ec7..d49e17cf 100644
--- a/src/streamlink/plugins/skai.py
+++ b/src/streamlink/plugins/skai.py
@@ -3,7 +3,6 @@ import re
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 
-
 _url_re = re.compile(r'http(s)?://www\.skai(?:tv)?.gr/.*')
 _api_url = "http://www.skaitv.gr/json/live.php"
 _api_res_schema = validate.Schema(validate.all(
diff --git a/src/streamlink/plugins/stadium.py b/src/streamlink/plugins/stadium.py
index 27c003cc..1ecfb52a 100644
--- a/src/streamlink/plugins/stadium.py
+++ b/src/streamlink/plugins/stadium.py
@@ -1,5 +1,5 @@
-import re
 import logging
+import re
 
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
diff --git a/src/streamlink/plugins/steam.py b/src/streamlink/plugins/steam.py
index a07ced50..a383950c 100644
--- a/src/streamlink/plugins/steam.py
+++ b/src/streamlink/plugins/steam.py
@@ -1,15 +1,15 @@
 import base64
-from html import unescape as html_unescape
 import logging
 import re
 import time
+from html import unescape as html_unescape
 
 from Crypto.Cipher import PKCS1_v1_5
 from Crypto.PublicKey import RSA
 
 import streamlink
 from streamlink.exceptions import FatalPluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.plugin.api.utils import itertags, parse_json
 from streamlink.plugin.api.validate import Schema
diff --git a/src/streamlink/plugins/streamingvideoprovider.py b/src/streamlink/plugins/streamingvideoprovider.py
index 5cece121..e885cf90 100644
--- a/src/streamlink/plugins/streamingvideoprovider.py
+++ b/src/streamlink/plugins/streamingvideoprovider.py
@@ -4,8 +4,7 @@ from time import time
 
 from streamlink.plugin import Plugin, PluginError
 from streamlink.plugin.api import validate
-from streamlink.stream import RTMPStream, HLSStream
-
+from streamlink.stream import HLSStream, RTMPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/streann.py b/src/streamlink/plugins/streann.py
index d8b0ac07..0ed54d61 100644
--- a/src/streamlink/plugins/streann.py
+++ b/src/streamlink/plugins/streann.py
@@ -11,7 +11,6 @@ from streamlink.stream import HLSStream
 from streamlink.utils import parse_qsd
 from streamlink.utils.crypto import decrypt_openssl
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/svtplay.py b/src/streamlink/plugins/svtplay.py
index 285b932d..049c42e5 100644
--- a/src/streamlink/plugins/svtplay.py
+++ b/src/streamlink/plugins/svtplay.py
@@ -2,7 +2,7 @@ import logging
 import re
 from urllib.parse import urljoin
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.stream import DASHStream, HTTPStream
 from streamlink.stream.ffmpegmux import MuxedStream
diff --git a/src/streamlink/plugins/swisstxt.py b/src/streamlink/plugins/swisstxt.py
index c1632f69..f0bc1307 100644
--- a/src/streamlink/plugins/swisstxt.py
+++ b/src/streamlink/plugins/swisstxt.py
@@ -1,11 +1,10 @@
 import logging
 import re
-from urllib.parse import urlparse, parse_qsl, urlunparse
+from urllib.parse import parse_qsl, urlparse, urlunparse
 
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/tamago.py b/src/streamlink/plugins/tamago.py
index 0b6dc719..2da5de72 100644
--- a/src/streamlink/plugins/tamago.py
+++ b/src/streamlink/plugins/tamago.py
@@ -1,9 +1,9 @@
 import re
 
+from streamlink import NoStreamsError
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HTTPStream
-from streamlink import NoStreamsError
 
 
 class Tamago(Plugin):
diff --git a/src/streamlink/plugins/telefe.py b/src/streamlink/plugins/telefe.py
index b8f63023..08431320 100644
--- a/src/streamlink/plugins/telefe.py
+++ b/src/streamlink/plugins/telefe.py
@@ -6,7 +6,6 @@ from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/theplatform.py b/src/streamlink/plugins/theplatform.py
index 36747d37..d9bba898 100644
--- a/src/streamlink/plugins/theplatform.py
+++ b/src/streamlink/plugins/theplatform.py
@@ -4,7 +4,6 @@ import re
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/tigerdile.py b/src/streamlink/plugins/tigerdile.py
index 9ef0fa42..d7ac41f7 100644
--- a/src/streamlink/plugins/tigerdile.py
+++ b/src/streamlink/plugins/tigerdile.py
@@ -3,9 +3,7 @@ import logging
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.stream import RTMPStream
-from streamlink.stream import HLSStream
-
+from streamlink.stream import HLSStream, RTMPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/trt.py b/src/streamlink/plugins/trt.py
index 0a7aee53..979dfa5f 100644
--- a/src/streamlink/plugins/trt.py
+++ b/src/streamlink/plugins/trt.py
@@ -1,6 +1,6 @@
-from base64 import b64decode
 import logging
 import re
+from base64 import b64decode
 from urllib.parse import parse_qsl, urlparse
 
 from streamlink.plugin import Plugin
diff --git a/src/streamlink/plugins/trtspor.py b/src/streamlink/plugins/trtspor.py
index 5eaf2683..2d5fef6c 100644
--- a/src/streamlink/plugins/trtspor.py
+++ b/src/streamlink/plugins/trtspor.py
@@ -1,8 +1,7 @@
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.stream import HDSStream
-from streamlink.stream import HLSStream
+from streamlink.stream import HDSStream, HLSStream
 
 
 class TRTSpor(Plugin):
diff --git a/src/streamlink/plugins/turkuvaz.py b/src/streamlink/plugins/turkuvaz.py
index 47eff3b8..61cb3d04 100644
--- a/src/streamlink/plugins/turkuvaz.py
+++ b/src/streamlink/plugins/turkuvaz.py
@@ -2,11 +2,9 @@ import logging
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/tv3cat.py b/src/streamlink/plugins/tv3cat.py
index 50bd3ba7..31e0b6ab 100644
--- a/src/streamlink/plugins/tv3cat.py
+++ b/src/streamlink/plugins/tv3cat.py
@@ -2,8 +2,8 @@ import logging
 import re
 
 from streamlink.plugin import Plugin, PluginError
-from streamlink.stream import HLSStream
 from streamlink.plugin.api import validate
+from streamlink.stream import HLSStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/tv5monde.py b/src/streamlink/plugins/tv5monde.py
index b7c2c035..d0898446 100644
--- a/src/streamlink/plugins/tv5monde.py
+++ b/src/streamlink/plugins/tv5monde.py
@@ -2,9 +2,9 @@ import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
+from streamlink.plugins.common_jwplayer import _js_to_json
 from streamlink.stream import HLSStream, HTTPStream, RTMPStream
 from streamlink.utils import parse_json
-from streamlink.plugins.common_jwplayer import _js_to_json
 
 
 class TV5Monde(Plugin):
diff --git a/src/streamlink/plugins/tvp.py b/src/streamlink/plugins/tvp.py
index ba49eccf..a0f6b9f3 100644
--- a/src/streamlink/plugins/tvp.py
+++ b/src/streamlink/plugins/tvp.py
@@ -4,9 +4,7 @@ import re
 from streamlink.exceptions import PluginError
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
-from streamlink.stream import HLSStream
-from streamlink.stream import HTTPStream
-
+from streamlink.stream import HLSStream, HTTPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/tvplayer.py b/src/streamlink/plugins/tvplayer.py
index 94882b0d..9f3d09be 100644
--- a/src/streamlink/plugins/tvplayer.py
+++ b/src/streamlink/plugins/tvplayer.py
@@ -1,12 +1,10 @@
 import logging
 import re
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
-from streamlink.plugin.api import validate
-from streamlink.plugin.api import useragents
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/tvrby.py b/src/streamlink/plugins/tvrby.py
index 4c4f6e35..1c9ef40b 100644
--- a/src/streamlink/plugins/tvrby.py
+++ b/src/streamlink/plugins/tvrby.py
@@ -5,7 +5,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/tvrplus.py b/src/streamlink/plugins/tvrplus.py
index d1800b91..2120e149 100644
--- a/src/streamlink/plugins/tvrplus.py
+++ b/src/streamlink/plugins/tvrplus.py
@@ -2,11 +2,9 @@ import logging
 import re
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/twitcasting.py b/src/streamlink/plugins/twitcasting.py
index 99c5fcfc..e00be2a6 100644
--- a/src/streamlink/plugins/twitcasting.py
+++ b/src/streamlink/plugins/twitcasting.py
@@ -1,16 +1,16 @@
 import logging
 import re
-from urllib.parse import urlparse, unquote_plus
+from threading import Event, Thread
+from urllib.parse import unquote_plus, urlparse
+
 import websocket
 
 from streamlink import logger
 from streamlink.buffers import RingBuffer
 from streamlink.plugin import Plugin, PluginError
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
-from streamlink.stream import Stream
+from streamlink.plugin.api import useragents, validate
+from streamlink.stream.stream import Stream
 from streamlink.stream.stream import StreamIO
-from threading import Thread, Event
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/twitch.py b/src/streamlink/plugins/twitch.py
index 59b6193c..d4bf53ee 100644
--- a/src/streamlink/plugins/twitch.py
+++ b/src/streamlink/plugins/twitch.py
@@ -1,23 +1,22 @@
-from collections import namedtuple
 import json
 import logging
-from random import random
 import re
+from collections import namedtuple
+from random import random
 from urllib.parse import urlparse
 
 import requests
 
 from streamlink.exceptions import NoStreamsError, PluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.plugin.api.utils import parse_json, parse_query
-from streamlink.stream import HTTPStream, HLSStream
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.stream.hls import HLSStreamWorker
-from streamlink.stream.hls_filtered import FilteredHLSStreamWriter, FilteredHLSStreamReader
+from streamlink.stream.hls_filtered import FilteredHLSStreamReader, FilteredHLSStreamWriter
 from streamlink.stream.hls_playlist import M3U8, M3U8Parser, load as load_hls_playlist
 from streamlink.utils.times import hours_minutes_seconds
 
-
 log = logging.getLogger(__name__)
 
 Segment = namedtuple("Segment", "uri duration title key discontinuity ad byterange date map prefetch")
@@ -298,7 +297,7 @@ class TwitchAPI(object):
                 validate.get("sig"),
                 validate.get("token")
             ))
-        ))
+        ), player_type="frontpage")
 
     def token(self, tokenstr):
         return parse_json(tokenstr, schema=validate.Schema(
diff --git a/src/streamlink/plugins/ustreamtv.py b/src/streamlink/plugins/ustreamtv.py
index 7d637b49..58bff678 100644
--- a/src/streamlink/plugins/ustreamtv.py
+++ b/src/streamlink/plugins/ustreamtv.py
@@ -3,24 +3,22 @@ import errno
 import json
 import logging
 import re
-from urllib.parse import urljoin, urlunparse, urlparse, unquote_plus
-import websocket
-
 from collections import deque, namedtuple
 from random import randint
 from socket import error as SocketError
-from threading import Thread, Event
+from threading import Event, Thread
 from time import sleep
+from urllib.parse import unquote_plus, urljoin, urlparse, urlunparse
+
+import websocket
 
 from streamlink.exceptions import PluginError, StreamError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents, validate
-from streamlink.stream import Stream
 from streamlink.stream.dash_manifest import sleep_until, utc
 from streamlink.stream.flvconcat import FLVTagConcat
-from streamlink.stream.segmented import (
-    SegmentedStreamReader, SegmentedStreamWriter, SegmentedStreamWorker
-)
+from streamlink.stream.segmented import (SegmentedStreamReader, SegmentedStreamWorker, SegmentedStreamWriter)
+from streamlink.stream.stream import Stream
 from streamlink.utils import parse_json
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/ustvnow.py b/src/streamlink/plugins/ustvnow.py
index b0c25d96..36778fbf 100644
--- a/src/streamlink/plugins/ustvnow.py
+++ b/src/streamlink/plugins/ustvnow.py
@@ -10,7 +10,7 @@ from Crypto.Hash import SHA256
 from Crypto.Util.Padding import pad, unpad
 
 from streamlink import PluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.stream import HLSStream
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/viasat.py b/src/streamlink/plugins/viasat.py
index 7a456d4b..cc031cfd 100644
--- a/src/streamlink/plugins/viasat.py
+++ b/src/streamlink/plugins/viasat.py
@@ -8,7 +8,6 @@ from streamlink.plugin.api import StreamMapper, validate
 from streamlink.stream import HDSStream, HLSStream, RTMPStream
 from streamlink.utils import rtmpparse
 
-
 log = logging.getLogger(__name__)
 
 STREAM_API_URL = "https://playapi.mtgx.tv/v3/videos/stream/{0}"
diff --git a/src/streamlink/plugins/vidio.py b/src/streamlink/plugins/vidio.py
index bca36915..8d93d06f 100644
--- a/src/streamlink/plugins/vidio.py
+++ b/src/streamlink/plugins/vidio.py
@@ -11,7 +11,6 @@ from streamlink.plugin.api import useragents, validate
 from streamlink.stream import HLSStream
 from streamlink.utils import parse_json
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/vimeo.py b/src/streamlink/plugins/vimeo.py
index 01f7eb15..95180bee 100644
--- a/src/streamlink/plugins/vimeo.py
+++ b/src/streamlink/plugins/vimeo.py
@@ -1,9 +1,9 @@
-from html import unescape as html_unescape
 import logging
 import re
+from html import unescape as html_unescape
 from urllib.parse import urlparse
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import validate
 from streamlink.stream import DASHStream, HLSStream, HTTPStream
 from streamlink.stream.ffmpegmux import MuxedStream
diff --git a/src/streamlink/plugins/viutv.py b/src/streamlink/plugins/viutv.py
index 24b6cbb9..0eeacca9 100644
--- a/src/streamlink/plugins/viutv.py
+++ b/src/streamlink/plugins/viutv.py
@@ -1,8 +1,8 @@
 import datetime
+import json
 import logging
 import random
 import re
-import json
 
 from streamlink.plugin import Plugin
 from streamlink.stream import HLSStream
diff --git a/src/streamlink/plugins/vk.py b/src/streamlink/plugins/vk.py
index d9900c28..143cd57f 100644
--- a/src/streamlink/plugins/vk.py
+++ b/src/streamlink/plugins/vk.py
@@ -1,12 +1,12 @@
-from html import unescape as html_unescape
 import logging
 import re
-from urllib.parse import urlparse, unquote
+from html import unescape as html_unescape
+from urllib.parse import unquote, urlparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
 from streamlink.plugin.api.utils import itertags
-from streamlink.stream import HTTPStream, HLSStream
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.utils import update_scheme
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/plugins/vlive.py b/src/streamlink/plugins/vlive.py
index ba61a223..77cd3f9a 100644
--- a/src/streamlink/plugins/vlive.py
+++ b/src/streamlink/plugins/vlive.py
@@ -5,7 +5,6 @@ import re
 from streamlink.plugin import Plugin, PluginError
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/vrtbe.py b/src/streamlink/plugins/vrtbe.py
index c6633a0e..258c0136 100644
--- a/src/streamlink/plugins/vrtbe.py
+++ b/src/streamlink/plugins/vrtbe.py
@@ -5,7 +5,7 @@ from urllib.parse import urljoin
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
 from streamlink.plugin.api.utils import itertags
-from streamlink.stream import HLSStream, DASHStream
+from streamlink.stream import DASHStream, HLSStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/wasd.py b/src/streamlink/plugins/wasd.py
index 28a4289b..737aa421 100644
--- a/src/streamlink/plugins/wasd.py
+++ b/src/streamlink/plugins/wasd.py
@@ -3,8 +3,8 @@ import re
 
 from streamlink.exceptions import PluginError
 from streamlink.plugin import Plugin
-from streamlink.stream import HLSStream
 from streamlink.plugin.api import validate
+from streamlink.stream import HLSStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/plugins/webcast_india_gov.py b/src/streamlink/plugins/webcast_india_gov.py
index 8bf31bff..97be569a 100644
--- a/src/streamlink/plugins/webcast_india_gov.py
+++ b/src/streamlink/plugins/webcast_india_gov.py
@@ -5,7 +5,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/webtv.py b/src/streamlink/plugins/webtv.py
index 1e49e9ad..7f75710f 100644
--- a/src/streamlink/plugins/webtv.py
+++ b/src/streamlink/plugins/webtv.py
@@ -11,7 +11,6 @@ from streamlink.stream import HLSStream
 from streamlink.utils import parse_json, update_scheme
 from streamlink.utils.crypto import unpad_pkcs5
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/willax.py b/src/streamlink/plugins/willax.py
index e01640ac..c3aed2bd 100644
--- a/src/streamlink/plugins/willax.py
+++ b/src/streamlink/plugins/willax.py
@@ -1,6 +1,6 @@
-from html import unescape as html_unescape
 import logging
 import re
+from html import unescape as html_unescape
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
diff --git a/src/streamlink/plugins/wwenetwork.py b/src/streamlink/plugins/wwenetwork.py
index cf19883d..057f0b96 100644
--- a/src/streamlink/plugins/wwenetwork.py
+++ b/src/streamlink/plugins/wwenetwork.py
@@ -1,10 +1,10 @@
 import json
 import logging
 import re
-from urllib.parse import urlparse, parse_qsl
+from urllib.parse import parse_qsl, urlparse
 
 from streamlink import PluginError
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 from streamlink.utils import memoize
diff --git a/src/streamlink/plugins/youtube.py b/src/streamlink/plugins/youtube.py
index f4278c20..dde5c7a7 100644
--- a/src/streamlink/plugins/youtube.py
+++ b/src/streamlink/plugins/youtube.py
@@ -3,9 +3,9 @@ import re
 from urllib.parse import parse_qsl, urlparse, urlunparse
 
 from streamlink.plugin import Plugin, PluginError
-from streamlink.plugin.api import validate, useragents
+from streamlink.plugin.api import useragents, validate
 from streamlink.plugin.api.utils import itertags, parse_query
-from streamlink.stream import HTTPStream, HLSStream
+from streamlink.stream import HLSStream, HTTPStream
 from streamlink.stream.ffmpegmux import MuxedStream
 from streamlink.utils import parse_json, search_dict
 
diff --git a/src/streamlink/plugins/yupptv.py b/src/streamlink/plugins/yupptv.py
index cdddc711..f87c2414 100644
--- a/src/streamlink/plugins/yupptv.py
+++ b/src/streamlink/plugins/yupptv.py
@@ -2,11 +2,10 @@ import logging
 import re
 import time
 
-from streamlink.plugin import Plugin, PluginArguments, PluginArgument
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/zattoo.py b/src/streamlink/plugins/zattoo.py
index ce79fe98..9f25c3fc 100644
--- a/src/streamlink/plugins/zattoo.py
+++ b/src/streamlink/plugins/zattoo.py
@@ -6,10 +6,8 @@ from requests.cookies import cookiejar_from_dict
 
 from streamlink import PluginError
 from streamlink.cache import Cache
-from streamlink.plugin import Plugin
-from streamlink.plugin import PluginArguments, PluginArgument
-from streamlink.plugin.api import useragents
-from streamlink.plugin.api import validate
+from streamlink.plugin import Plugin, PluginArgument, PluginArguments
+from streamlink.plugin.api import useragents, validate
 from streamlink.stream import DASHStream, HLSStream
 from streamlink.utils.args import comma_list_filter
 
diff --git a/src/streamlink/plugins/zdf_mediathek.py b/src/streamlink/plugins/zdf_mediathek.py
index b9640c81..60f20e68 100644
--- a/src/streamlink/plugins/zdf_mediathek.py
+++ b/src/streamlink/plugins/zdf_mediathek.py
@@ -1,5 +1,6 @@
 import logging
 import re
+from urllib.parse import urlparse, urlunparse
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
@@ -7,11 +8,8 @@ from streamlink.stream import HDSStream, HLSStream
 from streamlink.utils import parse_json
 from streamlink.utils.url import url_concat
 
-
 log = logging.getLogger(__name__)
 
-API_URL = "https://api.zdf.de"
-
 QUALITY_WEIGHTS = {
     "hd": 720,
     "veryhigh": 480,
@@ -30,7 +28,7 @@ STREAMING_TYPES = {
 }
 
 _url_re = re.compile(r"""
-    http(s)?://(\w+\.)?zdf.de/
+    http(s)?://(\w+\.)?(zdf\.de|3sat\.de)/
 """, re.VERBOSE | re.IGNORECASE)
 _api_json_re = re.compile(r'''data-zdfplayer-jsb=["'](?P<json>{.+?})["']''', re.S)
 
@@ -141,10 +139,13 @@ class zdf_mediathek(Plugin):
         res = self.session.http.get(zdf_json['content'], headers=headers)
         document = self.session.http.json(res, schema=_documents_schema)
 
+        document_url_p = urlparse(zdf_json['content'])
+        api_url = urlunparse((document_url_p.scheme, document_url_p.netloc, "", "", "", ""))
+
         content = document["mainVideoContent"]
         target = content["http://zdf.de/rels/target"]
         template = target["http://zdf.de/rels/streams/ptmd-template"]
-        stream_request_url = url_concat(API_URL, template.format(playerId="ngplayer_2_3").replace(" ", ""))
+        stream_request_url = url_concat(api_url, template.format(playerId="ngplayer_2_3").replace(" ", ""))
 
         res = self.session.http.get(stream_request_url, headers=headers)
         res = self.session.http.json(res, schema=_schema)
diff --git a/src/streamlink/plugins/zengatv.py b/src/streamlink/plugins/zengatv.py
index 4fbaae35..1b6a330c 100644
--- a/src/streamlink/plugins/zengatv.py
+++ b/src/streamlink/plugins/zengatv.py
@@ -5,7 +5,6 @@ from streamlink.plugin import Plugin
 from streamlink.plugin.api import useragents
 from streamlink.stream import HLSStream
 
-
 log = logging.getLogger(__name__)
 
 
diff --git a/src/streamlink/plugins/zhanqi.py b/src/streamlink/plugins/zhanqi.py
index 65244150..48c98691 100644
--- a/src/streamlink/plugins/zhanqi.py
+++ b/src/streamlink/plugins/zhanqi.py
@@ -3,8 +3,7 @@ import re
 
 from streamlink.plugin import Plugin
 from streamlink.plugin.api import validate
-from streamlink.stream import HTTPStream, HLSStream
-
+from streamlink.stream import HLSStream, HTTPStream
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/session.py b/src/streamlink/session.py
index 4d773689..c8a9fd30 100644
--- a/src/streamlink/session.py
+++ b/src/streamlink/session.py
@@ -3,19 +3,18 @@ import logging
 import pkgutil
 import sys
 import traceback
+from collections import OrderedDict
 
 import requests
 
-from collections import OrderedDict
-
+from streamlink import __version__, plugins
+from streamlink.compat import is_win32
+from streamlink.exceptions import NoPluginError, PluginError
 from streamlink.logger import StreamlinkLogger
-from streamlink.utils import update_scheme, memoize
+from streamlink.options import Options
+from streamlink.plugin import api
+from streamlink.utils import memoize, update_scheme
 from streamlink.utils.l10n import Localization
-from . import plugins, __version__
-from .compat import is_win32
-from .exceptions import NoPluginError, PluginError
-from .options import Options
-from .plugin import api
 
 # Ensure that the Logger class returned is Streamslink's for using the API (for backwards compatibility)
 logging.setLoggerClass(StreamlinkLogger)
diff --git a/src/streamlink/stream/__init__.py b/src/streamlink/stream/__init__.py
index 003802a6..bef4ac42 100644
--- a/src/streamlink/stream/__init__.py
+++ b/src/streamlink/stream/__init__.py
@@ -1,14 +1,11 @@
-from ..exceptions import StreamError
-from streamlink.stream.stream import Stream
-
 from streamlink.stream.akamaihd import AkamaiHDStream
+from streamlink.stream.dash import DASHStream
+from streamlink.stream.flvconcat import extract_flv_header_tags
 from streamlink.stream.hds import HDSStream
 from streamlink.stream.hls import HLSStream
 from streamlink.stream.http import HTTPStream
+from streamlink.stream.playlist import FLVPlaylist, Playlist
 from streamlink.stream.rtmpdump import RTMPStream
-from streamlink.stream.dash import DASHStream
+from streamlink.stream.stream import Stream
 from streamlink.stream.streamprocess import StreamProcess
-from streamlink.stream.wrappers import StreamIOWrapper, StreamIOIterWrapper, StreamIOThreadWrapper
-
-from streamlink.stream.flvconcat import extract_flv_header_tags
-from streamlink.stream.playlist import Playlist, FLVPlaylist
+from streamlink.stream.wrappers import StreamIOIterWrapper, StreamIOThreadWrapper, StreamIOWrapper
diff --git a/src/streamlink/stream/akamaihd.py b/src/streamlink/stream/akamaihd.py
index 0a74e4b9..f59ac267 100644
--- a/src/streamlink/stream/akamaihd.py
+++ b/src/streamlink/stream/akamaihd.py
@@ -2,19 +2,17 @@ import base64
 import hashlib
 import hmac
 import io
+import logging
 import random
 from urllib.parse import urlparse
 
-from .stream import Stream
-from .wrappers import StreamIOThreadWrapper, StreamIOIterWrapper
-
-from ..buffers import Buffer
-from ..exceptions import StreamError
-from ..utils import swfdecompress
-
-from ..packages.flashmedia import FLV, FLVError
-from ..packages.flashmedia.tag import ScriptData
-import logging
+from streamlink.buffers import Buffer
+from streamlink.exceptions import StreamError
+from streamlink.packages.flashmedia import FLV, FLVError
+from streamlink.packages.flashmedia.tag import ScriptData
+from streamlink.stream.stream import Stream
+from streamlink.stream.wrappers import StreamIOIterWrapper, StreamIOThreadWrapper
+from streamlink.utils import swfdecompress
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/dash.py b/src/streamlink/stream/dash.py
index 3acc7c0f..a8d9fa68 100644
--- a/src/streamlink/stream/dash.py
+++ b/src/streamlink/stream/dash.py
@@ -7,12 +7,12 @@ from urllib.parse import urlparse, urlunparse
 
 import requests
 
-from streamlink import StreamError, PluginError
-from streamlink.stream.http import valid_args, normalize_key
-from streamlink.stream.stream import Stream
-from streamlink.stream.dash_manifest import MPD, sleeper, sleep_until, utc, freeze_timeline
+from streamlink import PluginError, StreamError
+from streamlink.stream.dash_manifest import MPD, freeze_timeline, sleep_until, sleeper, utc
 from streamlink.stream.ffmpegmux import FFMPEGMuxer
+from streamlink.stream.http import normalize_key, valid_args
 from streamlink.stream.segmented import SegmentedStreamReader, SegmentedStreamWorker, SegmentedStreamWriter
+from streamlink.stream.stream import Stream
 from streamlink.utils import parse_xml
 from streamlink.utils.l10n import Language
 
diff --git a/src/streamlink/stream/dash_manifest.py b/src/streamlink/stream/dash_manifest.py
index 3478254c..5acbf929 100644
--- a/src/streamlink/stream/dash_manifest.py
+++ b/src/streamlink/stream/dash_manifest.py
@@ -1,16 +1,15 @@
-from collections import defaultdict, namedtuple
-from contextlib import contextmanager
 import copy
 import datetime
-from itertools import repeat, count
 import logging
 import math
 import re
 import time
-from urllib.parse import urlparse, urljoin, urlunparse, urlsplit, urlunsplit
-
-from isodate import parse_datetime, parse_duration, Duration
+from collections import defaultdict, namedtuple
+from contextlib import contextmanager
+from itertools import count, repeat
+from urllib.parse import urljoin, urlparse, urlsplit, urlunparse, urlunsplit
 
+from isodate import Duration, parse_datetime, parse_duration
 
 if hasattr(datetime, "timezone"):
     utc = datetime.timezone.utc
diff --git a/src/streamlink/stream/ffmpegmux.py b/src/streamlink/stream/ffmpegmux.py
index 813c3f80..e1607262 100644
--- a/src/streamlink/stream/ffmpegmux.py
+++ b/src/streamlink/stream/ffmpegmux.py
@@ -1,17 +1,15 @@
 import logging
 import os
 import random
-from shutil import which
 import subprocess
 import sys
 import threading
+from shutil import which
 
 from streamlink import StreamError
-from streamlink.stream import Stream
-from streamlink.stream.stream import StreamIO
-from streamlink.utils import NamedPipe
 from streamlink.compat import devnull
-
+from streamlink.stream.stream import Stream, StreamIO
+from streamlink.utils import NamedPipe
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/file.py b/src/streamlink/stream/file.py
index e3bb0646..cdee2cfe 100644
--- a/src/streamlink/stream/file.py
+++ b/src/streamlink/stream/file.py
@@ -1,7 +1,7 @@
 """
 Stream wrapper around a file
 """
-from streamlink.stream import Stream
+from streamlink.stream.stream import Stream
 
 
 class FileStream(Stream):
diff --git a/src/streamlink/stream/flvconcat.py b/src/streamlink/stream/flvconcat.py
index 0c8b4727..f514b2ff 100644
--- a/src/streamlink/stream/flvconcat.py
+++ b/src/streamlink/stream/flvconcat.py
@@ -4,17 +4,13 @@ from io import IOBase
 from itertools import chain, islice
 from threading import Thread
 
-from ..buffers import RingBuffer
-from ..packages.flashmedia import FLVError
-from ..packages.flashmedia.tag import (AudioData, AACAudioData, VideoData,
-                                       AVCVideoData, VideoCommandFrame,
-                                       Header, ScriptData, Tag)
-from ..packages.flashmedia.tag import (AAC_PACKET_TYPE_SEQUENCE_HEADER,
-                                       AVC_PACKET_TYPE_SEQUENCE_HEADER,
-                                       AUDIO_CODEC_ID_AAC,
-                                       VIDEO_CODEC_ID_AVC,
-                                       TAG_TYPE_AUDIO,
-                                       TAG_TYPE_VIDEO)
+from streamlink.buffers import RingBuffer
+from streamlink.packages.flashmedia import FLVError
+from streamlink.packages.flashmedia.tag import (
+    AACAudioData, AAC_PACKET_TYPE_SEQUENCE_HEADER, AUDIO_CODEC_ID_AAC, AVCVideoData,
+    AVC_PACKET_TYPE_SEQUENCE_HEADER, AudioData, Header, ScriptData, TAG_TYPE_AUDIO,
+    TAG_TYPE_VIDEO, Tag, VIDEO_CODEC_ID_AVC, VideoCommandFrame, VideoData
+)
 
 __all__ = ["extract_flv_header_tags", "FLVTagConcat", "FLVTagConcatIO"]
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/stream/hds.py b/src/streamlink/stream/hds.py
index b093c2eb..750be252 100644
--- a/src/streamlink/stream/hds.py
+++ b/src/streamlink/stream/hds.py
@@ -1,11 +1,10 @@
-import logging
 import base64
 import hmac
+import logging
+import os.path
 import random
 import re
-import os.path
 import string
-
 from binascii import unhexlify
 from collections import namedtuple
 from copy import deepcopy
@@ -14,20 +13,16 @@ from io import BytesIO
 from math import ceil
 from urllib.parse import parse_qsl, urljoin, urlparse, urlunparse
 
-from .flvconcat import FLVTagConcat
-from .segmented import (SegmentedStreamReader,
-                        SegmentedStreamWriter,
-                        SegmentedStreamWorker)
-from .stream import Stream
-from .wrappers import StreamIOIterWrapper
-
-from ..cache import Cache
-from ..exceptions import StreamError, PluginError
-from ..utils import absolute_url, swfdecompress
-
-from ..packages.flashmedia import F4V, F4VError
-from ..packages.flashmedia.box import Box
-from ..packages.flashmedia.tag import ScriptData, Tag, TAG_TYPE_SCRIPT
+from streamlink.cache import Cache
+from streamlink.exceptions import PluginError, StreamError
+from streamlink.packages.flashmedia import F4V, F4VError
+from streamlink.packages.flashmedia.box import Box
+from streamlink.packages.flashmedia.tag import ScriptData, TAG_TYPE_SCRIPT, Tag
+from streamlink.stream.flvconcat import FLVTagConcat
+from streamlink.stream.segmented import (SegmentedStreamReader, SegmentedStreamWorker, SegmentedStreamWriter)
+from streamlink.stream.stream import Stream
+from streamlink.stream.wrappers import StreamIOIterWrapper
+from streamlink.utils import absolute_url, swfdecompress
 
 log = logging.getLogger(__name__)
 # Akamai HD player verification key
diff --git a/src/streamlink/stream/hls.py b/src/streamlink/stream/hls.py
index 8615b2b6..bb123abe 100644
--- a/src/streamlink/stream/hls.py
+++ b/src/streamlink/stream/hls.py
@@ -1,7 +1,7 @@
-from collections import defaultdict, namedtuple, OrderedDict
 import logging
 import re
 import struct
+from collections import OrderedDict, defaultdict, namedtuple
 from urllib.parse import urlparse
 
 from Crypto.Cipher import AES
@@ -11,9 +11,7 @@ from streamlink.exceptions import StreamError
 from streamlink.stream import hls_playlist
 from streamlink.stream.ffmpegmux import FFMPEGMuxer, MuxedStream
 from streamlink.stream.http import HTTPStream
-from streamlink.stream.segmented import (SegmentedStreamReader,
-                                         SegmentedStreamWriter,
-                                         SegmentedStreamWorker)
+from streamlink.stream.segmented import (SegmentedStreamReader, SegmentedStreamWorker, SegmentedStreamWriter)
 from streamlink.utils import LazyFormatter
 
 log = logging.getLogger(__name__)
diff --git a/src/streamlink/stream/hls_filtered.py b/src/streamlink/stream/hls_filtered.py
index f49248b7..0072b70b 100644
--- a/src/streamlink/stream/hls_filtered.py
+++ b/src/streamlink/stream/hls_filtered.py
@@ -1,8 +1,7 @@
 import logging
 from threading import Event
 
-from .hls import HLSStreamWriter, HLSStreamReader
-
+from streamlink.stream.hls import HLSStreamReader, HLSStreamWriter
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/hls_playlist.py b/src/streamlink/stream/hls_playlist.py
index 77ccc4b1..366e834e 100644
--- a/src/streamlink/stream/hls_playlist.py
+++ b/src/streamlink/stream/hls_playlist.py
@@ -1,14 +1,13 @@
+import logging
+import re
 from binascii import unhexlify
 from collections import namedtuple
 from datetime import timedelta
 from itertools import starmap
-import logging
-import re
 from urllib.parse import urljoin, urlparse
 
 from isodate import parse_datetime
 
-
 log = logging.getLogger(__name__)
 
 __all__ = ["load", "M3U8Parser"]
diff --git a/src/streamlink/stream/http.py b/src/streamlink/stream/http.py
index e7e4e26b..74289a48 100644
--- a/src/streamlink/stream/http.py
+++ b/src/streamlink/stream/http.py
@@ -3,8 +3,8 @@ from inspect import getfullargspec
 import requests
 
 from streamlink.exceptions import StreamError
-from streamlink.stream import Stream
-from streamlink.stream.wrappers import StreamIOThreadWrapper, StreamIOIterWrapper
+from streamlink.stream.stream import Stream
+from streamlink.stream.wrappers import StreamIOIterWrapper, StreamIOThreadWrapper
 
 
 def normalize_key(keyval):
diff --git a/src/streamlink/stream/playlist.py b/src/streamlink/stream/playlist.py
index b5924ea4..1813a064 100644
--- a/src/streamlink/stream/playlist.py
+++ b/src/streamlink/stream/playlist.py
@@ -1,8 +1,9 @@
-from .flvconcat import FLVTagConcatIO
-from .stream import Stream
-from ..exceptions import StreamError
 import logging
 
+from streamlink.exceptions import StreamError
+from streamlink.stream.flvconcat import FLVTagConcatIO
+from streamlink.stream.stream import Stream
+
 __all__ = ["Playlist", "FLVPlaylist"]
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/rtmpdump.py b/src/streamlink/stream/rtmpdump.py
index 5f2b6c61..bf17c1fa 100644
--- a/src/streamlink/stream/rtmpdump.py
+++ b/src/streamlink/stream/rtmpdump.py
@@ -1,14 +1,13 @@
 import logging
-from operator import itemgetter
 import re
-from shutil import which
 import subprocess
+from operator import itemgetter
+from shutil import which
 
 from streamlink import logger
-from streamlink.stream.streamprocess import StreamProcess
 from streamlink.exceptions import StreamError
-from streamlink.utils import rtmpparse, escape_librtmp
-
+from streamlink.stream.streamprocess import StreamProcess
+from streamlink.utils import escape_librtmp, rtmpparse
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/segmented.py b/src/streamlink/stream/segmented.py
index 106f056d..4601111c 100644
--- a/src/streamlink/stream/segmented.py
+++ b/src/streamlink/stream/segmented.py
@@ -1,12 +1,12 @@
-from concurrent import futures
-from concurrent.futures.thread import ThreadPoolExecutor
 import logging
 import queue
-from threading import Thread, Event
+from concurrent import futures
+from concurrent.futures.thread import ThreadPoolExecutor
 from sys import version_info
+from threading import Event, Thread
 
-from .stream import StreamIO
-from ..buffers import RingBuffer
+from streamlink.buffers import RingBuffer
+from streamlink.stream.stream import StreamIO
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/streamprocess.py b/src/streamlink/stream/streamprocess.py
index 4c984c1e..f8c20bc2 100644
--- a/src/streamlink/stream/streamprocess.py
+++ b/src/streamlink/stream/streamprocess.py
@@ -1,16 +1,15 @@
 import logging
-from operator import itemgetter
 import os.path
-from shutil import which
 import subprocess
 import tempfile
 import time
+from operator import itemgetter
+from shutil import which
 
-from streamlink.stream import Stream
-from streamlink.stream.wrappers import StreamIOThreadWrapper
 from streamlink.compat import devnull
 from streamlink.exceptions import StreamError
-
+from streamlink.stream.stream import Stream
+from streamlink.stream.wrappers import StreamIOThreadWrapper
 
 log = logging.getLogger(__name__)
 
diff --git a/src/streamlink/stream/wrappers.py b/src/streamlink/stream/wrappers.py
index d0306958..33370a2c 100644
--- a/src/streamlink/stream/wrappers.py
+++ b/src/streamlink/stream/wrappers.py
@@ -1,8 +1,7 @@
-from ..buffers import Buffer, RingBuffer
-
+import io
 from threading import Thread
 
-import io
+from streamlink.buffers import Buffer, RingBuffer
 
 
 class StreamIOWrapper(io.IOBase):
diff --git a/src/streamlink/utils/__init__.py b/src/streamlink/utils/__init__.py
index 2a06df6a..af6bc6a5 100644
--- a/src/streamlink/utils/__init__.py
+++ b/src/streamlink/utils/__init__.py
@@ -1,13 +1,13 @@
 import functools
 import json
 import re
-from urllib.parse import urljoin, urlparse, parse_qsl
 import xml.etree.ElementTree as ET
 import zlib
+from urllib.parse import parse_qsl, urljoin, urlparse
 
 from streamlink.exceptions import PluginError
-from streamlink.utils.named_pipe import NamedPipe
 from streamlink.utils.lazy_formatter import LazyFormatter
+from streamlink.utils.named_pipe import NamedPipe
 from streamlink.utils.url import update_scheme, url_equal
 
 
diff --git a/src/streamlink/utils/named_pipe.py b/src/streamlink/utils/named_pipe.py
index 747328a1..4e4c85d4 100644
--- a/src/streamlink/utils/named_pipe.py
+++ b/src/streamlink/utils/named_pipe.py
@@ -1,8 +1,7 @@
 import os
 import tempfile
 
-from ..compat import is_win32
-
+from streamlink.compat import is_win32
 
 if is_win32:
     from ctypes import windll, cast, c_ulong, c_void_p, byref
diff --git a/src/streamlink/utils/url.py b/src/streamlink/utils/url.py
index 7d08945d..35bbfb34 100644
--- a/src/streamlink/utils/url.py
+++ b/src/streamlink/utils/url.py
@@ -1,5 +1,5 @@
 from collections import OrderedDict
-from urllib.parse import urljoin, urlparse, urlunparse, parse_qsl, urlencode
+from urllib.parse import parse_qsl, urlencode, urljoin, urlparse, urlunparse
 
 
 def update_scheme(current, target):
diff --git a/src/streamlink_cli/__main__.py b/src/streamlink_cli/__main__.py
index b5af1d12..c81930c5 100644
--- a/src/streamlink_cli/__main__.py
+++ b/src/streamlink_cli/__main__.py
@@ -1,3 +1,3 @@
 if __name__ == "__main__":
-    from .main import main
+    from streamlink_cli.main import main
     main()
diff --git a/src/streamlink_cli/argparser.py b/src/streamlink_cli/argparser.py
index f1f6f8a9..3633da54 100644
--- a/src/streamlink_cli/argparser.py
+++ b/src/streamlink_cli/argparser.py
@@ -4,15 +4,13 @@ import re
 from string import printable
 from textwrap import dedent
 
-from streamlink import logger, __version__ as streamlink_version
+from streamlink import __version__ as streamlink_version, logger
 from streamlink.utils.args import (
     boolean, comma_list, comma_list_filter, filesize, keyvalue, num
 )
 from streamlink.utils.times import hours_minutes_seconds
-from .constants import (
-    STREAM_PASSTHROUGH, DEFAULT_PLAYER_ARGUMENTS, DEFAULT_STREAM_METADATA, SUPPORTED_PLAYERS
-)
-from .utils import find_default_player
+from streamlink_cli.constants import (DEFAULT_PLAYER_ARGUMENTS, DEFAULT_STREAM_METADATA, STREAM_PASSTHROUGH, SUPPORTED_PLAYERS)
+from streamlink_cli.utils import find_default_player
 
 _printable_re = re.compile(r"[{0}]".format(printable))
 _option_re = re.compile(r"""
diff --git a/src/streamlink_cli/console.py b/src/streamlink_cli/console.py
index 4cc8770b..e2482993 100644
--- a/src/streamlink_cli/console.py
+++ b/src/streamlink_cli/console.py
@@ -4,7 +4,7 @@ import sys
 from getpass import getpass
 
 from streamlink.plugin.plugin import UserInputRequester
-from .utils import JSONEncoder
+from streamlink_cli.utils import JSONEncoder
 
 log = logging.getLogger("streamlink.cli")
 
diff --git a/src/streamlink_cli/constants.py b/src/streamlink_cli/constants.py
index 08902ab3..443903c7 100644
--- a/src/streamlink_cli/constants.py
+++ b/src/streamlink_cli/constants.py
@@ -1,6 +1,6 @@
 import os
 
-from .compat import is_win32
+from streamlink_cli.compat import is_win32
 
 DEFAULT_PLAYER_ARGUMENTS = u"{filename}"
 DEFAULT_STREAM_METADATA = {
diff --git a/src/streamlink_cli/main.py b/src/streamlink_cli/main.py
index ca2a9865..e7ee8b7b 100644
--- a/src/streamlink_cli/main.py
+++ b/src/streamlink_cli/main.py
@@ -3,37 +3,33 @@ import errno
 import logging
 import os
 import platform
-from collections import OrderedDict
-from gettext import gettext
-
-import requests
-import sys
 import signal
-
+import sys
+from collections import OrderedDict
 from contextlib import closing
 from distutils.version import StrictVersion
 from functools import partial
+from gettext import gettext
 from itertools import chain
-from socks import __version__ as socks_version
 from time import sleep
+
+import requests
+from socks import __version__ as socks_version
 from websocket import __version__ as websocket_version
 
-from streamlink import __version__ as streamlink_version
-from streamlink import (Streamlink, StreamError, PluginError,
-                        NoPluginError)
+import streamlink.logger as logger
+from streamlink import NoPluginError, PluginError, StreamError, Streamlink, __version__ as streamlink_version
 from streamlink.cache import Cache
 from streamlink.exceptions import FatalPluginError
-from streamlink.stream import StreamProcess
 from streamlink.plugin import PluginOptions
+from streamlink.stream import StreamProcess
 from streamlink.utils import LazyFormatter
-
-import streamlink.logger as logger
-from .argparser import build_parser
-from .compat import stdout, is_win32
-from .console import ConsoleOutput, ConsoleUserInputRequester
-from .constants import CONFIG_FILES, PLUGINS_DIR, STREAM_SYNONYMS, DEFAULT_STREAM_METADATA
-from .output import FileOutput, PlayerOutput
-from .utils import NamedPipe, HTTPServer, ignored, progress, stream_to_url
+from streamlink_cli.argparser import build_parser
+from streamlink_cli.compat import is_win32, stdout
+from streamlink_cli.console import ConsoleOutput, ConsoleUserInputRequester
+from streamlink_cli.constants import CONFIG_FILES, DEFAULT_STREAM_METADATA, PLUGINS_DIR, STREAM_SYNONYMS
+from streamlink_cli.output import FileOutput, PlayerOutput
+from streamlink_cli.utils import HTTPServer, NamedPipe, ignored, progress, stream_to_url
 
 ACCEPTABLE_ERRNO = (errno.EPIPE, errno.EINVAL, errno.ECONNRESET)
 try:
diff --git a/src/streamlink_cli/output.py b/src/streamlink_cli/output.py
index 776b2f27..aad16d1e 100644
--- a/src/streamlink_cli/output.py
+++ b/src/streamlink_cli/output.py
@@ -5,9 +5,9 @@ import subprocess
 import sys
 from time import sleep
 
-from .compat import is_win32, stdout
-from .constants import DEFAULT_PLAYER_ARGUMENTS, SUPPORTED_PLAYERS
-from .utils import ignored
+from streamlink_cli.compat import is_win32, stdout
+from streamlink_cli.constants import DEFAULT_PLAYER_ARGUMENTS, SUPPORTED_PLAYERS
+from streamlink_cli.utils import ignored
 
 if is_win32:
     import msvcrt
diff --git a/src/streamlink_cli/utils/http_server.py b/src/streamlink_cli/utils/http_server.py
index 14aaf291..56409dee 100644
--- a/src/streamlink_cli/utils/http_server.py
+++ b/src/streamlink_cli/utils/http_server.py
@@ -1,5 +1,4 @@
 import socket
-
 from io import BytesIO
 
 try:
diff --git a/src/streamlink_cli/utils/named_pipe.py b/src/streamlink_cli/utils/named_pipe.py
index 5da983a3..97281532 100644
--- a/src/streamlink_cli/utils/named_pipe.py
+++ b/src/streamlink_cli/utils/named_pipe.py
@@ -1,6 +1,5 @@
 # These imports, while unused, are here to provide API compatibility for this module
-from streamlink.utils.named_pipe import NamedPipe
-from ..compat import is_win32
+from streamlink.compat import is_win32
 
 if is_win32:
     from streamlink.utils.named_pipe import (
@@ -10,3 +9,11 @@ if is_win32:
         PIPE_WAIT,
         PIPE_UNLIMITED_INSTANCES,
         INVALID_HANDLE_VALUE)
+
+__all__ = ['is_win32',
+           'PIPE_ACCESS_OUTBOUND',
+           'PIPE_TYPE_BYTE',
+           'PIPE_READMODE_BYTE',
+           'PIPE_WAIT',
+           'PIPE_UNLIMITED_INSTANCES',
+           'INVALID_HANDLE_VALUE']
diff --git a/src/streamlink_cli/utils/player.py b/src/streamlink_cli/utils/player.py
index 70c0012b..0c6266d8 100644
--- a/src/streamlink_cli/utils/player.py
+++ b/src/streamlink_cli/utils/player.py
@@ -1,7 +1,6 @@
 import os
-import sys
-
 import subprocess
+import sys
 
 
 def check_paths(exes, paths):
diff --git a/src/streamlink_cli/utils/progress.py b/src/streamlink_cli/utils/progress.py
index 5888da34..18e7ef55 100644
--- a/src/streamlink_cli/utils/progress.py
+++ b/src/streamlink_cli/utils/progress.py
@@ -1,10 +1,9 @@
 import sys
-
 from collections import deque
-from time import time
 from shutil import get_terminal_size
+from time import time
 
-from ..compat import is_win32
+from streamlink_cli.compat import is_win32
 
 PROGRESS_FORMATS = (
     "[download][{prefix}] Written {written} ({elapsed} @ {speed}/s)",


Test patch:
diff --git a/tests/mixins/stream_hls.py b/tests/mixins/stream_hls.py
index af9aae43..bcfde081 100644
--- a/tests/mixins/stream_hls.py
+++ b/tests/mixins/stream_hls.py
@@ -1,10 +1,10 @@
+import unittest
 from binascii import hexlify
 from collections import OrderedDict
 from functools import partial
 from threading import Event, Thread
 
 import requests_mock
-import unittest
 
 from streamlink import Streamlink
 from streamlink.stream.hls import HLSStream
diff --git a/tests/plugins/test_cbsnews.py b/tests/plugins/test_cbsnews.py
index addc4ac7..cd146e67 100644
--- a/tests/plugins/test_cbsnews.py
+++ b/tests/plugins/test_cbsnews.py
@@ -1,5 +1,7 @@
 import unittest  # noqa: F401
+
 import pytest
+
 from streamlink.plugins.cbsnews import CBSNews
 
 
diff --git a/tests/plugins/test_cubetv.py b/tests/plugins/test_cubetv.py
index fcf539d3..79828d5a 100644
--- a/tests/plugins/test_cubetv.py
+++ b/tests/plugins/test_cubetv.py
@@ -1,6 +1,7 @@
-from streamlink.plugins.cubetv import CubeTV
 import unittest
 
+from streamlink.plugins.cubetv import CubeTV
+
 
 class TestPluginCubeTV(unittest.TestCase):
     def test_can_handle_url(self):
diff --git a/tests/plugins/test_dash.py b/tests/plugins/test_dash.py
index e3c350cd..5fb58b2f 100644
--- a/tests/plugins/test_dash.py
+++ b/tests/plugins/test_dash.py
@@ -2,7 +2,7 @@ import unittest
 from unittest.mock import patch
 
 from streamlink import Streamlink
-from streamlink.plugin.plugin import LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY, BIT_RATE_WEIGHT_RATIO
+from streamlink.plugin.plugin import BIT_RATE_WEIGHT_RATIO, LOW_PRIORITY, NORMAL_PRIORITY, NO_PRIORITY
 from streamlink.plugins.dash import MPEGDASH
 
 
diff --git a/tests/plugins/test_garena.py b/tests/plugins/test_garena.py
index 547d6c50..6ac16332 100644
--- a/tests/plugins/test_garena.py
+++ b/tests/plugins/test_garena.py
@@ -1,6 +1,6 @@
 import json
 import unittest
-from unittest.mock import Mock, MagicMock
+from unittest.mock import MagicMock, Mock
 
 from streamlink import Streamlink
 from streamlink.plugin.api import HTTPSession
diff --git a/tests/plugins/test_kingkong.py b/tests/plugins/test_kingkong.py
index 311041bb..7f9cf43e 100644
--- a/tests/plugins/test_kingkong.py
+++ b/tests/plugins/test_kingkong.py
@@ -1,4 +1,5 @@
 import unittest
+
 from streamlink.plugins.kingkong import Kingkong
 
 
diff --git a/tests/plugins/test_mjunoon.py b/tests/plugins/test_mjunoon.py
index 445b2725..96a85cfb 100644
--- a/tests/plugins/test_mjunoon.py
+++ b/tests/plugins/test_mjunoon.py
@@ -1,5 +1,5 @@
 import unittest
-from unittest.mock import patch, Mock, ANY, call
+from unittest.mock import ANY, Mock, call, patch
 
 import requests_mock
 
diff --git a/tests/plugins/test_senategov.py b/tests/plugins/test_senategov.py
index 3ffc3f95..0cc194db 100644
--- a/tests/plugins/test_senategov.py
+++ b/tests/plugins/test_senategov.py
@@ -1,6 +1,7 @@
-from streamlink.plugins.senategov import SenateGov
 import unittest
 
+from streamlink.plugins.senategov import SenateGov
+
 
 class TestPluginSenateGov(unittest.TestCase):
     def test_can_handle_url(self):
diff --git a/tests/plugins/test_stadium.py b/tests/plugins/test_stadium.py
index d0154f07..6658c9a5 100644
--- a/tests/plugins/test_stadium.py
+++ b/tests/plugins/test_stadium.py
@@ -1,6 +1,7 @@
-from streamlink.plugins.stadium import Stadium
 import unittest
 
+from streamlink.plugins.stadium import Stadium
+
 
 class TestPluginStadium(unittest.TestCase):
     def test_can_handle_url(self):
diff --git a/tests/plugins/test_stream.py b/tests/plugins/test_stream.py
index 3bcddb92..dba35862 100644
--- a/tests/plugins/test_stream.py
+++ b/tests/plugins/test_stream.py
@@ -2,7 +2,7 @@ import unittest
 from unittest.mock import patch
 
 from streamlink import Streamlink
-from streamlink.plugin.plugin import stream_weight, parse_params
+from streamlink.plugin.plugin import parse_params, stream_weight
 from streamlink.stream import AkamaiHDStream, HLSStream, HTTPStream, RTMPStream
 
 
diff --git a/tests/plugins/test_tvplayer.py b/tests/plugins/test_tvplayer.py
index 7443a3a8..7143554d 100644
--- a/tests/plugins/test_tvplayer.py
+++ b/tests/plugins/test_tvplayer.py
@@ -1,5 +1,5 @@
 import unittest
-from unittest.mock import patch, Mock, ANY, MagicMock, call
+from unittest.mock import ANY, MagicMock, Mock, call, patch
 
 from streamlink import Streamlink
 from streamlink.plugin.api import HTTPSession
diff --git a/tests/plugins/test_twitch.py b/tests/plugins/test_twitch.py
index 2dd37929..7bfc78db 100644
--- a/tests/plugins/test_twitch.py
+++ b/tests/plugins/test_twitch.py
@@ -1,14 +1,13 @@
-from datetime import datetime, timedelta
 import unittest
+from datetime import datetime, timedelta
 from unittest.mock import MagicMock, call, patch
 
 import requests_mock
 
-from tests.mixins.stream_hls import Playlist, Tag, Segment as _Segment, TestMixinStreamHLS
-
 from streamlink import Streamlink
 from streamlink.plugin import PluginError
 from streamlink.plugins.twitch import Twitch, TwitchHLSStream
+from tests.mixins.stream_hls import Playlist, Segment as _Segment, Tag, TestMixinStreamHLS
 
 
 DATETIME_BASE = datetime(2000, 1, 1, 0, 0, 0, 0)
diff --git a/tests/plugins/test_zdf_mediathek.py b/tests/plugins/test_zdf_mediathek.py
index 0d006310..848cbb9b 100644
--- a/tests/plugins/test_zdf_mediathek.py
+++ b/tests/plugins/test_zdf_mediathek.py
@@ -16,6 +16,7 @@ class TestPluginzdf_mediathek(unittest.TestCase):
             'https://www.zdf.de/dokumentation/zdfinfo-doku/zdfinfo-live-beitrag-100.html',
             'https://www.zdf.de/comedy/heute-show/videos/diy-hazel-habeck-100.html',
             'https://www.zdf.de/nachrichten/heute-sendungen/so-wird-das-wetter-102.html',
+            'https://www.3sat.de/wissen/nano',
         ]
         for url in should_match:
             self.assertTrue(zdf_mediathek.can_handle_url(url))
diff --git a/tests/plugins/testplugin.py b/tests/plugins/testplugin.py
index 600eb546..3049e90c 100644
--- a/tests/plugins/testplugin.py
+++ b/tests/plugins/testplugin.py
@@ -1,11 +1,10 @@
 from io import BytesIO
 
 from streamlink import NoStreamsError
-from streamlink.plugins import Plugin
 from streamlink.options import Options
-from streamlink.stream import AkamaiHDStream, HLSStream, HTTPStream, RTMPStream, Stream
-
 from streamlink.plugin.api.support_plugin import testplugin_support
+from streamlink.plugins import Plugin
+from streamlink.stream import AkamaiHDStream, HLSStream, HTTPStream, RTMPStream, Stream
 
 
 class TestStream(Stream):
diff --git a/tests/resources/__init__.py b/tests/resources/__init__.py
index b1721ee5..0a096e5c 100644
--- a/tests/resources/__init__.py
+++ b/tests/resources/__init__.py
@@ -1,13 +1,12 @@
 import codecs
 import os.path
 import xml.etree.ElementTree as ET
+from contextlib import contextmanager
+from io import BytesIO
 
 import requests_mock
 import six
 
-from contextlib import contextmanager
-from io import BytesIO
-
 __here__ = os.path.abspath(os.path.dirname(__file__))
 
 
diff --git a/tests/streams/test_dash.py b/tests/streams/test_dash.py
index fb353093..d231970a 100644
--- a/tests/streams/test_dash.py
+++ b/tests/streams/test_dash.py
@@ -1,12 +1,11 @@
 import unittest
-from unittest.mock import MagicMock, patch, ANY, Mock, call
-
-from tests.resources import text, xml
+from unittest.mock import ANY, MagicMock, Mock, call, patch
 
 from streamlink import PluginError
 from streamlink.stream import DASHStream
 from streamlink.stream.dash import DASHStreamWorker
 from streamlink.stream.dash_manifest import MPD
+from tests.resources import text, xml
 
 
 class TestDASHStream(unittest.TestCase):
diff --git a/tests/streams/test_dash_parser.py b/tests/streams/test_dash_parser.py
index bc8dc081..8c5d8ae4 100644
--- a/tests/streams/test_dash_parser.py
+++ b/tests/streams/test_dash_parser.py
@@ -1,16 +1,15 @@
 import datetime
 import itertools
-from operator import attrgetter
 import unittest
+from operator import attrgetter
 from unittest.mock import Mock
 
 from freezegun import freeze_time
 from freezegun.api import FakeDatetime
 
+from streamlink.stream.dash_manifest import MPD, MPDParsers, MPDParsingError, Representation, utc
 from tests.resources import xml
 
-from streamlink.stream.dash_manifest import MPD, MPDParsers, MPDParsingError, utc, Representation
-
 
 class TestMPDParsers(unittest.TestCase):
     def test_utc(self):
diff --git a/tests/streams/test_hls.py b/tests/streams/test_hls.py
index 4d07b8d3..148eea11 100644
--- a/tests/streams/test_hls.py
+++ b/tests/streams/test_hls.py
@@ -1,16 +1,15 @@
 import os
 import unittest
-from unittest.mock import patch, Mock
+from unittest.mock import Mock, patch
 
-from Crypto.Cipher import AES
 import pytest
 import requests_mock
-
-from tests.mixins.stream_hls import Playlist, Tag, Segment, TestMixinStreamHLS
-from tests.resources import text
+from Crypto.Cipher import AES
 
 from streamlink.session import Streamlink
 from streamlink.stream import hls
+from tests.mixins.stream_hls import Playlist, Segment, Tag, TestMixinStreamHLS
+from tests.resources import text
 
 
 def pkcs7_encode(data, keySize):
diff --git a/tests/streams/test_hls_filtered.py b/tests/streams/test_hls_filtered.py
index 6546180b..5bf086cd 100644
--- a/tests/streams/test_hls_filtered.py
+++ b/tests/streams/test_hls_filtered.py
@@ -1,11 +1,10 @@
-from threading import Event
 import unittest
+from threading import Event
 from unittest.mock import MagicMock, call, patch
 
-from tests.mixins.stream_hls import Playlist, Segment, TestMixinStreamHLS
-
 from streamlink.stream.hls import HLSStream
-from streamlink.stream.hls_filtered import FilteredHLSStreamWriter, FilteredHLSStreamReader
+from streamlink.stream.hls_filtered import FilteredHLSStreamReader, FilteredHLSStreamWriter
+from tests.mixins.stream_hls import Playlist, Segment, TestMixinStreamHLS
 
 
 FILTERED = "filtered"
diff --git a/tests/streams/test_hls_playlist.py b/tests/streams/test_hls_playlist.py
index 69e8aeaa..811b3adc 100644
--- a/tests/streams/test_hls_playlist.py
+++ b/tests/streams/test_hls_playlist.py
@@ -1,12 +1,11 @@
-from datetime import datetime, timedelta
 import unittest
+from datetime import datetime, timedelta
 
 from isodate import tzinfo
 
+from streamlink.stream.hls_playlist import DateRange, Media, Resolution, Segment, StreamInfo, load
 from tests.resources import text
 
-from streamlink.stream.hls_playlist import load, StreamInfo, Resolution, Media, DateRange, Segment
-
 
 class TestHLSPlaylist(unittest.TestCase):
     def test_load(self):
diff --git a/tests/streams/test_stream_streamprocess.py b/tests/streams/test_stream_streamprocess.py
index 6bf4a11d..8a1ceccc 100644
--- a/tests/streams/test_stream_streamprocess.py
+++ b/tests/streams/test_stream_streamprocess.py
@@ -1,5 +1,5 @@
 import unittest
-from unittest.mock import patch, PropertyMock
+from unittest.mock import PropertyMock, patch
 
 import pytest
 
diff --git a/tests/streams/test_stream_to_url.py b/tests/streams/test_stream_to_url.py
index 4ad447b0..69d3c48d 100644
--- a/tests/streams/test_stream_to_url.py
+++ b/tests/streams/test_stream_to_url.py
@@ -1,5 +1,5 @@
 import unittest
-from unittest.mock import patch, PropertyMock
+from unittest.mock import PropertyMock, patch
 
 from streamlink import Streamlink
 from streamlink.plugins.filmon import FilmOnHLS
@@ -8,7 +8,7 @@ from streamlink.stream import HDSStream
 from streamlink.stream import HLSStream
 from streamlink.stream import HTTPStream
 from streamlink.stream import RTMPStream
-from streamlink.stream import Stream
+from streamlink.stream.stream import Stream
 from streamlink_cli.utils import stream_to_url
 
 
diff --git a/tests/test_api_http_session.py b/tests/test_api_http_session.py
index ab1f9971..6aa40a05 100644
--- a/tests/test_api_http_session.py
+++ b/tests/test_api_http_session.py
@@ -1,5 +1,5 @@
 import unittest
-from unittest.mock import patch, PropertyMock
+from unittest.mock import PropertyMock, patch
 
 import requests
 
diff --git a/tests/test_api_validate.py b/tests/test_api_validate.py
index e6282711..e5e55bc8 100644
--- a/tests/test_api_validate.py
+++ b/tests/test_api_validate.py
@@ -1,12 +1,11 @@
 import re
 import unittest
-
 from xml.etree.ElementTree import Element
 
 from streamlink.plugin.api.validate import (
-    validate, all, any, optional, transform, text, filter, map, hasattr,
-    get, getattr, length, xml_element, xml_find, xml_findtext, xml_findall,
-    union, attr, url, startswith, endswith
+    all, any, attr, endswith, filter, get, getattr, hasattr,
+    length, map, optional, startswith, text, transform, union, url,
+    validate, xml_element, xml_find, xml_findall, xml_findtext
 )
 
 
diff --git a/tests/test_cache.py b/tests/test_cache.py
index c7b6b680..712d2c4f 100644
--- a/tests/test_cache.py
+++ b/tests/test_cache.py
@@ -1,8 +1,8 @@
 import datetime
 import os.path
-from shutil import rmtree
 import tempfile
 import unittest
+from shutil import rmtree
 from unittest.mock import patch
 
 import streamlink.cache
diff --git a/tests/test_cli_main.py b/tests/test_cli_main.py
index 365b352b..20177921 100644
--- a/tests/test_cli_main.py
+++ b/tests/test_cli_main.py
@@ -4,9 +4,9 @@ import unittest
 from unittest.mock import Mock, patch
 
 import streamlink_cli.main
-from streamlink_cli.main import resolve_stream_name, format_valid_streams, check_file_output, create_output
-from streamlink_cli.output import FileOutput, PlayerOutput
 from streamlink.plugin.plugin import Plugin
+from streamlink_cli.main import check_file_output, create_output, format_valid_streams, resolve_stream_name
+from streamlink_cli.output import FileOutput, PlayerOutput
 
 
 class FakePlugin:
diff --git a/tests/test_cli_playerout.py b/tests/test_cli_playerout.py
index 51d91c18..6357ba43 100644
--- a/tests/test_cli_playerout.py
+++ b/tests/test_cli_playerout.py
@@ -1,6 +1,7 @@
+from unittest.mock import ANY, patch
+
 from streamlink_cli.output import PlayerOutput
 from tests import posix_only, windows_only
-from unittest.mock import patch, ANY
 
 UNICODE_TITLE = u"기타치는소율 with UL섬 "
 
diff --git a/tests/test_cli_util_progress.py b/tests/test_cli_util_progress.py
index d6e9bb8d..69152a19 100644
--- a/tests/test_cli_util_progress.py
+++ b/tests/test_cli_util_progress.py
@@ -1,6 +1,7 @@
-from streamlink_cli.utils.progress import terminal_width, get_cut_prefix
 import unittest
 
+from streamlink_cli.utils.progress import get_cut_prefix, terminal_width
+
 
 class TestCliUtilProgess(unittest.TestCase):
     def test_terminal_width(self):
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index c85dde47..98cb6122 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -1,9 +1,9 @@
 import os.path
 import unittest
-from unittest.mock import patch, ANY
+from unittest.mock import ANY, patch
 
-from streamlink import Streamlink
 import streamlink_cli.main
+from streamlink import Streamlink
 from streamlink_cli.compat import is_win32
 
 
diff --git a/tests/test_console.py b/tests/test_console.py
index 43e300f7..ddb85948 100644
--- a/tests/test_console.py
+++ b/tests/test_console.py
@@ -1,5 +1,5 @@
-from io import StringIO
 import unittest
+from io import StringIO
 from unittest.mock import patch
 
 from streamlink_cli.console import ConsoleOutput
diff --git a/tests/test_log.py b/tests/test_log.py
index 69c6e405..0f11a400 100644
--- a/tests/test_log.py
+++ b/tests/test_log.py
@@ -1,7 +1,7 @@
-from datetime import datetime
-from io import StringIO
 import logging
 import unittest
+from datetime import datetime
+from io import StringIO
 
 import freezegun
 
diff --git a/tests/test_options.py b/tests/test_options.py
index 1dc0bc6f..8fc36a26 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -1,8 +1,8 @@
 import unittest
 from unittest.mock import Mock
 
+from streamlink.options import Argument, Arguments, Options
 from streamlink_cli.main import setup_plugin_args
-from streamlink.options import Options, Arguments, Argument
 
 
 class TestOptions(unittest.TestCase):
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
index 9221863b..6eb18837 100644
--- a/tests/test_plugins.py
+++ b/tests/test_plugins.py
@@ -1,10 +1,10 @@
 import imp
 import os.path
 import pkgutil
-import six
-
 import unittest
 
+import six
+
 import streamlink.plugins
 from streamlink import Streamlink
 from streamlink.utils import load_module
diff --git a/tests/test_plugins_input.py b/tests/test_plugins_input.py
index 39f43b11..011dbcad 100644
--- a/tests/test_plugins_input.py
+++ b/tests/test_plugins_input.py
@@ -1,13 +1,12 @@
-from contextlib import contextmanager
 import os.path
 import unittest
+from contextlib import contextmanager
 from unittest.mock import MagicMock, patch
 
-from tests.plugins.testplugin import TestPlugin as _TestPlugin
-
-from streamlink import Streamlink, PluginError
-from streamlink_cli.console import ConsoleUserInputRequester
+from streamlink import PluginError, Streamlink
 from streamlink.plugin.plugin import UserInputRequester
+from streamlink_cli.console import ConsoleUserInputRequester
+from tests.plugins.testplugin import TestPlugin as _TestPlugin
 
 
 class TestPluginUserInput(unittest.TestCase):
diff --git a/tests/test_plugins_meta.py b/tests/test_plugins_meta.py
index 541b096f..dcd4c0d3 100644
--- a/tests/test_plugins_meta.py
+++ b/tests/test_plugins_meta.py
@@ -1,8 +1,8 @@
 import os.path
 import re
 import unittest
-
 from glob import glob
+
 from streamlink import Streamlink
 
 
diff --git a/tests/test_session.py b/tests/test_session.py
index cc87bd98..488dba95 100644
--- a/tests/test_session.py
+++ b/tests/test_session.py
@@ -1,8 +1,8 @@
 import os
 import unittest
-from unittest.mock import patch, call
+from unittest.mock import call, patch
 
-from streamlink import Streamlink, NoPluginError
+from streamlink import NoPluginError, Streamlink
 from streamlink.plugin.plugin import HIGH_PRIORITY, LOW_PRIORITY
 from streamlink.plugins import Plugin
 from streamlink.session import print_small_exception
diff --git a/tests/test_stream_file.py b/tests/test_stream_file.py
index c2c654e4..e88111f4 100644
--- a/tests/test_stream_file.py
+++ b/tests/test_stream_file.py
@@ -1,5 +1,5 @@
 import unittest
-from unittest.mock import Mock, patch, mock_open
+from unittest.mock import Mock, mock_open, patch
 
 from streamlink import Streamlink
 from streamlink.stream.file import FileStream
diff --git a/tests/test_stream_json.py b/tests/test_stream_json.py
index 967672f2..b7c2afe3 100644
--- a/tests/test_stream_json.py
+++ b/tests/test_stream_json.py
@@ -6,7 +6,7 @@ from streamlink.stream import HDSStream
 from streamlink.stream import HLSStream
 from streamlink.stream import HTTPStream
 from streamlink.stream import RTMPStream
-from streamlink.stream import Stream
+from streamlink.stream.stream import Stream
 
 
 class TestStreamToJSON(unittest.TestCase):
diff --git a/tests/test_utils.py b/tests/test_utils.py
index c59d5af5..3416c7c5 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -5,8 +5,8 @@ import unittest
 import xml.etree.ElementTree as ET
 
 from streamlink.exceptions import PluginError
-from streamlink.plugin.api.validate import xml_element, text
 from streamlink.plugin.api import validate
+from streamlink.plugin.api.validate import text, xml_element
 from streamlink.utils import (
     absolute_url,
     load_module,
diff --git a/tests/test_utils_args.py b/tests/test_utils_args.py
index b1d9e94e..7d287732 100644
--- a/tests/test_utils_args.py
+++ b/tests/test_utils_args.py
@@ -1,6 +1,6 @@
 import unittest
-
 from argparse import ArgumentTypeError
+
 from streamlink.utils.args import (
     boolean, comma_list, comma_list_filter, filesize, keyvalue, num
 )
diff --git a/tests/test_utils_crypto.py b/tests/test_utils_crypto.py
index 9e4c2b4d..a2386aec 100644
--- a/tests/test_utils_crypto.py
+++ b/tests/test_utils_crypto.py
@@ -1,8 +1,7 @@
 import base64
-
 import unittest
 
-from streamlink.utils.crypto import evp_bytestokey, decrypt_openssl
+from streamlink.utils.crypto import decrypt_openssl, evp_bytestokey
 
 
 class TestUtil(unittest.TestCase):
diff --git a/tests/test_utils_url.py b/tests/test_utils_url.py
index fc9f2694..eb87e6df 100644
--- a/tests/test_utils_url.py
+++ b/tests/test_utils_url.py
@@ -1,8 +1,6 @@
 from collections import OrderedDict
 
-from streamlink.utils.url import (
-    update_scheme, url_equal, url_concat, update_qsd
-)
+from streamlink.utils.url import update_qsd, update_scheme, url_concat, url_equal
 
 
 def test_update_scheme():