Example #1
0
 def writeDuration(self, duration):
     if self._debug:
         print('writing duration', duration)
     output = amf.AMFBytesIO()
     amfWriter = amf.AMF0(output)  # TODO: use AMF3 if needed
     amfWriter.write('onMetaData')
     amfWriter.write(
         {"duration": duration, "videocodecid": 7, "audiocodecid": 10})
     output.seek(0)
     data = output.read()
     length, ts = len(data), 0
     data = struct.pack(
         '>BBHBHB',
         Message.DATA,
         (length >> 16) & 0xff,
         length & 0x0ffff,
         (ts >> 16) & 0xff,
         ts & 0x0ffff,
         (ts >> 24) & 0xff) + b'\x00\x00\x00' + data
     data += struct.pack('>I', len(data))
     lastpos = self.fp.tell()
     if lastpos != 13:
         self.fp.seek(13, os.SEEK_SET)
     self.fp.write(data)
     if lastpos != 13:
         self.fp.seek(lastpos, os.SEEK_SET)
Example #2
0
    def fromMessage(cls, message):
        ''' initialize from a parsed RTMP message'''
        assert (message.type
                in [Message.RPC, Message.RPC3, Message.DATA, Message.DATA3])

        length = len(message.data)
        if length == 0:
            raise ValueError('zero length message data')

        if message.type == Message.RPC3 or message.type == Message.DATA3:
            assert message.data[0] == b'\x00'  # must be 0 in AMF3
            data = message.data[1:]
        else:
            data = message.data

        #from pyamf import remoting
        amfReader = amf.AMF0(data)
        inst = cls()
        inst.type = message.type
        inst.time = message.time
        inst.name = amfReader.read()  # first field is command name

        try:
            if message.type == Message.RPC or message.type == Message.RPC3:
                inst.id = amfReader.read()  # second field *may* be message id
                inst.cmdData = amfReader.read()  # third is command data
            else:
                inst.id = 0
            inst.args = []  # others are optional
            while True:
                inst.args.append(amfReader.read())  # amfReader.read())
        except EOFError:
            pass
        return inst
Example #3
0
 def writeDuration(self, duration):
     if self._debug:
         print("writing duration", duration)
     output = amf.AMFBytesIO()
     amfWriter = amf.AMF0(output)  # TODO: use AMF3 if needed
     amfWriter.write("onMetaData")
     amfWriter.write({
         "duration": duration,
         "videocodecid": 7,
         "audiocodecid": 10
     })
     output.seek(0)
     data = output.read()
     length, ts = len(data), 0
     data = (struct.pack(
         ">BBHBHB",
         Message.DATA,
         (length >> 16) & 0xFF,
         length & 0x0FFFF,
         (ts >> 16) & 0xFF,
         ts & 0x0FFFF,
         (ts >> 24) & 0xFF,
     ) + b"\x00\x00\x00" + data)
     data += struct.pack(">I", len(data))
     lastpos = self.fp.tell()
     if lastpos != 13:
         self.fp.seek(13, os.SEEK_SET)
     self.fp.write(data)
     if lastpos != 13:
         self.fp.seek(lastpos, os.SEEK_SET)
Example #4
0
 def toMessage(self):
     msg = Message()
     assert self.type
     msg.type = self.type
     msg.time = self.time
     output = amf.AMFBytesIO()
     amfWriter = amf.AMF0(output)
     amfWriter.write(self.name)
     if msg.type == Message.RPC or msg.type == Message.RPC3:
         amfWriter.write(self.id)
         amfWriter.write(self.cmdData)
     for arg in self.args:
         amfWriter.write(arg)
     output.seek(0)
     # hexdump.hexdump(output)
     # output.seek(0)
     if msg.type == Message.RPC3 or msg.type == Message.DATA3:
         data = b'\x00' + output.read()
     else:
         data = output.read()
     msg.data = data
     output.close()
     return msg
Example #5
0
 def reader(self, stream):
     '''A generator to periodically read the file and dispatch them to the stream. The supplied stream
     object must have a send(Message) method and id and client properties.'''
     if self._debug:
         print('reader started')
     yield
     try:
         while self.fp is not None:
             bytes = self.fp.read(11)
             if len(bytes) == 0:
                 try:
                     tm = stream.client.relativeTime
                 except BaseException:
                     tm = 0
                 response = Command(
                     name='onStatus',
                     id=stream.id,
                     tm=tm,
                     args=[
                         amf.Object(
                             level='status',
                             code='NetStream.Play.Stop',
                             description='File ended',
                             details=None)])
                 yield stream.send(response.toMessage())
                 break
             type, len0, len1, ts0, ts1, ts2, sid0, sid1 = struct.unpack(
                 '>BBHBHBBH', bytes)
             length = (len0 << 16) | len1
             ts = (ts0 << 16) | (ts1 & 0x0ffff) | (ts2 << 24)
             body = self.fp.read(length)
             ptagsize, = struct.unpack('>I', self.fp.read(4))
             if ptagsize != (length + 11):
                 if self._debug:
                     print(
                         'invalid previous tag-size found:',
                         ptagsize,
                         '!=',
                         (length + 11),
                         'ignored.')
             if stream is None or stream.client is None:
                 break  # if it is closed
             #hdr = Header(3 if type == Message.AUDIO else 4, ts if ts < 0xffffff else 0xffffff, length, type, stream.id)
             hdr = Header(0, ts, length, type, stream.id)
             msg = Message(hdr, body)
             # if self._debug: print 'FLV.read() length=', length, 'hdr=', hdr
             # if hdr.type == Message.AUDIO: print 'r', hdr.type, hdr.time
             if type == Message.DATA:  # metadata
                 amfReader = amf.AMF0(body)  # TODO: use AMF3 if needed
                 name = amfReader.read()
                 obj = amfReader.read()
                 if self._debug:
                     print('FLV.read()', name, repr(obj))
             yield stream.send(msg)
             if ts > self.tsp:
                 diff, self.tsp = ts - self.tsp, ts
                 if self._debug:
                     print('FLV.read() sleep', diff)
                 yield multitask.sleep(diff / 1000.0)
     except StopIteration:
         pass
     except BaseException:
         if self._debug:
             print('closing the reader', (sys and sys.exc_info() or None))
         if self.fp is not None:
             try:
                 self.fp.close()
             except BaseException:
                 pass
             self.fp = None