We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[HiDive]: Login fails when both cookies and netrc are given
### Checklist

- [X] I'm reporting a broken site
- [X] I've verified that I'm running yt-dlp version **2022.03.08.1** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)
- [X] I've checked that all provided URLs are alive and playable in a browser
- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/ytdl-org/youtube-dl#video-url-contains-an-ampersand-and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)
- [X] I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues including closed ones. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)
- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and I'm willing to share it if required

### Region

United States

### Description

When I try to download from HIDIVE without a `cookies.txt` it uses my netrc credentials and successfully downloads. Once I run the command again using the `cookies.txt` that `yt-dlp` dumps from the successful download, I get the error message shown in the logs. I get the same error message when I use a `cookies.txt` dumped from my browser. Funimation and Crunchyroll both work with the `cookies.txt` dumped from my browser.

The issue persists when trying from different countries using a vpn.

Also, I install and update `yt-dlp` with `pip3 install --force-reinstall -I https://github.com/yt-dlp/yt-dlp/archive/master.zip`

### Verbose log

```shell
[debug] Command-line config: ['-vU', '-N', '32', '--embed-subs', '--remux-video', 'mkv', '-a', 'batch_file', '-o', 'S%(season_number)02dE%(episode_number)02d.%(ext)s']
[debug] User config "/home/{user}/.config/yt-dlp/config": ['--netrc', '--cookies', '~/.config/yt-dlp/cookies.txt']
[debug] Batch file urls: ['https://www.hidive.com/stream/made-in-abyss/s01e001']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8
[debug] yt-dlp version 2022.03.08.1 [c0c2c57d3]
[debug] Lazy loading extractors is disabled
[debug] Python version 3.8.10 (CPython 64bit) - Linux-5.4.0-100-generic-x86_64-with-glibc2.29
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg 4.2.4, ffprobe 4.2.4, phantomjs 2.1.1, rtmpdump 2.4
[debug] Optional libraries: brotli, certifi, Cryptodome, secretstorage, mutagen, sqlite, websockets
[debug] Proxy map: {}
Latest version: 2022.03.08.1, Current version: 2022.03.08.1
yt-dlp is up to date (2022.03.08.1)
[HiDive] None: Downloading webpage
ERROR: [HiDive] made-in-abyss/s01e001: Unable to extract login form; please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py", line 639, in extract
    self.initialize()
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py", line 544, in initialize
    self._perform_login(username, password)
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/hidive.py", line 40, in _perform_login
    form = self._search_regex(
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py", line 1229, in _search_regex
    raise RegexNotFoundError('Unable to extract %s' % _name)
```

[HiDive]: Login fails when both cookies and netrc are given
### Checklist

- [X] I'm reporting a broken site
- [X] I've verified that I'm running yt-dlp version **2022.03.08.1** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)
- [X] I've checked that all provided URLs are alive and playable in a browser
- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/ytdl-org/youtube-dl#video-url-contains-an-ampersand-and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)
- [X] I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues including closed ones. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)
- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and I'm willing to share it if required

### Region

United States

### Description

When I try to download from HIDIVE without a `cookies.txt` it uses my netrc credentials and successfully downloads. Once I run the command again using the `cookies.txt` that `yt-dlp` dumps from the successful download, I get the error message shown in the logs. I get the same error message when I use a `cookies.txt` dumped from my browser. Funimation and Crunchyroll both work with the `cookies.txt` dumped from my browser.

The issue persists when trying from different countries using a vpn.

Also, I install and update `yt-dlp` with `pip3 install --force-reinstall -I https://github.com/yt-dlp/yt-dlp/archive/master.zip`

### Verbose log

```shell
[debug] Command-line config: ['-vU', '-N', '32', '--embed-subs', '--remux-video', 'mkv', '-a', 'batch_file', '-o', 'S%(season_number)02dE%(episode_number)02d.%(ext)s']
[debug] User config "/home/{user}/.config/yt-dlp/config": ['--netrc', '--cookies', '~/.config/yt-dlp/cookies.txt']
[debug] Batch file urls: ['https://www.hidive.com/stream/made-in-abyss/s01e001']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8
[debug] yt-dlp version 2022.03.08.1 [c0c2c57d3]
[debug] Lazy loading extractors is disabled
[debug] Python version 3.8.10 (CPython 64bit) - Linux-5.4.0-100-generic-x86_64-with-glibc2.29
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg 4.2.4, ffprobe 4.2.4, phantomjs 2.1.1, rtmpdump 2.4
[debug] Optional libraries: brotli, certifi, Cryptodome, secretstorage, mutagen, sqlite, websockets
[debug] Proxy map: {}
Latest version: 2022.03.08.1, Current version: 2022.03.08.1
yt-dlp is up to date (2022.03.08.1)
[HiDive] None: Downloading webpage
ERROR: [HiDive] made-in-abyss/s01e001: Unable to extract login form; please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py", line 639, in extract
    self.initialize()
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py", line 544, in initialize
    self._perform_login(username, password)
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/hidive.py", line 40, in _perform_login
    form = self._search_regex(
  File "/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py", line 1229, in _search_regex
    raise RegexNotFoundError('Unable to extract %s' % _name)
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `yt_dlp/extractor/hidive.py`
Content:
```
1 import re
2 
3 from .common import InfoExtractor
4 from ..utils import (
5     ExtractorError,
6     int_or_none,
7     try_get,
8     url_or_none,
9     urlencode_postdata,
10 )
11 
12 
13 class HiDiveIE(InfoExtractor):
14     _VALID_URL = r'https?://(?:www\.)?hidive\.com/stream/(?P<id>(?P<title>[^/]+)/(?P<key>[^/?#&]+))'
15     # Using X-Forwarded-For results in 403 HTTP error for HLS fragments,
16     # so disabling geo bypass completely
17     _GEO_BYPASS = False
18     _NETRC_MACHINE = 'hidive'
19     _LOGIN_URL = 'https://www.hidive.com/account/login'
20 
21     _TESTS = [{
22         'url': 'https://www.hidive.com/stream/the-comic-artist-and-his-assistants/s01e001',
23         'info_dict': {
24             'id': 'the-comic-artist-and-his-assistants/s01e001',
25             'ext': 'mp4',
26             'title': 'the-comic-artist-and-his-assistants/s01e001',
27             'series': 'the-comic-artist-and-his-assistants',
28             'season_number': 1,
29             'episode_number': 1,
30         },
31         'params': {
32             'skip_download': True,
33         },
34         'skip': 'Requires Authentication',
35     }]
36 
37     def _perform_login(self, username, password):
38         webpage = self._download_webpage(self._LOGIN_URL, None)
39         form = self._search_regex(
40             r'(?s)<form[^>]+action="/account/login"[^>]*>(.+?)</form>',
41             webpage, 'login form')
42         data = self._hidden_inputs(form)
43         data.update({
44             'Email': username,
45             'Password': password,
46         })
47         self._download_webpage(
48             self._LOGIN_URL, None, 'Logging in', data=urlencode_postdata(data))
49 
50     def _call_api(self, video_id, title, key, data={}, **kwargs):
51         data = {
52             **data,
53             'Title': title,
54             'Key': key,
55             'PlayerId': 'f4f895ce1ca713ba263b91caeb1daa2d08904783',
56         }
57         return self._download_json(
58             'https://www.hidive.com/play/settings', video_id,
59             data=urlencode_postdata(data), **kwargs) or {}
60 
61     def _extract_subtitles_from_rendition(self, rendition, subtitles, parsed_urls):
62         for cc_file in rendition.get('ccFiles', []):
63             cc_url = url_or_none(try_get(cc_file, lambda x: x[2]))
64             # name is used since we cant distinguish subs with same language code
65             cc_lang = try_get(cc_file, (lambda x: x[1].replace(' ', '-').lower(), lambda x: x[0]), str)
66             if cc_url not in parsed_urls and cc_lang:
67                 parsed_urls.add(cc_url)
68                 subtitles.setdefault(cc_lang, []).append({'url': cc_url})
69 
70     def _get_subtitles(self, url, video_id, title, key, parsed_urls):
71         webpage = self._download_webpage(url, video_id, fatal=False) or ''
72         subtitles = {}
73         for caption in set(re.findall(r'data-captions=\"([^\"]+)\"', webpage)):
74             renditions = self._call_api(
75                 video_id, title, key, {'Captions': caption}, fatal=False,
76                 note=f'Downloading {caption} subtitle information').get('renditions') or {}
77             for rendition_id, rendition in renditions.items():
78                 self._extract_subtitles_from_rendition(rendition, subtitles, parsed_urls)
79         return subtitles
80 
81     def _real_extract(self, url):
82         video_id, title, key = self._match_valid_url(url).group('id', 'title', 'key')
83         settings = self._call_api(video_id, title, key)
84 
85         restriction = settings.get('restrictionReason')
86         if restriction == 'RegionRestricted':
87             self.raise_geo_restricted()
88         if restriction and restriction != 'None':
89             raise ExtractorError(
90                 '%s said: %s' % (self.IE_NAME, restriction), expected=True)
91 
92         formats, parsed_urls = [], {None}
93         for rendition_id, rendition in settings['renditions'].items():
94             audio, version, extra = rendition_id.split('_')
95             m3u8_url = url_or_none(try_get(rendition, lambda x: x['bitrates']['hls']))
96             if m3u8_url not in parsed_urls:
97                 parsed_urls.add(m3u8_url)
98                 frmt = self._extract_m3u8_formats(
99                     m3u8_url, video_id, 'mp4', entry_protocol='m3u8_native', m3u8_id=rendition_id, fatal=False)
100                 for f in frmt:
101                     f['language'] = audio
102                     f['format_note'] = f'{version}, {extra}'
103                 formats.extend(frmt)
104         self._sort_formats(formats)
105 
106         return {
107             'id': video_id,
108             'title': video_id,
109             'subtitles': self.extract_subtitles(url, video_id, title, key, parsed_urls),
110             'formats': formats,
111             'series': title,
112             'season_number': int_or_none(
113                 self._search_regex(r's(\d+)', key, 'season number', default=None)),
114             'episode_number': int_or_none(
115                 self._search_regex(r'e(\d+)', key, 'episode number', default=None)),
116             'http_headers': {'Referer': url}
117         }
118
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/yt_dlp/extractor/hidive.py b/yt_dlp/extractor/hidive.py
--- a/yt_dlp/extractor/hidive.py
+++ b/yt_dlp/extractor/hidive.py
@@ -38,7 +38,9 @@
         webpage = self._download_webpage(self._LOGIN_URL, None)
         form = self._search_regex(
             r'(?s)<form[^>]+action="/account/login"[^>]*>(.+?)</form>',
-            webpage, 'login form')
+            webpage, 'login form', default=None)
+        if not form:  # logged in
+            return
         data = self._hidden_inputs(form)
         data.update({
             'Email': username,

{"golden_diff": "diff --git a/yt_dlp/extractor/hidive.py b/yt_dlp/extractor/hidive.py\n--- a/yt_dlp/extractor/hidive.py\n+++ b/yt_dlp/extractor/hidive.py\n@@ -38,7 +38,9 @@\n         webpage = self._download_webpage(self._LOGIN_URL, None)\n         form = self._search_regex(\n             r'(?s)<form[^>]+action=\"/account/login\"[^>]*>(.+?)</form>',\n-            webpage, 'login form')\n+            webpage, 'login form', default=None)\n+        if not form:  # logged in\n+            return\n         data = self._hidden_inputs(form)\n         data.update({\n             'Email': username,\n", "issue": "[HiDive]: Login fails when both cookies and netrc are given\n### Checklist\n\n- [X] I'm reporting a broken site\n- [X] I've verified that I'm running yt-dlp version **2022.03.08.1** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)\n- [X] I've checked that all provided URLs are alive and playable in a browser\n- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/ytdl-org/youtube-dl#video-url-contains-an-ampersand-and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)\n- [X] I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues including closed ones. DO NOT post duplicates\n- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)\n- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and I'm willing to share it if required\n\n### Region\n\nUnited States\n\n### Description\n\nWhen I try to download from HIDIVE without a `cookies.txt` it uses my netrc credentials and successfully downloads. Once I run the command again using the `cookies.txt` that `yt-dlp` dumps from the successful download, I get the error message shown in the logs. I get the same error message when I use a `cookies.txt` dumped from my browser. Funimation and Crunchyroll both work with the `cookies.txt` dumped from my browser.\r\n\r\nThe issue persists when trying from different countries using a vpn.\r\n\r\nAlso, I install and update `yt-dlp` with `pip3 install --force-reinstall -I https://github.com/yt-dlp/yt-dlp/archive/master.zip`\n\n### Verbose log\n\n```shell\n[debug] Command-line config: ['-vU', '-N', '32', '--embed-subs', '--remux-video', 'mkv', '-a', 'batch_file', '-o', 'S%(season_number)02dE%(episode_number)02d.%(ext)s']\r\n[debug] User config \"/home/{user}/.config/yt-dlp/config\": ['--netrc', '--cookies', '~/.config/yt-dlp/cookies.txt']\r\n[debug] Batch file urls: ['https://www.hidive.com/stream/made-in-abyss/s01e001']\r\n[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8\r\n[debug] yt-dlp version 2022.03.08.1 [c0c2c57d3]\r\n[debug] Lazy loading extractors is disabled\r\n[debug] Python version 3.8.10 (CPython 64bit) - Linux-5.4.0-100-generic-x86_64-with-glibc2.29\r\n[debug] Checking exe version: ffmpeg -bsfs\r\n[debug] Checking exe version: ffprobe -bsfs\r\n[debug] exe versions: ffmpeg 4.2.4, ffprobe 4.2.4, phantomjs 2.1.1, rtmpdump 2.4\r\n[debug] Optional libraries: brotli, certifi, Cryptodome, secretstorage, mutagen, sqlite, websockets\r\n[debug] Proxy map: {}\r\nLatest version: 2022.03.08.1, Current version: 2022.03.08.1\r\nyt-dlp is up to date (2022.03.08.1)\r\n[HiDive] None: Downloading webpage\r\nERROR: [HiDive] made-in-abyss/s01e001: Unable to extract login form; please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py\", line 639, in extract\r\n    self.initialize()\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py\", line 544, in initialize\r\n    self._perform_login(username, password)\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/hidive.py\", line 40, in _perform_login\r\n    form = self._search_regex(\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py\", line 1229, in _search_regex\r\n    raise RegexNotFoundError('Unable to extract %s' % _name)\n```\n\n[HiDive]: Login fails when both cookies and netrc are given\n### Checklist\n\n- [X] I'm reporting a broken site\n- [X] I've verified that I'm running yt-dlp version **2022.03.08.1** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)\n- [X] I've checked that all provided URLs are alive and playable in a browser\n- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/ytdl-org/youtube-dl#video-url-contains-an-ampersand-and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)\n- [X] I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues including closed ones. DO NOT post duplicates\n- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)\n- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and I'm willing to share it if required\n\n### Region\n\nUnited States\n\n### Description\n\nWhen I try to download from HIDIVE without a `cookies.txt` it uses my netrc credentials and successfully downloads. Once I run the command again using the `cookies.txt` that `yt-dlp` dumps from the successful download, I get the error message shown in the logs. I get the same error message when I use a `cookies.txt` dumped from my browser. Funimation and Crunchyroll both work with the `cookies.txt` dumped from my browser.\r\n\r\nThe issue persists when trying from different countries using a vpn.\r\n\r\nAlso, I install and update `yt-dlp` with `pip3 install --force-reinstall -I https://github.com/yt-dlp/yt-dlp/archive/master.zip`\n\n### Verbose log\n\n```shell\n[debug] Command-line config: ['-vU', '-N', '32', '--embed-subs', '--remux-video', 'mkv', '-a', 'batch_file', '-o', 'S%(season_number)02dE%(episode_number)02d.%(ext)s']\r\n[debug] User config \"/home/{user}/.config/yt-dlp/config\": ['--netrc', '--cookies', '~/.config/yt-dlp/cookies.txt']\r\n[debug] Batch file urls: ['https://www.hidive.com/stream/made-in-abyss/s01e001']\r\n[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8\r\n[debug] yt-dlp version 2022.03.08.1 [c0c2c57d3]\r\n[debug] Lazy loading extractors is disabled\r\n[debug] Python version 3.8.10 (CPython 64bit) - Linux-5.4.0-100-generic-x86_64-with-glibc2.29\r\n[debug] Checking exe version: ffmpeg -bsfs\r\n[debug] Checking exe version: ffprobe -bsfs\r\n[debug] exe versions: ffmpeg 4.2.4, ffprobe 4.2.4, phantomjs 2.1.1, rtmpdump 2.4\r\n[debug] Optional libraries: brotli, certifi, Cryptodome, secretstorage, mutagen, sqlite, websockets\r\n[debug] Proxy map: {}\r\nLatest version: 2022.03.08.1, Current version: 2022.03.08.1\r\nyt-dlp is up to date (2022.03.08.1)\r\n[HiDive] None: Downloading webpage\r\nERROR: [HiDive] made-in-abyss/s01e001: Unable to extract login form; please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py\", line 639, in extract\r\n    self.initialize()\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py\", line 544, in initialize\r\n    self._perform_login(username, password)\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/hidive.py\", line 40, in _perform_login\r\n    form = self._search_regex(\r\n  File \"/home/{user}/.local/lib/python3.8/site-packages/yt_dlp/extractor/common.py\", line 1229, in _search_regex\r\n    raise RegexNotFoundError('Unable to extract %s' % _name)\n```\n\n", "before_files": [{"content": "import re\n\nfrom .common import InfoExtractor\nfrom ..utils import (\n    ExtractorError,\n    int_or_none,\n    try_get,\n    url_or_none,\n    urlencode_postdata,\n)\n\n\nclass HiDiveIE(InfoExtractor):\n    _VALID_URL = r'https?://(?:www\\.)?hidive\\.com/stream/(?P<id>(?P<title>[^/]+)/(?P<key>[^/?#&]+))'\n    # Using X-Forwarded-For results in 403 HTTP error for HLS fragments,\n    # so disabling geo bypass completely\n    _GEO_BYPASS = False\n    _NETRC_MACHINE = 'hidive'\n    _LOGIN_URL = 'https://www.hidive.com/account/login'\n\n    _TESTS = [{\n        'url': 'https://www.hidive.com/stream/the-comic-artist-and-his-assistants/s01e001',\n        'info_dict': {\n            'id': 'the-comic-artist-and-his-assistants/s01e001',\n            'ext': 'mp4',\n            'title': 'the-comic-artist-and-his-assistants/s01e001',\n            'series': 'the-comic-artist-and-his-assistants',\n            'season_number': 1,\n            'episode_number': 1,\n        },\n        'params': {\n            'skip_download': True,\n        },\n        'skip': 'Requires Authentication',\n    }]\n\n    def _perform_login(self, username, password):\n        webpage = self._download_webpage(self._LOGIN_URL, None)\n        form = self._search_regex(\n            r'(?s)<form[^>]+action=\"/account/login\"[^>]*>(.+?)</form>',\n            webpage, 'login form')\n        data = self._hidden_inputs(form)\n        data.update({\n            'Email': username,\n            'Password': password,\n        })\n        self._download_webpage(\n            self._LOGIN_URL, None, 'Logging in', data=urlencode_postdata(data))\n\n    def _call_api(self, video_id, title, key, data={}, **kwargs):\n        data = {\n            **data,\n            'Title': title,\n            'Key': key,\n            'PlayerId': 'f4f895ce1ca713ba263b91caeb1daa2d08904783',\n        }\n        return self._download_json(\n            'https://www.hidive.com/play/settings', video_id,\n            data=urlencode_postdata(data), **kwargs) or {}\n\n    def _extract_subtitles_from_rendition(self, rendition, subtitles, parsed_urls):\n        for cc_file in rendition.get('ccFiles', []):\n            cc_url = url_or_none(try_get(cc_file, lambda x: x[2]))\n            # name is used since we cant distinguish subs with same language code\n            cc_lang = try_get(cc_file, (lambda x: x[1].replace(' ', '-').lower(), lambda x: x[0]), str)\n            if cc_url not in parsed_urls and cc_lang:\n                parsed_urls.add(cc_url)\n                subtitles.setdefault(cc_lang, []).append({'url': cc_url})\n\n    def _get_subtitles(self, url, video_id, title, key, parsed_urls):\n        webpage = self._download_webpage(url, video_id, fatal=False) or ''\n        subtitles = {}\n        for caption in set(re.findall(r'data-captions=\\\"([^\\\"]+)\\\"', webpage)):\n            renditions = self._call_api(\n                video_id, title, key, {'Captions': caption}, fatal=False,\n                note=f'Downloading {caption} subtitle information').get('renditions') or {}\n            for rendition_id, rendition in renditions.items():\n                self._extract_subtitles_from_rendition(rendition, subtitles, parsed_urls)\n        return subtitles\n\n    def _real_extract(self, url):\n        video_id, title, key = self._match_valid_url(url).group('id', 'title', 'key')\n        settings = self._call_api(video_id, title, key)\n\n        restriction = settings.get('restrictionReason')\n        if restriction == 'RegionRestricted':\n            self.raise_geo_restricted()\n        if restriction and restriction != 'None':\n            raise ExtractorError(\n                '%s said: %s' % (self.IE_NAME, restriction), expected=True)\n\n        formats, parsed_urls = [], {None}\n        for rendition_id, rendition in settings['renditions'].items():\n            audio, version, extra = rendition_id.split('_')\n            m3u8_url = url_or_none(try_get(rendition, lambda x: x['bitrates']['hls']))\n            if m3u8_url not in parsed_urls:\n                parsed_urls.add(m3u8_url)\n                frmt = self._extract_m3u8_formats(\n                    m3u8_url, video_id, 'mp4', entry_protocol='m3u8_native', m3u8_id=rendition_id, fatal=False)\n                for f in frmt:\n                    f['language'] = audio\n                    f['format_note'] = f'{version}, {extra}'\n                formats.extend(frmt)\n        self._sort_formats(formats)\n\n        return {\n            'id': video_id,\n            'title': video_id,\n            'subtitles': self.extract_subtitles(url, video_id, title, key, parsed_urls),\n            'formats': formats,\n            'series': title,\n            'season_number': int_or_none(\n                self._search_regex(r's(\\d+)', key, 'season number', default=None)),\n            'episode_number': int_or_none(\n                self._search_regex(r'e(\\d+)', key, 'episode number', default=None)),\n            'http_headers': {'Referer': url}\n        }\n", "path": "yt_dlp/extractor/hidive.py"}], "after_files": [{"content": "import re\n\nfrom .common import InfoExtractor\nfrom ..utils import (\n    ExtractorError,\n    int_or_none,\n    try_get,\n    url_or_none,\n    urlencode_postdata,\n)\n\n\nclass HiDiveIE(InfoExtractor):\n    _VALID_URL = r'https?://(?:www\\.)?hidive\\.com/stream/(?P<id>(?P<title>[^/]+)/(?P<key>[^/?#&]+))'\n    # Using X-Forwarded-For results in 403 HTTP error for HLS fragments,\n    # so disabling geo bypass completely\n    _GEO_BYPASS = False\n    _NETRC_MACHINE = 'hidive'\n    _LOGIN_URL = 'https://www.hidive.com/account/login'\n\n    _TESTS = [{\n        'url': 'https://www.hidive.com/stream/the-comic-artist-and-his-assistants/s01e001',\n        'info_dict': {\n            'id': 'the-comic-artist-and-his-assistants/s01e001',\n            'ext': 'mp4',\n            'title': 'the-comic-artist-and-his-assistants/s01e001',\n            'series': 'the-comic-artist-and-his-assistants',\n            'season_number': 1,\n            'episode_number': 1,\n        },\n        'params': {\n            'skip_download': True,\n        },\n        'skip': 'Requires Authentication',\n    }]\n\n    def _perform_login(self, username, password):\n        webpage = self._download_webpage(self._LOGIN_URL, None)\n        form = self._search_regex(\n            r'(?s)<form[^>]+action=\"/account/login\"[^>]*>(.+?)</form>',\n            webpage, 'login form', default=None)\n        if not form:  # logged in\n            return\n        data = self._hidden_inputs(form)\n        data.update({\n            'Email': username,\n            'Password': password,\n        })\n        self._download_webpage(\n            self._LOGIN_URL, None, 'Logging in', data=urlencode_postdata(data))\n\n    def _call_api(self, video_id, title, key, data={}, **kwargs):\n        data = {\n            **data,\n            'Title': title,\n            'Key': key,\n            'PlayerId': 'f4f895ce1ca713ba263b91caeb1daa2d08904783',\n        }\n        return self._download_json(\n            'https://www.hidive.com/play/settings', video_id,\n            data=urlencode_postdata(data), **kwargs) or {}\n\n    def _extract_subtitles_from_rendition(self, rendition, subtitles, parsed_urls):\n        for cc_file in rendition.get('ccFiles', []):\n            cc_url = url_or_none(try_get(cc_file, lambda x: x[2]))\n            # name is used since we cant distinguish subs with same language code\n            cc_lang = try_get(cc_file, (lambda x: x[1].replace(' ', '-').lower(), lambda x: x[0]), str)\n            if cc_url not in parsed_urls and cc_lang:\n                parsed_urls.add(cc_url)\n                subtitles.setdefault(cc_lang, []).append({'url': cc_url})\n\n    def _get_subtitles(self, url, video_id, title, key, parsed_urls):\n        webpage = self._download_webpage(url, video_id, fatal=False) or ''\n        subtitles = {}\n        for caption in set(re.findall(r'data-captions=\\\"([^\\\"]+)\\\"', webpage)):\n            renditions = self._call_api(\n                video_id, title, key, {'Captions': caption}, fatal=False,\n                note=f'Downloading {caption} subtitle information').get('renditions') or {}\n            for rendition_id, rendition in renditions.items():\n                self._extract_subtitles_from_rendition(rendition, subtitles, parsed_urls)\n        return subtitles\n\n    def _real_extract(self, url):\n        video_id, title, key = self._match_valid_url(url).group('id', 'title', 'key')\n        settings = self._call_api(video_id, title, key)\n\n        restriction = settings.get('restrictionReason')\n        if restriction == 'RegionRestricted':\n            self.raise_geo_restricted()\n        if restriction and restriction != 'None':\n            raise ExtractorError(\n                '%s said: %s' % (self.IE_NAME, restriction), expected=True)\n\n        formats, parsed_urls = [], {None}\n        for rendition_id, rendition in settings['renditions'].items():\n            audio, version, extra = rendition_id.split('_')\n            m3u8_url = url_or_none(try_get(rendition, lambda x: x['bitrates']['hls']))\n            if m3u8_url not in parsed_urls:\n                parsed_urls.add(m3u8_url)\n                frmt = self._extract_m3u8_formats(\n                    m3u8_url, video_id, 'mp4', entry_protocol='m3u8_native', m3u8_id=rendition_id, fatal=False)\n                for f in frmt:\n                    f['language'] = audio\n                    f['format_note'] = f'{version}, {extra}'\n                formats.extend(frmt)\n        self._sort_formats(formats)\n\n        return {\n            'id': video_id,\n            'title': video_id,\n            'subtitles': self.extract_subtitles(url, video_id, title, key, parsed_urls),\n            'formats': formats,\n            'series': title,\n            'season_number': int_or_none(\n                self._search_regex(r's(\\d+)', key, 'season number', default=None)),\n            'episode_number': int_or_none(\n                self._search_regex(r'e(\\d+)', key, 'episode number', default=None)),\n            'http_headers': {'Referer': url}\n        }\n", "path": "yt_dlp/extractor/hidive.py"}]}