示例#1
0
    def __init__(self, key):
        key = bytes_list(key)
        data = list(range(256))

        b, n = 0, len(key)
        for i in range(256):
            b += (data[i] + key[i%n])
            b &= 0xff
            data[i], data[b] = data[b], data[i]

        self.c1 = self.c2 = 0
        self.data = data
示例#2
0
def extract_strings(data, keys):
    fd = BytesIO(keys)
    keys = [fd.read(16) for i in range(U8.read(fd))]
    if not keys:
        return

    fd = BytesIO(data)
    for i in range(U32LE.read(fd)):
        msg = fd.read(U32LE.read(fd))
        key = keys[i % len(keys)]

        return Decryptor(key).decrypt(msg)
示例#3
0
    def _create_flv_playlist(self, template):
        res = http.get(template)
        json = http.json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")

        parsed = urlparse(template)
        try:
            url_template = '{0}://{1}{2}'.format(parsed.scheme, parsed.netloc,
                                                 json['template'])
            segment_max = reduce(lambda i, j: i + j[0], json['fragments'], 0)
            duration = json['duration']
        except KeyError:
            raise PluginError('Unexpected JSON response')

        substreams = [
            HTTPStream(self.session,
                       url_template.replace('$fragment$', str(i)))
            for i in range(1, segment_max + 1)
        ]

        return FLVPlaylist(self.session,
                           streams=substreams,
                           duration=duration,
                           skip_header=True,
                           flatten_timestamps=True)
示例#4
0
    def update_chunk_info(self, result):
        chunk_range = result["chunkRange"]
        if not chunk_range:
            return

        chunk_id = int(result["chunkId"])
        chunk_offset = int(result["offset"])
        chunk_range = dict(map(partial(map, int), chunk_range.items()))

        self.chunk_ranges.update(chunk_range)
        self.chunk_id_min = sorted(chunk_range)[0]
        self.chunk_id_max = int(result["chunkId"])
        self.chunks = [Chunk(i, self.format_chunk_url(i),
                             not self.chunk_id and i == chunk_id and chunk_offset)
                       for i in range(self.chunk_id_min, self.chunk_id_max + 1)]

        if self.chunk_id is None and self.chunks:
            self.chunk_id = chunk_id
示例#5
0
 def iter_segments(self):
     quality = QUALITY_MAP[self.stream.quality]
     for part in self.stream.parts:
         duration = part.get("duration")
         if not part.get("recording"):
             recording = part.get("id")
             extension = "part"
         else:
             recording = part.get("recording")
             extension = "rec"
         chunks = int(duration / 12) + 1
         start = int(part.get("start", 0) / 12)
         for sequence in range(start, chunks + start):
             if self.closed:
                 return
             self.logger.debug("Adding chunk {0}/{1}/{2} to queue",
                               recording, quality, sequence)
             yield Chunk(recording, quality, sequence, extension)
示例#6
0
    def _create_flv_playlist(self, template):
        res = http.get(template)
        playlist = http.json(res, schema=_vod_playlist_schema)

        parsed = urlparse(template)
        url_template = "{0}://{1}{2}".format(
            parsed.scheme, parsed.netloc, playlist["template"]
        )
        segment_max = reduce(lambda i,j: i + j[0], playlist["fragments"], 0)

        substreams = [HTTPStream(self.session,
                                 url_template.replace("$fragment$", str(i)))
                      for i in range(1, segment_max + 1)]

        return FLVPlaylist(self.session,
                           duration=playlist["duration"],
                           flatten_timestamps=True,
                           skip_header=True,
                           streams=substreams)
示例#7
0
    def _create_flv_playlist(self, template):
        res = http.get(template)
        playlist = http.json(res, schema=_vod_playlist_schema)

        parsed = urlparse(template)
        url_template = "{0}://{1}{2}".format(
            parsed.scheme, parsed.netloc, playlist["template"]
        )
        segment_max = reduce(lambda i,j: i+j[0], playlist["fragments"], 0)

        substreams = [HTTPStream(self.session,
                                 url_template.replace("$fragment$", str(i)))
                      for i in range(1, segment_max + 1)]

        return FLVPlaylist(self.session,
                           duration=playlist["duration"],
                           flatten_timestamps=True,
                           skip_header=True,
                           streams=substreams)
示例#8
0
    def update_chunk_info(self, result):
        chunk_range = result["chunkRange"]
        if not chunk_range:
            return

        chunk_id = int(result["chunkId"])
        chunk_offset = int(result["offset"])
        chunk_range = dict(map(partial(map, int), chunk_range.items()))

        self.chunk_ranges.update(chunk_range)
        self.chunk_id_min = sorted(chunk_range)[0]
        self.chunk_id_max = int(result["chunkId"])
        self.chunks = [
            Chunk(i, self.format_chunk_url(i), not self.chunk_id
                  and i == chunk_id and chunk_offset)
            for i in range(self.chunk_id_min, self.chunk_id_max + 1)
        ]

        if self.chunk_id is None and self.chunks:
            self.chunk_id = chunk_id
示例#9
0
 def iter_segments(self):
     quality = QUALITY_MAP[self.stream.quality]
     for part in self.stream.parts:
         duration = part.get("duration")
         if not part.get("recording"):
             recording = part.get("id")
             extension = "part"
         else:
             recording = part.get("recording")
             extension = "rec"
         chunks = int(duration / 12) + 1
         start = int(part.get("start", 0) / 12)
         for sequence in range(start, chunks + start):
             if self.closed:
                 return
             self.logger.debug("Adding chunk {0}/{1}/{2} to queue",
                               recording,
                               quality,
                               sequence)
             yield Chunk(recording, quality, sequence, extension)
示例#10
0
    def _create_flv_playlist(self, template):
        res = http.get(template)
        json = http.json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")

        parsed = urlparse(template)
        try:
            url_template = '{0}://{1}{2}'.format(
                parsed.scheme, parsed.netloc, json['template']
            )
            segment_max = reduce(lambda i,j: i+j[0], json['fragments'], 0)
            duration = json['duration']
        except KeyError:
            raise PluginError('Unexpected JSON response')

        substreams = [HTTPStream(self.session,
                                 url_template.replace('$fragment$', str(i)))
                      for i in range(1, segment_max + 1)]

        return FLVPlaylist(self.session, streams=substreams,
                           duration=duration, skip_header=True,
                           flatten_timestamps=True)
示例#11
0
    def iter_tags(self, fd=None, buf=None, skip_header=None):
        flags = U8.read(fd)
        quality = flags & 15
        version = flags >> 4
        lookup_size = U16BE.read(fd)
        enc_table = fd.read(lookup_size)

        key = b""
        iv = b""

        for i in range(16):
            key += fd.read(1)
            iv += fd.read(1)

        if not (key and iv):
            return

        dec_table = self.decrypt_data(key, iv, enc_table)
        dstream = BytesIO(dec_table)

        # Decode lookup table (ported from K-S-V BeatConvert.php)
        while True:
            flags = U8.read(dstream)
            if not flags:
                break

            typ = flags >> 4
            encrypted = (flags & 4) > 0
            keyframe = (flags & 2) > 0
            config = (flags & 1) > 0
            time = U32BE.read(dstream)
            data_length = U32BE.read(dstream)

            if encrypted:
                raw_length = U32BE.read(dstream)
            else:
                raw_length = data_length

            # Decrypt encrypted tags
            data = fd.read(data_length)
            if encrypted:
                data = self.decrypt_data(key, iv, data)
                data = data[:raw_length]

            # Create video tag
            if typ == 1:
                if version == 2:
                    if config:
                        avc = AVCVideoData(AVC_PACKET_TYPE_SEQUENCE_HEADER,
                                           data=data)
                    else:
                        avc = AVCVideoData(AVC_PACKET_TYPE_NALU, data=data)

                    if keyframe:
                        videodata = VideoData(VIDEO_FRAME_TYPE_KEY_FRAME,
                                              VIDEO_CODEC_ID_AVC, avc)
                    else:
                        videodata = VideoData(VIDEO_FRAME_TYPE_INTER_FRAME,
                                              VIDEO_CODEC_ID_AVC, avc)
                else:
                    videodata = RawData(data)

                yield Tag(TAG_TYPE_VIDEO, time, videodata)

            # Create audio tag
            if typ == 2:
                if version == 2:
                    if config:
                        aac = AACAudioData(AAC_PACKET_TYPE_SEQUENCE_HEADER,
                                           data)
                    else:
                        aac = AACAudioData(AAC_PACKET_TYPE_RAW, data)

                    audiodata = AudioData(codec=AUDIO_CODEC_ID_AAC,
                                          rate=AUDIO_RATE_44_KHZ,
                                          bits=AUDIO_BIT_RATE_16,
                                          type=AUDIO_TYPE_STEREO,
                                          data=aac)
                else:
                    audiodata = RawData(data)

                yield Tag(TAG_TYPE_AUDIO, time, audiodata)
示例#12
0
    def iter_tags(self, fd=None, buf=None, skip_header=None):
        flags = U8.read(fd)
        quality = flags & 15
        version = flags >> 4
        lookup_size = U16BE.read(fd)
        enc_table = fd.read(lookup_size)

        key = b""
        iv = b""

        for i in range(16):
            key += fd.read(1)
            iv += fd.read(1)

        if not (key and iv):
            return

        dec_table = self.decrypt_data(key, iv, enc_table)
        dstream = BytesIO(dec_table)

        # Decode lookup table (ported from K-S-V BeatConvert.php)
        while True:
            flags = U8.read(dstream)
            if not flags:
                break

            typ = flags >> 4
            encrypted = (flags & 4) > 0
            keyframe = (flags & 2) > 0
            config = (flags & 1) > 0
            time = U32BE.read(dstream)
            data_length = U32BE.read(dstream)

            if encrypted:
                raw_length = U32BE.read(dstream)
            else:
                raw_length = data_length

            # Decrypt encrypted tags
            data = fd.read(data_length)
            if encrypted:
                data = self.decrypt_data(key, iv, data)
                data = data[:raw_length]

            # Create video tag
            if typ == 1:
                if version == 2:
                    if config:
                        avc = AVCVideoData(AVC_PACKET_TYPE_SEQUENCE_HEADER,
                                           data=data)
                    else:
                        avc = AVCVideoData(AVC_PACKET_TYPE_NALU, data=data)

                    if keyframe:
                        videodata = VideoData(VIDEO_FRAME_TYPE_KEY_FRAME,
                                              VIDEO_CODEC_ID_AVC, avc)
                    else:
                        videodata = VideoData(VIDEO_FRAME_TYPE_INTER_FRAME,
                                              VIDEO_CODEC_ID_AVC, avc)
                else:
                    videodata = RawData(data)

                yield Tag(TAG_TYPE_VIDEO, time, videodata)

            # Create audio tag
            if typ == 2:
                if version == 2:
                    if config:
                        aac = AACAudioData(AAC_PACKET_TYPE_SEQUENCE_HEADER,
                                           data)
                    else:
                        aac = AACAudioData(AAC_PACKET_TYPE_RAW, data)

                    audiodata = AudioData(codec=AUDIO_CODEC_ID_AAC,
                                          rate=AUDIO_RATE_44_KHZ,
                                          bits=AUDIO_BIT_RATE_16,
                                          type=AUDIO_TYPE_STEREO,
                                          data=aac)
                else:
                    audiodata = RawData(data)

                yield Tag(TAG_TYPE_AUDIO, time, audiodata)