mediacms-io / mediacms

MediaCMS is a modern, fully featured open source video and media CMS, written in Python/Django and React, featuring a REST API.
https://mediacms.io
GNU Affero General Public License v3.0
2.52k stars 459 forks source link

How to set one frame per second for sprites? #944

Closed nikitazep closed 5 months ago

nikitazep commented 6 months ago

I found this code about sprites in /files/tasks.py, can you explain how the code works?

@task(name="produce_sprite_from_video", queue="long_tasks") def produce_sprite_from_video(friendly_token): """Produces a sprites file for a video, uses ffmpeg"""

try:
    media = Media.objects.get(friendly_token=friendly_token)
except BaseException:
    logger.info("failed to get media with friendly_token %s" % friendly_token)
    return False

with tempfile.TemporaryDirectory(dir=settings.TEMP_DIRECTORY) as tmpdirname:
    try:
        tmpdir_image_files = tmpdirname + "/img%03d.jpg"
        output_name = tmpdirname + "/sprites.jpg"
        cmd = "{0} -i {1} -f image2 -vf 'fps=1/10, scale=160:90' {2}&&files=$(ls {3}/img*.jpg | sort -t '-' -n -k 2 | tr '\n' ' ')&&convert $files -append {4}".format(
            settings.FFMPEG_COMMAND,
            media.media_file.path,
            tmpdir_image_files,
            tmpdirname,
            output_name,
        )
        subprocess.run(cmd, stdout=subprocess.PIPE, shell=True)
        if os.path.exists(output_name) and get_file_type(output_name) == "image":
            with open(output_name, "rb") as f:
                myfile = File(f)
                media.sprites.save(
                    content=myfile,
                    name=get_file_name(media.media_file.path) + "sprites.jpg",
                )
    except BaseException:
        pass
return True