예제 #1
0
class VodFragment(object):

    def __init__(self, stream):
        self._stream = RtmpStreamReader(stream)
        self._skip_meta = self._skip_head = self._skip_magic_head = False
        #self._skip_audio_tag = self._skip_video_tag = False
        self._skip_audio_tag = True
        self._skip_video_tag = False
        self._buf = []
        self.onMetaData = None

    def handle_magic_head(self, tag):
        """
        Catch the first audio tag and video tag in the stream.
        """
        if not self._skip_video_tag and tag.type == VIDEO_TAG:
            self._first_video_tag = tag
            self._skip_video_tag = True
        if not self._skip_audio_tag and tag.type == AUDIO_TAG:
            self._first_audio_tag = tag
            self._skip_audio_tag = True
        return (not(self._skip_audio_tag and self._skip_video_tag))
        #return (not(self._skip_audio_tag or self._skip_video_tag))
    
    def slice_head(self):
        for tag in self._stream:
            last_position = self._stream.position()
            self._buf.append(tag)
            if isinstance(tag, Tag):
                if tag.type == 18 and self.onMetaData:
                    self.onMetaData(tag)
                if not self.handle_magic_head(tag):
                    return last_position
        return last_position

    def flush(self):
        buf = ''
        for tag in self._buf:
            if isinstance(tag, Head):
                buf += pack_head(tag)
            else:
                buf += tag.pack()
        return buf
예제 #2
0
class VodFragment(object):
    def __init__(self, stream):
        self._stream = RtmpStreamReader(stream)
        self._skip_meta = self._skip_head = self._skip_magic_head = False
        #self._skip_audio_tag = self._skip_video_tag = False
        self._skip_audio_tag = True
        self._skip_video_tag = False
        self._buf = []
        self.onMetaData = None

    def handle_magic_head(self, tag):
        """
        Catch the first audio tag and video tag in the stream.
        """
        if not self._skip_video_tag and tag.type == VIDEO_TAG:
            self._first_video_tag = tag
            self._skip_video_tag = True
        if not self._skip_audio_tag and tag.type == AUDIO_TAG:
            self._first_audio_tag = tag
            self._skip_audio_tag = True
        return (not (self._skip_audio_tag and self._skip_video_tag))
        #return (not(self._skip_audio_tag or self._skip_video_tag))

    def slice_head(self):
        for tag in self._stream:
            last_position = self._stream.position()
            self._buf.append(tag)
            if isinstance(tag, Tag):
                if tag.type == 18 and self.onMetaData:
                    self.onMetaData(tag)
                if not self.handle_magic_head(tag):
                    return last_position
        return last_position

    def flush(self):
        buf = ''
        for tag in self._buf:
            if isinstance(tag, Head):
                buf += pack_head(tag)
            else:
                buf += tag.pack()
        return buf
예제 #3
0
class FlvFragment(Fragment):
    def __init__(self, fn, mode=True):
        stream = file(fn)
        self._fd = os.open(fn, os.O_RDONLY)
        self._reader = RtmpStreamReader(stream)
        self._pre_pos = 0
        self._skip_first_video_tag = False
        self._first_video_tag = None
        self._head = None
        self._keyframes = []
        self._skip_video_tag = False
        self._skip_first_audio_tag = False
        self._first_audio_tag = None
        self._head_dead_line = 0
        super(FlvFragment, self).__init__(mode=mode)
        self._swig = 0

    def position(self):
        return self._reader.position()

    def get_keyframes(self):
        return self._keyframes

    keyframes = property(get_keyframes)

    def size(self):
        return len(self._keyframes)

    def append_keyframe(self, tag):
        self._keyframes.append((self._pre_pos, tag.timestamp))
        self._ptr = len(self._keyframes) - 1
        self._swig = 0  #init loop

    def incr(self, step):
        if self.pointer == self.size() - 1:
            self._ptr += 1
            self._swig = 0
        else:
            self._swig += step
            span = self.span()
            print 'cacle %d' % (span, )
            if self._swig > span:
                self._ptr += 1
                print "increase ptr %d" % self._ptr
                self._swig -= span

    def span(self):
        if self.pointer >= self.size() - 1:
            return 0
        p = self.pointer
        a = self._keyframes[p][1]
        b = self._keyframes[p + 1][1]
        return ((b - a) / 1000)

    def advance(self):
        """
        Get a slice of CPU time to run.
        """
        in_bytes = self._pre_pos
        for tag in self._reader:
            if isinstance(tag, Tag):
                # skip the Metadata in flv stream.
                if not self.handle_magic_head(tag):
                    if tag.type == VIDEO_TAG and tag.is_keyframe:
                        self.append_keyframe(tag)
                self._pre_pos = self.position()
        in_bytes = self._pre_pos - in_bytes
        if in_bytes > 0:
            self.active()
        else:
            self.inactive()

    def handle_magic_head(self, tag):
        """
        Catch the first audio tag and video tag in the stream.
        """
        if not self._skip_video_tag and tag.type == VIDEO_TAG:
            self._first_video_tag = tag
            self._head_dead_line = self.position()
            self._skip_video_tag = True
        if not self._skip_first_audio_tag and tag.type == AUDIO_TAG:
            self._first_audio_tag = tag
            self._head_dead_line = self.position()
            self._skip_first_audio_tag = True
        return (not (self._skip_video_tag and self._skip_first_audio_tag))

    def do(self, start=-1, offset=None, flag=False, keyIndex=None):
        begin = end = 0
        current = keyIndex and keyIndex or self.pointer
        if start < 0:  #从关键帧开始取数据
            begin = self._keyframes[current][0]
        else:
            begin = start
        end = offset and min(begin + offset,
                             self.position()) or self.position()
        data_length = end - begin
        data = ''
        if data_length > 0:
            os.lseek(self._fd, begin, os.SEEK_SET)
            data = os.read(self._fd, data_length)
        else:
            raise OSError("Reach file end.")

        body = ''
        if flag:
            if not self._head and self._head_dead_line:
                os.lseek(self._fd, 0, os.SEEK_SET)
                self._head = os.read(self._fd, self._head_dead_line)
            body += struct.pack('>H%ds' % (len(self._head), ), len(self._head),
                                self._head)
        else:
            body += struct.pack('>H', 0)
        body += struct.pack('>QIH', begin, data_length,
                            config.NEXT_REQ_DELAY_TIME)
        #filepositions
        temp = ''
        for (k, t) in self._keyframes:
            if k >= begin:
                temp += struct.pack('>QI', k, t)
            if k > end:
                break
        body += struct.pack('>I', len(temp) / 12) + temp
        # insert head length
        body = struct.pack('>I', len(body)) + body + data
        return body

    def close(self):
        os.close(self._fd)
        self._reader.close()
예제 #4
0
class FlvFragment(Fragment):
    def __init__(self, fn, mode=True):
        stream = file(fn)
        self._fd = os.open(fn, os.O_RDONLY)
        self._reader = RtmpStreamReader(stream)
        self._pre_pos = 0
        self._skip_first_video_tag = False 
        self._first_video_tag = None
        self._head = None 
        self._keyframes = []
        self._skip_video_tag = False
        self._skip_first_audio_tag = False 
        self._first_audio_tag = None
        self._head_dead_line = 0
        super(FlvFragment, self).__init__(mode=mode)
        self._swig = 0
    def position(self):
        return self._reader.position()
    def get_keyframes(self):
        return self._keyframes
    keyframes = property(get_keyframes)
    def size(self):
        return len(self._keyframes)
    def append_keyframe(self, tag):
        self._keyframes.append((self._pre_pos, tag.timestamp))
        self._ptr = len(self._keyframes) - 1
        self._swig = 0 #init loop
    def incr(self, step):
        if self.pointer == self.size() - 1:
            self._ptr += 1
            self._swig = 0
        else:
            self._swig += step
            span = self.span()
            print 'cacle %d' % (span,)
            if self._swig > span:
                self._ptr += 1 
                print "increase ptr %d" % self._ptr
                self._swig -= span
    def span(self):
        if self.pointer >= self.size() - 1:
            return 0
        p = self.pointer
        a = self._keyframes[p][1]
        b = self._keyframes[p+1][1]
        return ((b - a)/1000)
        
    def advance(self):
        """
        Get a slice of CPU time to run.
        """
        in_bytes = self._pre_pos
        for tag in self._reader:
            if isinstance(tag, Tag):
                # skip the Metadata in flv stream.
                if not self.handle_magic_head(tag):
                    if tag.type == VIDEO_TAG and tag.is_keyframe:
                        self.append_keyframe(tag)
                self._pre_pos = self.position()
        in_bytes = self._pre_pos - in_bytes
        if in_bytes > 0:
            self.active()
        else:
            self.inactive()
    def handle_magic_head(self, tag):
        """
        Catch the first audio tag and video tag in the stream.
        """
        if not self._skip_video_tag and tag.type == VIDEO_TAG:
            self._first_video_tag = tag
            self._head_dead_line = self.position()
            self._skip_video_tag = True
        if not self._skip_first_audio_tag and tag.type == AUDIO_TAG:
            self._first_audio_tag = tag
            self._head_dead_line = self.position()
            self._skip_first_audio_tag = True
        return (not(self._skip_video_tag and self._skip_first_audio_tag))

    def do(self, start=-1, offset=None, flag=False, keyIndex=None):
        begin = end = 0
        current = keyIndex and keyIndex or self.pointer
        if start < 0: #从关键帧开始取数据
            begin = self._keyframes[current][0]
        else:
            begin = start
        end = offset and min(begin + offset, self.position()) or self.position()
        data_length = end - begin
        data = ''
        if data_length > 0:
            os.lseek(self._fd, begin, os.SEEK_SET)
            data = os.read(self._fd, data_length)
        else:
            raise OSError("Reach file end.")

        body = ''
        if flag:
            if not self._head and self._head_dead_line:
                os.lseek(self._fd, 0, os.SEEK_SET)
                self._head = os.read(self._fd, self._head_dead_line)
            body += struct.pack('>H%ds'%(len(self._head),), len(self._head), self._head)
        else:
            body += struct.pack('>H', 0)
        body += struct.pack('>QIH', begin, data_length, config.NEXT_REQ_DELAY_TIME)
        #filepositions
        temp = ''
        for (k,t) in self._keyframes:
            if k >= begin:
                temp += struct.pack('>QI', k, t)
            if k > end:
                break
        body += struct.pack('>I', len(temp)/12) + temp
        # insert head length
        body = struct.pack('>I', len(body)) + body + data
        return body

    def close(self):
        os.close(self._fd)
        self._reader.close()