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

Code before:
from ..utils import (
    int_or_none,
    parse_iso8601,
    unescapeHTML,
)


class PeriscopeBaseIE(InfoExtractor):
    _M3U8_HEADERS = {
        'Referer': 'https://www.periscope.tv/'
    }

    def _call_api(self, method, query, item_id):
        return self._download_json(
            'https://api.periscope.tv/api/v2/%s' % method,
            item_id, query=query)

    def _parse_broadcast_data(self, broadcast, video_id):
        title = broadcast.get('status') or 'Periscope Broadcast'
        uploader = broadcast.get('user_display_name') or broadcast.get('username')
        title = '%s - %s' % (uploader, title) if uploader else title
        timestamp = parse_iso8601(broadcast.get('created_at'))
        is_live = broadcast.get('state').lower() == 'running'

        if broadcast.get('created_at_ms'):
            timestamp = int_or_none(broadcast.get('created_at_ms'))

        thumbnails = [{
            'url': broadcast[image],
        } for image in ('image_url', 'image_url_medium', 'image_url_small') if broadcast.get(image)]

        return {
            'id': broadcast.get('id') or video_id,
            'title': title,
            'timestamp': timestamp,
            'uploader': uploader,
            'uploader_id': broadcast.get('user_id') or broadcast.get('username'),
            'thumbnails': thumbnails,
            'view_count': int_or_none(broadcast.get('total_watched')),
            'tags': broadcast.get('tags'),
            'is_live': is_live,
        }

    @staticmethod
    def _extract_common_format_info(broadcast):
        return broadcast.get('state').lower(), int_or_none(broadcast.get('width')), int_or_none(broadcast.get('height'))

    @staticmethod
    def _add_width_and_height(f, width, height):
        for key, val in (('width', width), ('height', height)):
            if not f.get(key):

Review comment (suggestion):
```suggestion
        is_live = broadcast.get('state').lower() == 'running'
        timestamp = (int_or_none(broadcast.get('created_at_ms'), scale=1000)
                     or parse_iso8601(broadcast.get('created_at')))
```
or inline below.

Code after:
from ..utils import (
    int_or_none,
    parse_iso8601,
    unescapeHTML,
)


class PeriscopeBaseIE(InfoExtractor):
    _M3U8_HEADERS = {
        'Referer': 'https://www.periscope.tv/'
    }

    def _call_api(self, method, query, item_id):
        return self._download_json(
            'https://api.periscope.tv/api/v2/%s' % method,
            item_id, query=query)

    def _parse_broadcast_data(self, broadcast, video_id):
        title = broadcast.get('status') or 'Periscope Broadcast'
        uploader = broadcast.get('user_display_name') or broadcast.get('username')
        title = '%s - %s' % (uploader, title) if uploader else title
        is_live = broadcast.get('state').lower() == 'running'

        thumbnails = [{
            'url': broadcast[image],
        } for image in ('image_url', 'image_url_medium', 'image_url_small') if broadcast.get(image)]

        return {
            'id': broadcast.get('id') or video_id,
            'title': title,
            'timestamp': parse_iso8601(broadcast.get('created_at')) or int_or_none(
                broadcast.get('created_at_ms'), scale=1000),
            'uploader': uploader,
            'uploader_id': broadcast.get('user_id') or broadcast.get('username'),
            'thumbnails': thumbnails,
            'view_count': int_or_none(broadcast.get('total_watched')),
            'tags': broadcast.get('tags'),
            'is_live': is_live,
        }

    @staticmethod
    def _extract_common_format_info(broadcast):
        return broadcast.get('state').lower(), int_or_none(broadcast.get('width')), int_or_none(broadcast.get('height'))

    @staticmethod
    def _add_width_and_height(f, width, height):
        for key, val in (('width', width), ('height', height)):
            if not f.get(key):
                f[key] = val

    def _extract_pscp_m3u8_formats(self, m3u8_url, video_id, format_id, state, width, height, fatal=True):