[willow] new extractor
diff --git a/yt_dlp/extractor/extractors.py b/yt_dlp/extractor/extractors.py
index 4f9de71e27d..a6f1acb5654 100644
--- a/yt_dlp/extractor/extractors.py
+++ b/yt_dlp/extractor/extractors.py
@@ -1782,6 +1782,7 @@
     WeiboMobileIE
 )
 from .weiqitv import WeiqiTVIE
+from .willow import WillowIE
 from .wimtv import WimTVIE
 from .whowatch import WhoWatchIE
 from .wistia import (
diff --git a/yt_dlp/extractor/willow.py b/yt_dlp/extractor/willow.py
new file mode 100644
index 00000000000..4d3d62f9556
--- /dev/null
+++ b/yt_dlp/extractor/willow.py
@@ -0,0 +1,58 @@
+# coding: utf-8
+from ..utils import ExtractorError
+from .common import InfoExtractor
+
+
+class WillowIE(InfoExtractor):
+    _VALID_URL = r'https?://(www\.)?willow\.tv/videos/(?P<id>[0-9a-z-_]+)'
+    _GEO_COUNTRIES = ['US']
+
+    _TESTS = [{
+        'url': 'http://willow.tv/videos/d5winning-moment-eng-vs-ind-streaming-online-4th-test-india-tour-of-england-2021',
+        'info_dict': {
+            'id': '169662',
+            'display_id': 'd5winning-moment-eng-vs-ind-streaming-online-4th-test-india-tour-of-england-2021',
+            'ext': 'mp4',
+            'title': 'Winning Moment: 4th Test, England vs India',
+            'thumbnail': 'https://aimages.willow.tv/ytThumbnails/6748_D5winning_moment.jpg',
+            'duration': 233,
+            'timestamp': 1630947954,
+            'upload_date': '20210906',
+            'location': 'Kennington Oval, London',
+            'series': 'India tour of England 2021',
+        },
+        'params': {
+            'skip_download': True,  # AES-encrypted m3u8
+        },
+    }, {
+        'url': 'http://willow.tv/videos/highlights-short-ind-vs-nz-streaming-online-2nd-t20i-new-zealand-tour-of-india-2021',
+        'only_matching': True,
+    }]
+
+    def _real_extract(self, url):
+        video_id = self._match_id(url)
+        webpage = self._download_webpage(url, video_id)
+        video_data = self._parse_json(self._html_search_regex(
+            r'var\s+data_js\s*=\s*JSON\.parse\(\'(.+)\'\)', webpage,
+            'data_js'), video_id)
+
+        video = next((v for v in video_data.get('trending_videos') or []
+                      if v.get('secureurl')), None)
+        if not video:
+            raise ExtractorError('No videos found')
+
+        formats = self._extract_m3u8_formats(video['secureurl'], video_id, 'mp4')
+        self._sort_formats(formats)
+
+        return {
+            'id': str(video.get('content_id')),
+            'display_id': video.get('video_slug'),
+            'title': video.get('video_name') or self._html_search_meta('twitter:title', webpage),
+            'formats': formats,
+            'thumbnail': video.get('yt_thumb_url') or self._html_search_meta(
+                'twitter:image', webpage, default=None),
+            'duration': video.get('duration_seconds'),
+            'timestamp': video.get('created_date'),
+            'location': video.get('venue'),
+            'series': video.get('series_name'),
+        }

## Please follow the guide below

- You will be asked some questions, please read them **carefully** and answer honestly
- Put an `x` into all the boxes [ ] relevant to your *pull request* (like that [x])
- Use *Preview* tab to see how your *pull request* will actually look like

---

### Before submitting a *pull request* make sure you have:
- [x] At least skimmed through [contributing guidelines](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#developer-instructions) including [yt-dlp coding conventions](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#yt-dlp-coding-conventions)
- [x] [Searched](https://github.com/yt-dlp/yt-dlp/search?q=is%3Apr&type=Issues) the bugtracker for similar pull requests
- [x] Checked the code with [flake8](https://pypi.python.org/pypi/flake8)

### In order to be accepted and merged into yt-dlp each piece of code must be in public domain or released under [Unlicense](http://unlicense.org/). Check one of the following options:
- [x] I am the original author of this code and I am willing to release it under [Unlicense](http://unlicense.org/)
- [ ] I am not the original author of this code but it is in public domain or released under [Unlicense](http://unlicense.org/) (provide reliable evidence)

### What is the purpose of your *pull request*?
- [ ] Bug fix
- [ ] Improvement
- [x] New extractor
- [ ] New feature

---

### Description of your *pull request* and other information

Extractor for willow.tv, which has both free and subscriber-only content. Only support for free videos was added as I am not a paid subscriber.