예제 #1
0
    def get_m3u8(self, quality: str) -> M3U8:
        """Gets the episode's M3U8 data.

        :param quality: The quality whose M3U8 data you need. All the available 
                        are "ld" (360p), "sd" (480p), "hd" (720p) and "fullhd" (1080p).
        :type quality: str
        :return: A M3U8 object, the data can be accessed by calling the ``data`` property on the
                 object.
        :rtype: M3U8
        """
        if self.__m3u8:
            return self.__m3u8
        else:
            try:
                headers = self.__generate_default_headers()
                aniwatch_episode = self.get_aniwatch_episode()
                self.toggle_mark_as_watched()
                self.spoof_download_sprites()
                uri = aniwatch_episode.stream.sources[
                    quality]  # The uri to the M3U8 file.
                res = self.__network.get_with_user_session(uri, headers)
                self.__m3u8 = M3U8(res.text)
                return self.__m3u8
            except:
                return Nonec
예제 #2
0
def make_feed_manifest(request, stream, feed):
    url = request.build_absolute_uri(stream.index_manifest_url)
    p = load_m3u8(url)
    m = M3U8()
    m.version = p.version
    m.target_duration = p.target_duration
    m.media_sequence = p.media_sequence
    for s in p.segments:
        if not m.program_date_time:
            m.program_date_time = s.current_program_date_time

        vtt_url = furl(basename(feed.webvtt_url)).set({"stream": stream.uuid})
        if s.current_program_date_time:
            vtt_url.args.update({
                "start":
                s.current_program_date_time.isoformat(),
                "end": (s.current_program_date_time +
                        timedelta(seconds=s.duration)).isoformat(),
                "epoch":
                stream.started_at.isoformat(),
            })
        v = Segment(
            base_uri=vtt_url.url,
            uri=vtt_url.url,
            duration=s.duration,
            discontinuity=s.discontinuity,
            program_date_time=s.current_program_date_time,
        )
        m.add_segment(v)

    return m.dumps()
예제 #3
0
def make_master_manifest(request, stream):
    if stream.info:
        bandwidth = int(stream.info["bw_out"])
        width = stream.info["meta"]["video"]["width"]
        height = stream.info["meta"]["video"]["height"]
        stream_info = {
            "bandwidth": bandwidth,
            "resolution": f"{width}x{height}",
            "codecs": "avc1.640028,mp4a.40.2",
        }
    else:
        stream_info = {"bandwidth": 1000}

    p = Playlist(basename(stream.index_manifest_url), stream_info, None, None)
    m = M3U8()
    m.add_playlist(p)

    for feed in stream.feeds.all():
        media = Media(
            type="SUBTITLES",
            group_id="feeds",
            name=f"feed-{feed.uuid}",
            language="en",
            default="YES",
            autoselect="YES",
            uri=furl(feed.manifest_url).set({
                "stream": stream.uuid
            }).url,
        )
        p.media.append(media)
        m.add_media(media)

    return m.dumps()
예제 #4
0
 def start(self):
     if self._run:
         self._files = None
         d = self._reload_playlist(
             M3U8(self.url, self._cookies, self.hls_headers))
         d.addCallback(self._start_get_files)
         return d
예제 #5
0
    def generate_vod_recording_playlist_m3u8(cls, client_uuid, recording_id,
                                             http_token):
        db_session = Database.create_session()

        try:
            vod_playlist_m3u8_object = M3U8()
            vod_playlist_m3u8_object.media_sequence = 0
            vod_playlist_m3u8_object.version = '3'
            vod_playlist_m3u8_object.target_duration = 0
            vod_playlist_m3u8_object.playlist_type = 'VOD'

            for segment_row in DatabaseAccess.query_segment_pickle(
                    db_session, recording_id):
                segment = pickle.loads(segment_row.pickle)

                if segment.duration > vod_playlist_m3u8_object.target_duration:
                    vod_playlist_m3u8_object.target_duration = math.ceil(
                        segment.duration)

                vod_playlist_m3u8_object.add_segment(segment)

            return re.sub(
                r'(\.ts\?)(.*)', r'\1client_uuid={0}&http_token={1}&\2'.format(
                    client_uuid,
                    urllib.parse.quote(http_token) if http_token else ''),
                '{0}\n'
                '{1}'.format(vod_playlist_m3u8_object.dumps(),
                             '#EXT-X-ENDLIST'))
        finally:
            db_session.close()
예제 #6
0
 async def get_m3u8(self):
     if self.m3u8 is None:
         headers = {"referer": "https://kwik.cx"}
         m3u8_url = await self.get_m3u8_url()
         response = await self.__network__.get(m3u8_url, headers=headers)
         print(await response.text())
         self.m3u8 = M3U8(await response.text())
     return self.m3u8
예제 #7
0
def downM3u8Video(url, out_dir, out_name, process_num):
    out_path = os.path.join(out_dir, out_name)
    tmp_dir = os.path.join(out_dir, os.path.splitext(os.path.basename(out_name))[0])
    if os.path.exists(out_path) and not os.path.exists(tmp_dir):
        # 该任务已完成下载
        print('Input name is existed:%s!' % out_name)
        return

    m3u8_info = M3U8(url)
    ts_len = len(m3u8_info.ts_urls)
    print('ts length:%d' % ts_len)

    if ts_len > 0:
        if not os.path.exists(tmp_dir):
            os.makedirs(tmp_dir)

        process_list = []
        per_process_num = int(ts_len / process_num)

        # 启用多进程下载视频
        for i in range(process_num):
            id_start = i * per_process_num
            id_end = (i + 1) * per_process_num
            if i == process_num - 1:
                id_end = ts_len
            cur_process = multiprocessing.Process(
                target=downloadTsFiles, args=(m3u8_info.ts_urls[id_start:id_end], tmp_dir, i))
            cur_process.start()
            # search_ip(ip_prefix, database, table_name, ip_start, ip_end, i)
            process_list.append(cur_process)

        for process_item in process_list:
            process_item.join()

        # 若有加密,尝试解密文件
        if CRYPTO_ENABLE and m3u8_info.encrypt_method:
            print('encrypt method:%s' % m3u8_info.encrypt_method)
            print('key uri:%s' % m3u8_info.key_uri)
            key_str = getResponse(m3u8_info.key_uri)
            decryptFiles(m3u8_info.ts_urls, tmp_dir, m3u8_info.encrypt_method, key_str)

        print('Merging to one file:%s' % out_path)
        with open(out_path, 'wb') as f_out:
            for i, ts_url in enumerate(m3u8_info.ts_urls):
                tmp_file = os.path.join(tmp_dir, ts_url.rsplit('/', 1)[-1])
                decrypt_file = os.path.join(tmp_dir, 'decrypt_' + ts_url.rsplit('/', 1)[-1])
                dst_file = decrypt_file if CRYPTO_ENABLE and m3u8_info.encrypt_method is not None else tmp_file

                if not os.path.exists(dst_file):
                    print('Some files fail to download or decrypt, try again!')
                    return

                with open(dst_file, 'rb') as f:
                    f_out.write(f.read())

        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
예제 #8
0
 def fetch_playlist(link, token=None):
     params = {'allow_source': 'true'} if token else {}
     params.update(
         {'token': token['token'], 'sig': token['sig']} if token else {}
     )
     raw_playlist = Contents.utf8(link, params=params, onerror=lambda _: None)
     if raw_playlist is None:
         return M3U8(None)
     return m3u8.loads(raw_playlist)
예제 #9
0
파일: downloader.py 프로젝트: gabri1135/4k
    def __init__(self, _outputFile: PathModel, _tempFolder: PathModel = None) -> None:
        if _tempFolder is None:
            _tempFolder = _outputFile.temp()
        os.chdir(_tempFolder.path)

        try:
            progress = int(re.findall("file tmp_(.*).mp4",
                                      open('temp.txt', 'r').readlines()[-3])[0])+1
        except:
            progress = 0

        key, M3U8s = M3U8.getAll(self)

        dec = Decrypt(key)

        l = len(M3U8s)
        id = Id(l, progress)

        try:
            for i in range(progress, l):
                file_name = 'tmp_%s.mp4' % id.add()
                print('Processing %d of %d' % (i+1, l))

                url = M3U8s[i].url
                url = "http" + url.removeprefix("https")

                open(file_name, 'wb').write(
                    dec.get(self.getFile(url)))

                open('temp.txt', 'a').write(
                    "file %s\nduration %s\n\n" % (file_name, M3U8s[i].duration))

        except:
            print("Errore nel download dei file\nRiprova in seguito")

        else:
            #            size = 0
            #            st = os.stat_result.
            #            free = st.f_bavail * st.f_frsize
            #            for file_name in os.listdir(tempPath):
            #                size += os.path.getsize(file_name)
            #
            #            if free >= size:
            self._concatenateAll()
#            else:
#                self._concatenateProgress(l)

            os.chdir(_tempFolder.dir)

            shutil.move("%s\\output.mp4" % _tempFolder.name, _outputFile.path)
            shutil.rmtree(_tempFolder.path)
예제 #10
0
파일: cnwkw.py 프로젝트: liuxiang0/cnwkw
def vido_download(num, videolist):
    '''下载视频文件,cnwkw.cn 网站上的视频分为 '流畅-LD' '标清-SD' '高清-HD',
    param num, videolist: numberID and video links list
    '''

    print("ResourceID: {0}".format(num))
    for video in videolist:
        # similiar to dict
        # {'definition': '流畅', 'format': 'mp4', 'url':
        # 'http://video.cnwkw.cn/WeiKe/video/201506/0215/928c9efb778f4c598449401f984603ca-LD.mp4'}
        # {'definition': '高清', 'format': 'm3u8', 'url':
        # 'http://video.cnwkw.cn/WeiKe/video/201710/1008/d9557690d81e4287a6fc3d41e39e05cf-HD.m3u8'}

        filename = video['url'].split('/')[-1]  # 解析内部文件名
        #suffix = video['url'].split('-')[-1]  # 解析文件名后缀,含分辨率 LD,SD,HD和文件格式

        print("Definition: {0}, Format: {1}, Filename: {2}, ...".format(
            video['definition'], video['format'], filename))

        # KEY: Copy a network object to a local file by using urllib.request.urlretrieve(URL, local_filename)

        # '高清' 视频(多为 m3u8 播放格式)下载, 可以借鉴 u3u8 module(from model.py)
        if video['format'].lower() == 'm3u8':
            url = video['url']
            base_path = url.rsplit('/', 1)[0]
            request = urllib.request.Request(
                url, headers={'User-Agent': UserAgent().random})
            response = urllib.request.urlopen(request)
            all_content = response.read()  # return 'bytes-object'
            all_content = all_content.decode(
                'utf-8')  # return 'string' after decoding by 'utf-8'
            response.close()
            #all_content = requests.get(url, headers=header).text  # replaced by Request/urlopen

            # 通过文本内容,调用m3u8模块中的类M3U8,和save_m3u过程
            m3u = M3U8(all_content, base_path=base_path)
            m3u_filename = video_file(num, video['definition'])
            #print("M3U Fielname: {0}".format(m3u_filename))
            save_m3u(m3u, m3u_filename)
            #download(num, video['definition'], video['url'])
        elif video['format'].lower() == 'mp4':
            mp4_filename = video_file(num, video['definition'])
            print('MP4 Filename: {0}'.format(mp4_filename))
            #urllib.request.urlretrieve(video['url'], mp4_filename)
            #MP_dir + num+'-'+suffix)  #'.'+video['format'])
        else:
            print("Unknown video format {0} in URL {1}".format(
                video['fromat'], video['url']))
예제 #11
0
 def get_m3u8(self, quality: str):
     if self.__m3u8:
         return self.__m3u8
     else:
         REFERER = self.__generate_referer()
         HEADERS = self.headers
         HEADERS.update({
             'REFERER': REFERER,
             'ORIGIN': 'https://aniwatch.me'
         })
         aniwatch_episode = self.get_aniwatch_episode()
         res = requests.get(aniwatch_episode.stream.sources[quality],
                            headers=HEADERS,
                            cookies=self.cookies)
         self.__m3u8 = M3U8(res.text)
         return self.__m3u8
예제 #12
0
 def _get_playlist_url(self) -> str:
     log.debug(f'Retrieving playlist: {self.video_id} {self.quality}')
     self._variant_m3u8 = M3U8(self._variant_fetch())
     try:
         return cast(
             str,
             next(playlist.uri for playlist in self._variant_m3u8.playlists
                  if playlist.media[0].group_id == self.quality))
     except StopIteration:
         qualities = [
             playlist.media[0].group_id
             for playlist in self._variant_m3u8.playlists
         ]
         msg = f"Got '{self.quality}' while expected one of {qualities}"
         log.exception(msg)
         raise
예제 #13
0
 def _playlist_updated(self, pl):
     if pl and pl.has_programs():
         # if we got a program playlist, save it and start a program
         self._program_playlist = pl
         (program_url, _) = pl.get_program_playlist(self.program,
                                                    self.bitrate)
         return self._reload_playlist(
             M3U8(program_url, self._cookies, self.hls_headers))
     elif pl and pl.has_files():
         # we got sequence playlist, start reloading it regularly, and get files
         self._file_playlist = pl
         if not self._files:
             self._files = pl.iter_files()
         if not pl.endlist():
             reactor.callLater(pl.reload_delay(), self._reload_playlist, pl)
         if self._file_playlisted:
             self._file_playlisted.callback(pl)
             self._file_playlisted = None
     else:
         raise Exception('Playlist has no valid content.')
     return pl
예제 #14
0
KICKFLIP_USER_NAME = ''
KICKFLIP_UUID = ''
KICKFLIP_ACCESS_TOKEN = ''
KICKFLIP_SECRET_ACCESS_TOKEN = ''

# Amazon
AWS_ACCESS_KEY = ''
AWS_SECRET_ACCESS_KEY = ''

s3 = None

# Video settings
VIDEO_BITRATE = '2000k'
AUDIO_BITRATE = '128k'

playlist = M3U8()

####################
# AWS
####################


def set_aws_keys(USERNAME, AWS_ACCESS_KEY_VAR, AWS_SECRET_ACCESS_KEY_VAR):
    global AWS_ACCESS_KEY
    global AWS_SECRET_ACCESS_KEY
    global KICKFLIP_USER_NAME

    AWS_ACCESS_KEY = AWS_ACCESS_KEY_VAR
    AWS_SECRET_ACCESS_KEY = AWS_SECRET_ACCESS_KEY_VAR
    KICKFLIP_USER_NAME = USERNAME
예제 #15
0
 def update(self, use_old_url: bool = False) -> None:
     if not use_old_url:
         self._url = self._get_playlist_url()
     request = get_url(self.url)
     self._m3u8 = M3U8(request.text)
예제 #16
0
    def start(self, agfid, device_name, temp_file_dir):

        params = {
            'segment_list_file_abs_path':
            temp_file_dir + str(datetime.datetime.now())[:10] + '.m3u8',
            'segment_afid_list_file_abs_path':
            temp_file_dir + str(datetime.datetime.now())[:10] + '_afid.m3u8',
            'segement_time':
            8,
            'device_mount_point':
            '/dev/' + device_name
        }
        self.ffmpeg = FFmpeg(self.get_live_command(params))

        live = None
        if agfid == "":
            res, err = self.afs.create_gfid()
            if err is not None:
                return err
        live = Live(res.agfid)

        err = self.ffmpeg.start()
        start = timer()
        now = datetime.datetime.now()
        live_time = now

        for line in self.ffmpeg.get_stdout():
            line = line.decode()
            if self.ffmpeg.is_fail_to_find_video_device(line):
                err = "cannot find video device " + params['device_mount_point']
                return err

            if self.ffmpeg.is_video_device_busy(line):
                err = "cannot connect to video device " + params[
                    'device_mount_point'] + " since it is busy"
                return err

            if self.ffmpeg.is_creating_segment_ts(line):
                if is_m3u8_file_exists(params):
                    m3u8 = M3U8(params['segment_list_file_abs_path'])
                    afid_m3u8 = None
                    if not is_afid_m3u8_file_exists(params):
                        contents = m3u8.get_contents(
                            m3u8.get_number_of_line() - 1)
                        afid_m3u8 = M3U8(
                            params['segment_afid_list_file_abs_path'])
                        afid_m3u8.create_from_contents(contents)
                        afid_m3u8.append_end("\n")
                        afid_m3u8.append_end(live.cts_afid)
                    else:
                        contents = m3u8.get_contents(
                            m3u8.get_number_of_line() - 1)
                        afid_m3u8 = M3U8(
                            params['segment_afid_list_file_abs_path'])
                        afid_m3u8.append_end("\n")
                        afid_m3u8.append_end(contents[-1])
                        afid_m3u8.append_end(live.cts_afid)
                    live.set_afid_m3u8(afid_m3u8)
                    live.set_m3u8(m3u8)

                    res, err = self.afs.upload(live.get_afid_m3u8().abs_path)
                    if err is not None:
                        return err
                    res, err = self.afs.set_gfid(live.get_agfid(), res.afid)
                    if err is not None:
                        return err

                live.num_of_ts = live.num_of_ts + 1
                live_time += datetime.timedelta(0, params['segement_time'])

            cmd_out = "live_start=" + now.strftime(
                "%Y-%m-%d %H:%M:%S"
            ) + ";lastest_up_cdn=" + datetime.datetime.now().strftime(
                "%Y-%m-%d %H:%M:%S") + ";num_of_ts=" + str(
                    live.num_of_ts) + ";live_time=" + live_time.strftime(
                        "%Y-%m-%d %H:%M:%S") + ";agfid=" + live.agfid + ";"
            print(cmd_out, flush=True)
            logging.info(cmd_out)
            live.cts_abs_path = self.ffmpeg.get_file_name_current_segemnt_ts(
                line)

            if self.ffmpeg.is_creating_segment_list(line):
                if live.cts_abs_path != None:
                    res = self.afs.upload(live.cts_abs_path)
                    if err is not None:
                        return err
                    live.cts_afid = res.afid
                    os.remove(live.cts_abs_path)
        return err
예제 #17
0
파일: run.py 프로젝트: ricardolyn/m3u8
import csv
import m3u8
from m3u8 import M3U8

# this could also be an absolute filename
m3u8_obj = m3u8.load(
    'http://tvdomel.com:8880/get.php?username=XXXX&password=YYYY&type=m3u&output=ts'
)
#print m3u8_obj.segments

outputTV = M3U8()
outputAll = M3U8()

orderTV = []
orderAll = []
configMap = {}
segmentMap = {}

with open('config.csv') as csvfile:
    readCSV = csv.reader(csvfile, delimiter=',')
    for row in readCSV:
        orderTV.append(row[4])
        configMap[row[4]] = row

for x in m3u8_obj.segments:
    if (".ts" in x.uri):
        if x.title not in orderTV:
            orderTV.append(x.title)
            orderAll.append(x.title)
    else:
        orderAll.append(x.title)