Repository: yt-dlp/yt-dlp

Issue:
Hotstar not working anymore
### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [X] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field

### Checklist

- [X] I'm reporting a bug unrelated to a specific site
- [X] I've verified that I'm running yt-dlp version **2023.03.04** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)
- [X] I've checked that all provided URLs are playable in a browser with the same IP and same login details
- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#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 [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and 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)

### Provide a description that is worded well enough to be understood

Hello all,

I hope I'm not making a mistake by opening this topic. I have a subscription with hotstar, I have been using yt-dlp for this for a long time. Since yesterday the website has changed and it no longer works. hopefully somebody can help me. I can't find any existing issue about this. Thanks in advance.

### Provide verbose output that clearly demonstrates the problem

- [X] Run **your** yt-dlp command with **-vU** flag added (`yt-dlp -vU <your command line>`)
- [ ] If using API, add `'verbose': True` to `YoutubeDL` params instead
- [X] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

```shell
yt-dlp -vU -F --cookies-from-browser chrome https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843
[debug] Command-line config: ['-vU', '-F', '--cookies-from-browser', 'chrome', 'https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version stable@2023.03.04 [392389b7d] (darwin_exe)
[debug] Python 3.8.9 (CPython x86_64 64bit) - macOS-12.6.1-x86_64-i386-64bit (LibreSSL 2.8.3)
[debug] exe versions: ffmpeg 6.0-tessus (setts), ffprobe 6.0-tessus
[debug] Optional libraries: Cryptodome-3.17, brotli-1.0.9, certifi-2022.12.07, mutagen-1.46.0, sqlite3-2.6.0, websockets-10.4
[Cookies] Extracting cookies from chrome
[debug] Extracting cookies from: "/Users/arishramsaran/Library/Application Support/Google/Chrome/Default/Cookies"
[debug] using find-generic-password to obtain password from OSX keychain
[Cookies] Extracted 3099 cookies from chrome
[debug] cookie version breakdown: {'v10': 3048, 'other': 0, 'unencrypted': 51}
[debug] Proxy map: {}
[debug] Loaded 1786 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
Available version: stable@2023.03.04, Current version: stable@2023.03.04
Current Build Hash: 1f893f5fb990b1df08820be3fac6c46ee93c0b2f797b72a104bbd485139a8e9d
yt-dlp is up to date (stable@2023.03.04)
[generic] Extracting URL: https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843
[generic] 1000282843: Downloading webpage
[redirect] Following redirect to https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843/watch
[generic] Extracting URL: https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843/watch
[generic] watch: Downloading webpage
WARNING: [generic] Falling back on generic information extractor
[generic] watch: Extracting information
[debug] Looking for embeds
ERROR: Unsupported URL: https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843/watch
Traceback (most recent call last):
  File "yt_dlp/YoutubeDL.py", line 1518, in wrapper
  File "yt_dlp/YoutubeDL.py", line 1594, in __extract_info
  File "yt_dlp/extractor/common.py", line 694, in extract
  File "yt_dlp/extractor/generic.py", line 2510, in _real_extract
yt_dlp.utils.UnsupportedError: Unsupported URL: https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843/watch
```



Discussion:
The link doesn't open in browser for me.

> * [x]  I've checked that all provided URLs are playable in a browser with the same IP and same login details

Pls double check
> The link doesn't open in browser for me.
> 
> > * [x]   I've checked that all provided URLs are playable in a browser with the same IP and same login details
> 
> Pls double check

Thanks for the quick reply. I just double-checked. It's working fine in the browser.
I wouldn't have expected a 404 due to lack of account... But I'll take your word for it

![image](https://user-images.githubusercontent.com/6623388/223538849-dd07bef4-76e5-4c93-b466-7fd1bfc3533b.png)

> I wouldn't have expected a 404 due to lack of account... But I'll take your word for it
> 
> ![image](https://user-images.githubusercontent.com/6623388/223538849-dd07bef4-76e5-4c93-b466-7fd1bfc3533b.png)

![Schermafbeelding 2023-03-09 om 15 21 50 kopiëren](https://user-images.githubusercontent.com/50719270/224054217-2c653db2-8ea0-4520-9ca2-e805ee35a027.png)

Sorry for the late reply. Any solution? It is working for me in the browser. It still doesn't work with yt-dlp. I've tried putting /watch behind it but that doesn't work either.
it looks like there's a new URL path of `/shows/` for some videos, which is not matched by the extractor.
Something like this might work? (I can't test it though; I don't have an account, am not in region, and I get a 400 at the `Downloading token` stage)

```diff
diff --git a/yt_dlp/extractor/hotstar.py b/yt_dlp/extractor/hotstar.py
index cea1812f1..dc793a62c 100644
--- a/yt_dlp/extractor/hotstar.py
+++ b/yt_dlp/extractor/hotstar.py
@@ -83,7 +83,7 @@ class HotStarIE(HotStarBaseIE):
     _VALID_URL = r'''(?x)
         https?://(?:www\.)?hotstar\.com(?:/in)?/(?!in/)
         (?:
-            (?P<type>movies|sports|episode|(?P<tv>tv))/
+            (?P<type>movies|sports|episode|(?P<tv>tv|shows))/
             (?(tv)(?:[^/?#]+/){2}|[^?#]*)
         )?
         [^/?#]+/
@@ -139,6 +139,7 @@ class HotStarIE(HotStarBaseIE):
         'sports': 'match',
         'episode': 'episode',
         'tv': 'episode',
+        'shows': 'episode',
         None: 'content',
     }
 
@@ -304,7 +305,7 @@ def _real_extract(self, url):
 
 class HotStarPlaylistIE(HotStarBaseIE):
     IE_NAME = 'hotstar:playlist'
-    _VALID_URL = r'https?://(?:www\.)?hotstar\.com(?:/in)?/tv(?:/[^/]+){2}/list/[^/]+/t-(?P<id>\w+)'
+    _VALID_URL = r'https?://(?:www\.)?hotstar\.com(?:/in)?/(?:tv|shows)(?:/[^/]+){2}/list/[^/]+/t-(?P<id>\w+)'
     _TESTS = [{
         'url': 'https://www.hotstar.com/tv/savdhaan-india/s-26/list/popular-clips/t-3_2_26',
         'info_dict': {
@@ -327,7 +328,7 @@ def _real_extract(self, url):
 
 class HotStarSeasonIE(HotStarBaseIE):
     IE_NAME = 'hotstar:season'
-    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/tv/[^/]+/\w+)/seasons/[^/]+/ss-(?P<id>\w+)'
+    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/(?:tv|shows)/[^/]+/\w+)/seasons/[^/]+/ss-(?P<id>\w+)'
     _TESTS = [{
         'url': 'https://www.hotstar.com/tv/radhakrishn/1260000646/seasons/season-2/ss-8028',
         'info_dict': {
@@ -356,7 +357,7 @@ def _real_extract(self, url):
 
 class HotStarSeriesIE(HotStarBaseIE):
     IE_NAME = 'hotstar:series'
-    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/tv/[^/]+/(?P<id>\d+))/?(?:[#?]|$)'
+    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/(?:tv|shows)/[^/]+/(?P<id>\d+))/?(?:[#?]|$)'
     _TESTS = [{
         'url': 'https://www.hotstar.com/in/tv/radhakrishn/1260000646',
         'info_dict': {
```
Thanks! Will try it soon.

—
Reply to this email directly, view it on GitHub<https://github.com/yt-dlp/yt-dlp/issues/6463#issuecomment-1478056982>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AMC6UJWO6AE6JV2DJJQWS6DW5HC77ANCNFSM6AAAAAAVSVEK4U>.
You are receiving this because you authored the thread.Message ID: ***@***.***>

seems like all links are being redirected to a "watch" page. Layout changed for the website and its more like a mobile webpage. @bashonly  your changes seems to do a  little progress but still falling back on generic extractor. Some more changes are required i guess.
I don't know if this will be useful to anyone but modifying the URL (replace "shows" with "tv") works, no need for a extractor update.

> I don't know if this will be useful to anyone but modifying the URL (replace "shows" with "tv") works, no need for a extractor update.

That effectively verifies @bashonly's patch

Thanks all!
> I don't know if this will be useful to anyone but modifying the URL (replace "shows" with "tv") works, no need for a extractor update.

Worked for me as well. Thanks buddy @machasundaram .
@pukkandan When will the next `stable` release be available? Its been more than a month. We are only getting `nightly` releases
Out of region the playback API (eg, `https://api.hotstar.com/play/v1/playback/content/1000076273?...`) returns 400 with 
```py
{
  'errorCode': 'ERR_PB_1401',
  'message': 'Bad Playback Request',
  'errorDetails': [
    {
      'headerName': 'X-Request-Id',
      'message': 'Missing or Invalid Header X-Request-Id'
    }
  ],
  'additionalInfo': {
  }
}
```
Where does `X-Request-Id` come from?

Can this be fixed (at least to return a real geo-block error), or should it just be converted to a `GeoRestrictedError`?

Resolving patch:
diff --git a/yt_dlp/extractor/hotstar.py b/yt_dlp/extractor/hotstar.py
--- a/yt_dlp/extractor/hotstar.py
+++ b/yt_dlp/extractor/hotstar.py
@@ -83,7 +83,7 @@ class HotStarIE(HotStarBaseIE):
     _VALID_URL = r'''(?x)
         https?://(?:www\.)?hotstar\.com(?:/in)?/(?!in/)
         (?:
-            (?P<type>movies|sports|episode|(?P<tv>tv))/
+            (?P<type>movies|sports|episode|(?P<tv>tv|shows))/
             (?(tv)(?:[^/?#]+/){2}|[^?#]*)
         )?
         [^/?#]+/
@@ -122,6 +122,25 @@ class HotStarIE(HotStarBaseIE):
             'episode': 'Janhvi Targets Suman',
             'episode_number': 8,
         }
+    }, {
+        'url': 'https://www.hotstar.com/in/shows/anupama/1260022017/anupama-anuj-share-a-moment/1000282843',
+        'info_dict': {
+            'id': '1000282843',
+            'ext': 'mp4',
+            'title': 'Anupama, Anuj Share a Moment',
+            'season': 'Chapter 1',
+            'description': 'md5:8d74ed2248423b8b06d5c8add4d7a0c0',
+            'timestamp': 1678149000,
+            'channel': 'StarPlus',
+            'series': 'Anupama',
+            'season_number': 1,
+            'season_id': 7399,
+            'upload_date': '20230307',
+            'episode': 'Anupama, Anuj Share a Moment',
+            'episode_number': 853,
+            'duration': 1272,
+            'channel_id': 3,
+        },
     }, {
         'url': 'https://www.hotstar.com/movies/radha-gopalam/1000057157',
         'only_matching': True,
@@ -139,6 +158,7 @@ class HotStarIE(HotStarBaseIE):
         'sports': 'match',
         'episode': 'episode',
         'tv': 'episode',
+        'shows': 'episode',
         None: 'content',
     }
 
@@ -304,13 +324,16 @@ def _real_extract(self, url):
 
 class HotStarPlaylistIE(HotStarBaseIE):
     IE_NAME = 'hotstar:playlist'
-    _VALID_URL = r'https?://(?:www\.)?hotstar\.com(?:/in)?/tv(?:/[^/]+){2}/list/[^/]+/t-(?P<id>\w+)'
+    _VALID_URL = r'https?://(?:www\.)?hotstar\.com(?:/in)?/(?:tv|shows)(?:/[^/]+){2}/list/[^/]+/t-(?P<id>\w+)'
     _TESTS = [{
         'url': 'https://www.hotstar.com/tv/savdhaan-india/s-26/list/popular-clips/t-3_2_26',
         'info_dict': {
             'id': '3_2_26',
         },
         'playlist_mincount': 20,
+    }, {
+        'url': 'https://www.hotstar.com/shows/savdhaan-india/s-26/list/popular-clips/t-3_2_26',
+        'only_matching': True,
     }, {
         'url': 'https://www.hotstar.com/tv/savdhaan-india/s-26/list/extras/t-2480',
         'only_matching': True,
@@ -327,7 +350,7 @@ def _real_extract(self, url):
 
 class HotStarSeasonIE(HotStarBaseIE):
     IE_NAME = 'hotstar:season'
-    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/tv/[^/]+/\w+)/seasons/[^/]+/ss-(?P<id>\w+)'
+    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/(?:tv|shows)/[^/]+/\w+)/seasons/[^/]+/ss-(?P<id>\w+)'
     _TESTS = [{
         'url': 'https://www.hotstar.com/tv/radhakrishn/1260000646/seasons/season-2/ss-8028',
         'info_dict': {
@@ -346,6 +369,9 @@ class HotStarSeasonIE(HotStarBaseIE):
             'id': '8208',
         },
         'playlist_mincount': 19,
+    }, {
+        'url': 'https://www.hotstar.com/in/shows/bigg-boss/14714/seasons/season-4/ss-8208/',
+        'only_matching': True,
     }]
 
     def _real_extract(self, url):
@@ -356,7 +382,7 @@ def _real_extract(self, url):
 
 class HotStarSeriesIE(HotStarBaseIE):
     IE_NAME = 'hotstar:series'
-    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/tv/[^/]+/(?P<id>\d+))/?(?:[#?]|$)'
+    _VALID_URL = r'(?P<url>https?://(?:www\.)?hotstar\.com(?:/in)?/(?:tv|shows)/[^/]+/(?P<id>\d+))/?(?:[#?]|$)'
     _TESTS = [{
         'url': 'https://www.hotstar.com/in/tv/radhakrishn/1260000646',
         'info_dict': {
@@ -375,6 +401,12 @@ class HotStarSeriesIE(HotStarBaseIE):
             'id': '435',
         },
         'playlist_mincount': 267,
+    }, {
+        'url': 'https://www.hotstar.com/in/shows/anupama/1260022017/',
+        'info_dict': {
+            'id': '1260022017',
+        },
+        'playlist_mincount': 940,
     }]
 
     def _real_extract(self, url):


Test patch: