Skip to content

Instantly share code, notes, and snippets.

@qrtt1
Last active December 21, 2015 20:49
Show Gist options
  • Save qrtt1/6364303 to your computer and use it in GitHub Desktop.
Save qrtt1/6364303 to your computer and use it in GitHub Desktop.
read flv data
import struct
class FLVParsingError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class FLVTag(object):
TYPE_AUDIO = 0x08
TYPE_VIDEO = 0x09
TYPE_META = 0x12
VALID_TYPE = [TYPE_AUDIO, TYPE_VIDEO, TYPE_META]
def __init__(self, file):
pos = file.tell()
while not self._find_tag(file):
pos = pos + 1
file.seek(pos)
if not self._valid():
return
self.body = file.read(self.body_length)
def _find_tag(self, file):
self.prev_tag_size = self.unpack("4b", file.read(4))
self.type = self.unpack("b", file.read(1))
self.body_length = self.uint24be(file.read(3))
self.timestamp = self.uint24be(file.read(3))
self.padding = self.unpack("4b", file.read(4))
return self._valid()
def _valid(self):
return self.padding == 0 and self.type in FLVTag.VALID_TYPE
def uint24be(self, data):
return self.unpack(">I", '\x00' + data)
def unpack(self, format, data):
unpacked = struct.unpack(format, data)
#print unpacked
return unpacked[0]
def __str__(self):
info = {}
info['prev_tag_size'] = self.prev_tag_size
info['type'] = self.type
info['body_length'] = self.body_length
info['timestamp'] = self.timestamp
return repr(info)
class FLV(object):
FLV_MARKER = "FLV"
FLV_HEADER_SIZE = 9
FLV_VERSION = 1
FLV_TAG_HEADER_SIZE = 15
def __init__(self, file):
self.file = file
self._validate_header()
def _validate_header(self):
header = self.file.read(FLV.FLV_HEADER_SIZE)
print struct.unpack("9b", header)
if FLV.FLV_MARKER == header[:3]:
version = struct.unpack("b", header[3])[0]
size = struct.unpack(">I", header[-4:])[0]
valid = size == FLV.FLV_HEADER_SIZE
valid = valid and version == FLV.FLV_VERSION
if not valid:
raise FLVParsingError("bad flv header")
def read(self):
while True:
try:
tag = FLVTag(self.file)
yield tag
except Exception as e:
break
if __name__ == "__main__":
with open("test1.flv", "rb") as f:
flv = FLV(f)
for t in flv.read():
print t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment