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)
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)