Ejemplo n.º 1
0
def _cat_m4a(audio_resources):
    filenames = [
        get_generated_filename(resource.blob.href, 'audio/mp4', None, resource)
        for resource in audio_resources
    ]

    # join the audio files into one
    tmpdir = mkdtemp()

    def delete_tmpdir(filename=None):
        rmtree(tmpdir, ignore_errors=True)

    output_filename = os.path.join(tmpdir, "joined_audio.m4a")
    logger.info("Joining %d m4a files" % len(filenames))
    try:
        # MP4Box can concatenate a maximum of 20 files at a time, so we call it
        # repeatedly until everything is concatenated.
        from itertools import islice
        MAX_CUMUL_OPS = 20  # as defined in gpac/applications/mp4box/main.c
        i = iter(filenames)
        while True:
            current_filenames = list(islice(i, MAX_CUMUL_OPS))
            if not current_filenames:
                break
            cmd = [
                settings.MP4BOX_PATH, output_filename, '-tmp', tmpdir, '-cat'
            ] + _join_list(current_filenames, '-cat')
            subprocess.check_call(cmd)
    except Exception:
        delete_tmpdir()
        raise
    return iterate_file_then_delete(output_filename, delete_func=delete_tmpdir)
Ejemplo n.º 2
0
def _cat_m4a(audio_resources):
    filenames = [get_generated_filename(resource.blob.href, 'audio/mp4',
                                        None, resource)
                 for resource in audio_resources]

    # join the audio files into one
    tmpdir = mkdtemp()
    def delete_tmpdir(filename=None):
        rmtree(tmpdir, ignore_errors=True)
    output_filename = os.path.join(tmpdir, "joined_audio.m4a")
    logger.info("Joining %d m4a files" % len(filenames))
    try:
        # MP4Box can concatenate a maximum of 20 files at a time, so we call it
        # repeatedly until everything is concatenated.
        from itertools import islice
        MAX_CUMUL_OPS = 20  # as defined in gpac/applications/mp4box/main.c
        i = iter(filenames)
        while True:
            current_filenames = list(islice(i, MAX_CUMUL_OPS))
            if not current_filenames:
                break
            cmd = [settings.MP4BOX_PATH, output_filename, '-tmp', tmpdir, '-cat'] + _join_list(current_filenames, '-cat')
            subprocess.check_call(cmd)
    except Exception:
        delete_tmpdir()
        raise
    return iterate_file_then_delete(output_filename, delete_func=delete_tmpdir)
Ejemplo n.º 3
0
def _cat_webm(audio_resources):
    """
    do the actual call to mkvmerge to concatenate audio files into a podcast.
    webm requires consistent vorbis codebooks in the embedded vorbis stream, if this is not the case,
    we fall back to ffmpeg to reencode the whole thing.
    (documentation about this is pretty limited, refer to mkvmerge sourcecode for details)
    """
    filenames = [get_generated_filename(resource.blob.href, 'audio/ogg',
                                        None, resource)
                 for resource in audio_resources]

    # join the audio files into one
    tmpdir = mkdtemp()
    def delete_tmpdir(filename=None):
        rmtree(tmpdir, ignore_errors=True)
    output_filename = os.path.join(tmpdir, "joined_audio.webm")
    logger.info("Joining %d ogg/vorbis files" % len(filenames))
    try:
        try:
            subprocess.check_call([settings.MKVMERGE_PATH, '-o', output_filename, '-w', '-q'] + _join_list(filenames, '+'))
        except subprocess.CalledProcessError as e:
            # webm format requires "compatible" vorbis codebooks in audio files, if not, we must reencode
            logger.info("couldn't merge files, reencoding the whole podcast")
            # there must be no space between 'concat:' and the first filename, so pass the args as a string
            files = 'concat:' + ''.join(_join_list(filenames, '|'))
            subprocess.check_call([settings.FFMPEG_PATH, '-i', files, '-y', '-aq', '3', output_filename])
    except Exception:
        delete_tmpdir()
        raise
    return iterate_file_then_delete(output_filename, delete_func=delete_tmpdir)
Ejemplo n.º 4
0
def _cat_webm(audio_resources):
    """
    do the actual call to mkvmerge to concatenate audio files into a podcast.
    webm requires consistent vorbis codebooks in the embedded vorbis stream, if this is not the case,
    we fall back to ffmpeg to reencode the whole thing.
    (documentation about this is pretty limited, refer to mkvmerge sourcecode for details)
    """
    filenames = [
        get_generated_filename(resource.blob.href, 'audio/ogg', None, resource)
        for resource in audio_resources
    ]

    # join the audio files into one
    tmpdir = mkdtemp()

    def delete_tmpdir(filename=None):
        rmtree(tmpdir, ignore_errors=True)

    output_filename = os.path.join(tmpdir, "joined_audio.webm")
    logger.info("Joining %d ogg/vorbis files" % len(filenames))
    try:
        try:
            subprocess.check_call(
                [settings.MKVMERGE_PATH, '-o', output_filename, '-w', '-q'] +
                _join_list(filenames, '+'))
        except subprocess.CalledProcessError as e:
            # webm format requires "compatible" vorbis codebooks in audio files, if not, we must reencode
            logger.info("couldn't merge files, reencoding the whole podcast")
            # there must be no space between 'concat:' and the first filename, so pass the args as a string
            files = 'concat:' + ''.join(_join_list(filenames, '|'))
            subprocess.check_call([
                settings.FFMPEG_PATH, '-i', files, '-y', '-aq', '3',
                output_filename
            ])
    except Exception:
        delete_tmpdir()
        raise
    return iterate_file_then_delete(output_filename, delete_func=delete_tmpdir)