Esempio n. 1
0
def retimestamp_and_index_file(inpath, outpath=None, retimestamp=None):

    # no retimestamping needed
    if retimestamp is None:

        return index_file(inpath, outpath)

    # retimestamp the input in place and index
    elif retimestamp == 'inplace':
        from flvlib.scripts.retimestamp_flv import retimestamp_file_inplace

        log.debug("Retimestamping file `%s' in place", inpath)

        # retimestamp the file inplace
        if not retimestamp_file_inplace(inpath):
            log.error("Failed to retimestamp `%s' in place", inpath)
            return False

        return index_file(inpath, outpath)

    # retimestamp the input into a temporary file
    elif retimestamp == 'atomic':
        from flvlib.scripts.retimestamp_flv import retimestamp_file_atomically

        log.debug("Retimestamping file `%s' atomically", inpath)

        try:
            fd, temppath = tempfile.mkstemp()
            os.close(fd)
            # preserve the permission bits
            shutil.copymode(inpath, temppath)
        except EnvironmentError, (errno, strerror):
            log.error("Failed to create temporary file: %s", strerror)
            return False

        if not retimestamp_file_atomically(inpath, temppath):
            log.error("Failed to retimestamp `%s' atomically", inpath)
            # remove the temporary files
            force_remove(temppath)
            return False

        # index the temporary file
        if not index_file(temppath, outpath):
            force_remove(temppath)
            return False

        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, (errno, strerror):
                log.error(
                    "Failed to overwrite the original file with the "
                    "retimestamped and indexed version: %s", strerror)
                return False
Esempio n. 2
0
def retimestamp_and_index_file(inpath, outpath=None, retimestamp=None):

    # no retimestamping needed
    if retimestamp is None:

        return index_file(inpath, outpath)

    # retimestamp the input in place and index
    elif retimestamp == 'inplace':
        from flvlib.scripts.retimestamp_flv import retimestamp_file_inplace

        log.debug("Retimestamping file `%s' in place", inpath)

        # retimestamp the file inplace
        if not retimestamp_file_inplace(inpath):
            log.error("Failed to retimestamp `%s' in place", inpath)
            return False

        return index_file(inpath, outpath)

    # retimestamp the input into a temporary file
    elif retimestamp == 'atomic':
        from flvlib.scripts.retimestamp_flv import retimestamp_file_atomically

        log.debug("Retimestamping file `%s' atomically", inpath)

        try:
            fd, temppath = tempfile.mkstemp()
            os.close(fd)
            # preserve the permission bits
            shutil.copymode(inpath, temppath)
        except EnvironmentError, (errno, strerror):
            log.error("Failed to create temporary file: %s", strerror)
            return False

        if not retimestamp_file_atomically(inpath, temppath):
            log.error("Failed to retimestamp `%s' atomically", inpath)
            # remove the temporary files
            force_remove(temppath)
            return False

        # index the temporary file
        if not index_file(temppath, outpath):
            force_remove(temppath)
            return False

        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, (errno, strerror):
                log.error("Failed to overwrite the original file with the "
                          "retimestamped and indexed version: %s", strerror)
                return False
Esempio n. 3
0
            force_remove(temppath)
            return False

        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, (errno, strerror):
                log.error("Failed to overwrite the original file with the "
                          "retimestamped and indexed version: %s", strerror)
                return False
        else:
            # if we were writing directly to the output file we need to remove
            # the retimestamped temporary file
            force_remove(temppath)

        return True


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, (errno, strerror):
        log.error("Failed to open `%s': %s", inpath, strerror)
        return False

    flv = IndexingFLV(f)
Esempio n. 4
0
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
Esempio n. 5
0
            force_remove(outpath)
            return False

        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, (errno, strerror):
                log.error("Failed to overwrite the original file with the "
                          "retimestamped and indexed version: %s", strerror)
                return False
        else:
            # if we were writing directly to the output file we need to remove
            # the retimestamped temporary file
            force_remove(outpath)

        return True


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, (errno, strerror):
        log.error("Failed to open `%s': %s", inpath, strerror)
        return False

    flv = IndexingFLV(f)
Esempio n. 6
0
def retimestamp_file_atomically(inpath, outpath):
    try:
        f = open(inpath, 'rb')
    except IOError as e5:
        (errno, strerror) = e5.args
        log.error("Failed to open `%s': %s", inpath, strerror)
        return False

    if outpath:
        try:
            fo = open(outpath, 'w+b')
        except IOError as e:
            (errno, strerror) = e.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 e1:
            (errno, strerror) = e1.args
            log.error("Failed to create temporary file: %s", strerror)
            return False

    try:
        shutil.copyfileobj(f, fo)
    except EnvironmentError as e6:
        (errno, strerror) = e6.args
        log.error("Failed to create temporary copy: %s", strerror)
        force_remove(temppath)
        return False

    f.seek(0)
    fo.seek(0)

    try:
        retimestamp_tags_inplace(f, fo)
    except IOError as e7:
        (errno, strerror) = e7.args
        log.error("Failed to create the retimestamped file: %s", strerror)
        if not outpath:
            force_remove(temppath)
        return False
    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)
        if not outpath:
            force_remove(temppath)
        return False
    except EndOfFile:
        log.error("Unexpected end of file on file `%s'", inpath)
        if not outpath:
            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 e2:
            (errno, strerror) = e2.args
            log.error(
                "Failed to overwrite the original file "
                "with the indexed version: %s", strerror)
            return False

    return True
Esempio n. 7
0
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
Esempio n. 8
0
def retimestamp_file_atomically(inpath, outpath):
    try:
        f = open(inpath, 'rb')
    except IOError as e5:
        (errno, strerror) = e5.args
        log.error("Failed to open `%s': %s", inpath, strerror)
        return False

    if outpath:
        try:
            fo = open(outpath, 'w+b')
        except IOError as e:
            (errno, strerror) = e.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 e1:
            (errno, strerror) = e1.args
            log.error("Failed to create temporary file: %s", strerror)
            return False

    try:
        shutil.copyfileobj(f, fo)
    except EnvironmentError as e6:
        (errno, strerror) = e6.args
        log.error("Failed to create temporary copy: %s", strerror)
        force_remove(temppath)
        return False

    f.seek(0)
    fo.seek(0)

    try:
        retimestamp_tags_inplace(f, fo)
    except IOError as e7:
        (errno, strerror) = e7.args
        log.error("Failed to create the retimestamped file: %s", strerror)
        if not outpath:
            force_remove(temppath)
        return False
    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)
        if not outpath:
            force_remove(temppath)
        return False
    except EndOfFile:
        log.error("Unexpected end of file on file `%s'", inpath)
        if not outpath:
            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 e2:
            (errno, strerror) = e2.args
            log.error("Failed to overwrite the original file "
                      "with the indexed version: %s", strerror)
            return False

    return True