Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/loom.py (Python)

Code before:
            'uploader': 'wILLIAM PIP',
            'upload_date': '20220328',
        }
    }, {
        'url': 'https://www.loom.com/share/c43a642f815f4378b6f80a889bb73d8d',
        'md5': '281c57772c6364c7a860fc222ea8d222',
        'info_dict': {
            'id': 'c43a642f815f4378b6f80a889bb73d8d',
            'ext': 'mp4',
            'title': 'Lilah Nielsen Intro Video',
            'uploader': 'Lilah Nielsen',
            'upload_date': '20200826',
        }
    }]

    def fetch_loom_download_url(self, id):
        json = self._download_json(f"https://www.loom.com/api/campaigns/sessions/{id}/transcoded-url", video_id=id, data=b'')
        return json["url"]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        webpage = self._download_webpage(url, video_id)

        json = self._search_json(start_pattern=r'window\.loomSSRVideo\s*=', string=webpage, name="Json from Loom Webpage", video_id=video_id)
        videourl = self.fetch_loom_download_url(video_id)
        ext = self._search_regex(r'([a-zA-Z0-9]+)(?=\?)', videourl, 'ext', fatal=False)

        date_string = json.get('createdAt')
        date = datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y%m%d")

        formats = []
        formats.append({
            'url': videourl,
            'width': traverse_obj(json, ('video_properties', 'width')),
            'height': traverse_obj(json, ('video_properties', 'height')),
            'ext': ext,
            'filesize': traverse_obj(json, ('video_properties', 'byte_size')),
        })

        return {
            'id': video_id,
            'title': json.get('name'),
            'uploader': json.get('owner_full_name'),
            'upload_date': date,
            'formats': formats,
            # 'view_count': json["total_views"], # View Count is always changing so don't know how to test this.
            # TODO more properties (see yt_dlp/extractor/common.py)
        }


Review comment (suggestion):
- use `determine_ext` from utils instead of manually searching w/ regex
- core code calls `determine_ext` on format URLs after the info dict is returned, so this is unnecessary here
```suggestion
```

Code after:
    url_or_none,
    variadic,
)
from ..utils.traversal import traverse_obj


class LoomIE(InfoExtractor):
    IE_NAME = 'loom'
    _VALID_URL = r'https?://(?:www\.)?loom\.com/(?:share|embed)/(?P<id>[\da-f]{32})'
    _EMBED_REGEX = [rf'<iframe[^>]+\bsrc=["\'](?P<url>{_VALID_URL})']
    _TESTS = [{
        # m3u8 raw-url, mp4 transcoded-url, cdn url == raw-url, json subs only
        'url': 'https://www.loom.com/share/43d05f362f734614a2e81b4694a3a523',
        'md5': 'bfc2d7e9c2e0eb4813212230794b6f42',
        'info_dict': {
            'id': '43d05f362f734614a2e81b4694a3a523',
            'ext': 'mp4',
            'title': 'A Ruler for Windows - 28 March 2022',
            'uploader': 'wILLIAM PIP',
            'upload_date': '20220328',
            'timestamp': 1648454238,
            'duration': 27,
        },
    }, {
        # webm raw-url, mp4 transcoded-url, cdn url == transcoded-url, no subs
        'url': 'https://www.loom.com/share/c43a642f815f4378b6f80a889bb73d8d',
        'md5': '70f529317be8cf880fcc2c649a531900',
        'info_dict': {
            'id': 'c43a642f815f4378b6f80a889bb73d8d',
            'ext': 'webm',
            'title': 'Lilah Nielsen Intro Video',
            'uploader': 'Lilah Nielsen',
            'upload_date': '20200826',
            'timestamp': 1598480716,
            'duration': 20,
        },
    }, {
        # m3u8 raw-url, mp4 transcoded-url, cdn url == raw-url, vtt sub and json subs
        'url': 'https://www.loom.com/share/9458bcbf79784162aa62ffb8dd66201b',
        'md5': '51737ec002969dd28344db4d60b9cbbb',
        'info_dict': {
            'id': '9458bcbf79784162aa62ffb8dd66201b',
            'ext': 'mp4',
            'title': 'Sharing screen with gpt-4',
            'description': 'Sharing screen with GPT 4 vision model and asking questions to guide through blender.',
            'uploader': 'Suneel Matham',
            'chapters': 'count:3',
            'upload_date': '20231109',
            'timestamp': 1699518978,
            'duration': 93,
        },