예제 #1
0
def test_find_key_throws_when_no_match():
    threw = False
    try:
        find_key({
            'method':   'AES-128',
            'iv':       0x12345678,
            'uri':      'http://1.2/'
        }, [
            # deliberately empty
        ])
    except KeyError as e:
        threw = True
    finally:
        assert threw
예제 #2
0
    async def video(self, url, media_dir, title, playurl):
        """
        :param url: hls 视频流文件
        :param media_dir: 下载保存目录
        :param title:  视频标题
        :param playurl: ts文件地址
        :return:
        """
        resp = await self.client.get(url, headers=self.header)

        media = loads(resp.text)
        # 拼接ts文件列表
        playlist = [
            "{playurl}{uri}".format(playurl=playurl, uri=uri)
            for uri in media.segments.uri
        ]

        n = 0
        new_segments = []
        semaphore = asyncio.BoundedSemaphore(20)
        tasks = []
        # get ts file list
        # async with self.client.parallel() as parallel:
        for url in playlist:
            ts_file = os.path.join(media_dir, title,
                                   'm_{num}.ts'.format(num=n))
            ts_path = os.path.join(title, 'm_{num}.ts'.format(num=n))
            media.data['segments'][n]['uri'] = ts_path
            new_segments.append(media.data.get('segments')[n])
            tasks.append(
                asyncio.ensure_future(
                    self.fetch_single_ts_file(url, ts_file, semaphore)))

            n += 1

        results = await asyncio.gather(*tasks)
        for download_result in results:
            if not download_result.success:
                logger.exception("url: {} download failed, reason: {}".format(
                    download_result.data_url, download_result.reason))
        # change m3u8 data
        media.data['segments'] = new_segments
        # 修改m3u8文件信息
        segments = SegmentList([
            Segment(base_uri=None,
                    keyobject=find_key(segment.get('key', {}), media.keys),
                    **segment) for segment in media.data.get('segments', [])
        ])
        media.segments = segments

        # save m3u8 file
        m3u8_file = os.path.join(media_dir, '{title}.m3u8'.format(title=title))
        if not os.path.exists(m3u8_file):
            with open(m3u8_file, 'w', encoding='utf8') as f:
                f.write(media.dumps())
예제 #3
0
    def download_video(self, download_dir, resource, nocache=False):
        resource_dir = os.path.join(download_dir, resource['id'])
        os.makedirs(resource_dir, exist_ok=True)

        url = resource['video_hls'].replace('\\', '')
        self.session.headers.update({
            'Referer':
            'https://pc-shop.xiaoe-tech.com/{appid}/video_details?id={resourceid}'
            .format(appid=self.appid, resourceid=resource['id'])
        })
        media = m3u8.loads(self.session.get(url).text)
        url_prefix, segments, changed, complete = url.split(
            'v.f230')[0], SegmentList(), False, True

        print('Total: {} part'.format(len(media.data['segments'])))
        for index, segment in enumerate(media.data['segments']):
            ts_file = os.path.join(resource_dir, 'v_{}.ts'.format(index))
            if not nocache and os.path.exists(ts_file):
                print('Already Downloaded: {title} {file}'.format(
                    title=resource['title'], file=ts_file))
            else:
                url = url_prefix + segment.get('uri')
                res = self.session.get(url)
                if res.status_code == 200:
                    with open(ts_file + '.tmp', 'wb') as ts:
                        ts.write(res.content)
                    os.rename(ts_file + '.tmp', ts_file)
                    changed = True
                    print('Download Successful: {title} {file}'.format(
                        title=resource['title'], file=ts_file))
                else:
                    print('Download Failed: {title} {file}'.format(
                        title=resource['title'], file=ts_file))
                    complete = False
            segment['uri'] = 'v_{}.ts'.format(index)
            segments.append(
                Segment(base_uri=None,
                        keyobject=find_key(segment.get('key', {}), media.keys),
                        **segment))

        m3u8_file = os.path.join(resource_dir, 'video.m3u8')
        if changed or not os.path.exists(m3u8_file):
            media.segments = segments
            with open(m3u8_file, 'w', encoding='utf8') as f:
                f.write(media.dumps())
        metadata = {'title': resource['title'], 'complete': complete}
        with open(os.path.join(download_dir, resource['id'], 'metadata'),
                  'w') as f:
            json.dump(metadata, f)
        return
예제 #4
0
    def video(self, url, media_dir, title, playurl):
        '''
        :param url: hls 视频流文件
        :param media_dir: 下载保存目录
        :param title:  视频标题
        :param playurl: ts文件地址
        :return:
        '''
        resp = self.session.get(url, headers=self.header)

        media = loads(resp.text)
        # 拼接ts文件列表
        playlist = ["{playurl}{uri}".format(playurl=playurl, uri=uri) for uri in media.segments.uri]

        n = 0
        new_segments = []
        # get ts file list
        for url in playlist:
            ts_file = os.path.join(media_dir, title, 'm_{num}.ts'.format(num=n))
            ts_path = os.path.join(title, 'm_{num}.ts'.format(num=n))
            media.data['segments'][n]['uri'] = ts_path
            new_segments.append(media.data.get('segments')[n])
            # 下载ts文件
            resp = self.session.get(url, headers=self.header, cookies=self.cookie)
            if resp.status_code != 200:
                print('Error: {title} {tsfile}'.format(title=title, tsfile=ts_file))

            # 如果文件不存在或者本地文件大小于接口返回大小不一致则保存ts文件
            if not os.path.exists(ts_file) or os.stat(ts_file).st_size != resp.headers['content-length']:
                with open(ts_file, 'wb') as ts:
                    ts.write(resp.content)

            n += 1

        # change m3u8 data
        media.data['segments'] = new_segments
        # 修改m3u8文件信息
        segments = SegmentList(
            [Segment(base_uri=None, keyobject=find_key(segment.get('key', {}), media.keys), **segment)
             for segment in
             media.data.get('segments', [])])
        media.segments = segments

        # save m3u8 file
        m3u8_file = os.path.join(media_dir, '{title}.m3u8'.format(title=title))
        if not os.path.exists(m3u8_file):
            with open(m3u8_file, 'wb', encoding='utf8') as f:
                f.write(media.dumps())