def test_create_flv_header(self): data = (((True, True), 'FLV\x01\x05\x00\x00\x00\t\x00\x00\x00\x00'), ((True, False), 'FLV\x01\x04\x00\x00\x00\t\x00\x00\x00\x00'), ((False, True), 'FLV\x01\x01\x00\x00\x00\t\x00\x00\x00\x00'), ((False, False), 'FLV\x01\x00\x00\x00\x00\t\x00\x00\x00\x00')) for has_audio_video, expected in data: s = tags.create_flv_header(*has_audio_video) self.assertEquals(s, expected)
def test_create_flv_header(self): data = (((True, True), 'FLV\x01\x05\x00\x00\x00\t\x00\x00\x00\x00'), ((True, False), 'FLV\x01\x04\x00\x00\x00\t\x00\x00\x00\x00'), ((False, True), 'FLV\x01\x01\x00\x00\x00\t\x00\x00\x00\x00'), ((False, False), 'FLV\x01\x00\x00\x00\x00\t\x00\x00\x00\x00')) for has_audio_video, expected in data: s = tags.create_flv_header(*has_audio_video) self.assertEquals(s, expected)
def _start(self): self.info("Starting feeding") hasVideo = True if not self._videoinfo: self.debug("No video tag received, video disabled") hasVideo = False else: if self._needVideoHeader and not self._gotVideoHeader: self.debug("No video sequence header received, video disabled") hasVideo = False hasAudio = True if not self._audioinfo: self.debug("No Audio tag received, audio disabled") hasAudio = False else: if self._needAudioHeader and not self._gotAudioHeader: self.debug("No Audio sequence header received, audio disabled") hasAudio = False self._videoEnabled = hasVideo self._audioEnabled = hasAudio header = tags.create_flv_header(hasAudio, hasVideo) buffer = self._buildHeaderBuffer(header) caps = gst.caps_from_string("video/x-flv") caps[0]['streamheader'] = (buffer, ) + tuple(self._headers) self._component.setStreamCaps(caps) if self._backlog: self.debug("Flushing backlog of %d buffers", len(self._backlog)) for buffer in self._backlog: self._component.pushStreamBuffer(buffer) self._backlog = [] self._started = True self._changed = False
log.error("Failed to open `%s': %s", outpath, strerror) return False else: try: fd, temppath = tempfile.mkstemp() # preserve the permission bits shutil.copymode(inpath, temppath) fo = os.fdopen(fd, 'wb') except EnvironmentError, (errno, strerror): log.error("Failed to create temporary file: %s", strerror) return False log.debug("Creating the output file") try: fo.write(create_flv_header(has_audio=flv.has_audio, has_video=flv.has_video)) fo.write(payload) f.seek(flv.first_media_tag_offset) shutil.copyfileobj(f, fo) except IOError, (errno, strerror): log.error("Failed to create the indexed file: %s", strerror) if not outpath: # remove the temporary file force_remove(temppath) return False f.close() fo.close() if not outpath: # If we were not writing directly to the output file
def index_file(inpath, outpath=None): out_text = (outpath and ("into file `%s'" % outpath)) or "and overwriting" log.debug("Indexing file `%s' %s", inpath, out_text) try: f = open(inpath, 'rb') except IOError as e5: (errno, strerror) = e5.args log.error("Failed to open `%s': %s", inpath, strerror) return False flv = IndexingFLV(f) tag_iterator = flv.iter_tags() last_tag = None try: while True: tag = next(tag_iterator) # some buggy software, like gstreamer's flvmux, puts a metadata tag # at the end of the file with timestamp 0, and we don't want to # base our duration computation on that if tag.timestamp != 0: last_tag = tag except MalformedFLV as e: message = e.args[0] % e.args[1:] log.error("The file `%s' is not a valid FLV file: %s", inpath, message) return False except EndOfFile: log.error("Unexpected end of file on file `%s'", inpath) return False except StopIteration: pass if not flv.first_media_tag_offset: log.error("The file `%s' does not have any media content", inpath) return False if not last_tag: log.error( "The file `%s' does not have any content with a " "non-zero timestamp", inpath) return False metadata = flv.metadata or {} if flv.metadata_tag_start: original_metadata_size = flv.metadata_tag_end - flv.metadata_tag_start else: log.debug("The file `%s' has no metadata", inpath) original_metadata_size = 0 keyframes = flv.keyframes if flv.no_video: log.info("The file `%s' has no video, using audio seekpoints info", inpath) keyframes = flv.audio_seekpoints duration = metadata.get('duration') if not duration: # A duration of 0 is nonsensical, yet some tools put it like that. In # that case (or when there is no such field) update the duration value. duration = last_tag.timestamp / 1000.0 metadata['duration'] = duration metadata['keyframes'] = keyframes metadata['metadatacreator'] = 'flvlib %s' % __versionstr__ # we're going to write new metadata, so we need to shift the # filepositions by the amount of bytes that we're going to add to # the metadata tag test_payload, difference = filepositions_difference( metadata, original_metadata_size) if difference: new_filepositions = [ pos + difference for pos in keyframes.filepositions ] metadata['keyframes'].filepositions = new_filepositions payload = create_script_tag('onMetaData', metadata) else: log.debug("The file `%s' metadata size did not change.", inpath) payload = test_payload if outpath: try: fo = open(outpath, 'wb') except IOError as e2: (errno, strerror) = e2.args log.error("Failed to open `%s': %s", outpath, strerror) return False else: try: fd, temppath = tempfile.mkstemp() # preserve the permission bits shutil.copymode(inpath, temppath) fo = os.fdopen(fd, 'wb') except EnvironmentError as e3: (errno, strerror) = e3.args log.error("Failed to create temporary file: %s", strerror) return False log.debug("Creating the output file") try: fo.write( create_flv_header(has_audio=flv.has_audio, has_video=flv.has_video)) fo.write(payload) f.seek(flv.first_media_tag_offset) shutil.copyfileobj(f, fo) except IOError as e6: (errno, strerror) = e6.args log.error("Failed to create the indexed file: %s", strerror) if not outpath: # remove the temporary file force_remove(temppath) return False f.close() fo.close() if not outpath: # If we were not writing directly to the output file # we need to overwrite the original try: shutil.move(temppath, inpath) except EnvironmentError as e4: (errno, strerror) = e4.args log.error( "Failed to overwrite the original file " "with the indexed version: %s", strerror) return False return True
log.error("Failed to open `%s': %s", outpath, strerror) return False else: try: fd, temppath = tempfile.mkstemp() # preserve the permission bits shutil.copymode(inpath, temppath) fo = os.fdopen(fd, 'wb') except EnvironmentError, (errno, strerror): log.error("Failed to create temporary file: %s", strerror) return False log.debug("Creating the output file") try: fo.write(create_flv_header(has_audio=flv.has_audio, has_video=flv.has_video)) fo.write(payload) f.seek(flv.first_media_tag_offset) shutil.copyfileobj(f, fo) except IOError, (errno, strerror): log.error("Failed to create the indexed file: %s", strerror) if not outpath: # remove the temporary file force_remove(temppath) return False f.close() fo.close() if not outpath: # If we were not writing directly to the output file
def index_file(inpath, outpath=None): out_text = (outpath and ("into file `%s'" % outpath)) or "and overwriting" log.debug("Indexing file `%s' %s", inpath, out_text) try: f = open(inpath, 'rb') except IOError as e5: (errno, strerror) = e5.args log.error("Failed to open `%s': %s", inpath, strerror) return False flv = IndexingFLV(f) tag_iterator = flv.iter_tags() last_tag = None try: while True: tag = next(tag_iterator) # some buggy software, like gstreamer's flvmux, puts a metadata tag # at the end of the file with timestamp 0, and we don't want to # base our duration computation on that if tag.timestamp != 0: last_tag = tag except MalformedFLV as e: message = e.args[0] % e.args[1:] log.error("The file `%s' is not a valid FLV file: %s", inpath, message) return False except EndOfFile: log.error("Unexpected end of file on file `%s'", inpath) return False except StopIteration: pass if not flv.first_media_tag_offset: log.error("The file `%s' does not have any media content", inpath) return False if not last_tag: log.error("The file `%s' does not have any content with a " "non-zero timestamp", inpath) return False metadata = flv.metadata or {} if flv.metadata_tag_start: original_metadata_size = flv.metadata_tag_end - flv.metadata_tag_start else: log.debug("The file `%s' has no metadata", inpath) original_metadata_size = 0 keyframes = flv.keyframes if flv.no_video: log.info("The file `%s' has no video, using audio seekpoints info", inpath) keyframes = flv.audio_seekpoints duration = metadata.get('duration') if not duration: # A duration of 0 is nonsensical, yet some tools put it like that. In # that case (or when there is no such field) update the duration value. duration = last_tag.timestamp / 1000.0 metadata['duration'] = duration metadata['keyframes'] = keyframes metadata['metadatacreator'] = 'flvlib %s' % __versionstr__ # we're going to write new metadata, so we need to shift the # filepositions by the amount of bytes that we're going to add to # the metadata tag test_payload, difference = filepositions_difference(metadata, original_metadata_size) if difference: new_filepositions = [pos + difference for pos in keyframes.filepositions] metadata['keyframes'].filepositions = new_filepositions payload = create_script_tag('onMetaData', metadata) else: log.debug("The file `%s' metadata size did not change.", inpath) payload = test_payload if outpath: try: fo = open(outpath, 'wb') except IOError as e2: (errno, strerror) = e2.args log.error("Failed to open `%s': %s", outpath, strerror) return False else: try: fd, temppath = tempfile.mkstemp() # preserve the permission bits shutil.copymode(inpath, temppath) fo = os.fdopen(fd, 'wb') except EnvironmentError as e3: (errno, strerror) = e3.args log.error("Failed to create temporary file: %s", strerror) return False log.debug("Creating the output file") try: fo.write(create_flv_header(has_audio=flv.has_audio, has_video=flv.has_video)) fo.write(payload) f.seek(flv.first_media_tag_offset) shutil.copyfileobj(f, fo) except IOError as e6: (errno, strerror) = e6.args log.error("Failed to create the indexed file: %s", strerror) if not outpath: # remove the temporary file force_remove(temppath) return False f.close() fo.close() if not outpath: # If we were not writing directly to the output file # we need to overwrite the original try: shutil.move(temppath, inpath) except EnvironmentError as e4: (errno, strerror) = e4.args log.error("Failed to overwrite the original file " "with the indexed version: %s", strerror) return False return True