def compile_timelapse(self, print_id):
    print = Print.objects.get(id=print_id)
    end_time = print.finished_at or print.cancelled_at

    if (end_time - print.started_at).total_seconds() < settings.TIMELAPSE_MINIMUM_SECONDS:
        print.delete()
        return

    to_dir = os.path.join(tempfile.gettempdir(), str(print.id))
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)

    print_pics = filter_pics_by_start_end(list_file_obj('raw/{}/'.format(print.printer.id), settings.PICS_CONTAINER), print.started_at, end_time)
    print_pics.sort()
    if print_pics:
        local_pics = download_files(print_pics, to_dir)
        last_pic = local_pics[-1]
        mp4_filename = '{}.mp4'.format(print.id)
        output_mp4 = os.path.join(to_dir, mp4_filename)
        subprocess.run('ffmpeg -y -r 30 -pattern_type glob -i {}/*.jpg -c:v libx264 -pix_fmt yuv420p {}'.format(last_pic.parent, output_mp4).split(' '), check=True)
        shutil.copyfile(last_pic, os.path.join(to_dir, '{}.jpg'.format(print.id)))

        with open(output_mp4, 'rb') as mp4_file:
            _, mp4_file_url = save_file_obj('private/{}'.format(mp4_filename), mp4_file, settings.TIMELAPSE_CONTAINER)
        with open(last_pic, 'rb') as poster_file:
            _, poster_file_url = save_file_obj('private/{}_poster.jpg'.format(print.id), poster_file, settings.TIMELAPSE_CONTAINER)

        print.video_url = mp4_file_url
        print.poster_url = poster_file_url
        print.save()

    # build tagged timelapse
    print_pics = filter_pics_by_start_end(list_file_obj('tagged/{}/'.format(print.printer.id), settings.PICS_CONTAINER), print.started_at, end_time)
    print_pics.sort()
    if print_pics:
        local_pics = download_files(print_pics, to_dir)
        mp4_filename = '{}_tagged.mp4'.format(print.id)
        output_mp4 = os.path.join(to_dir, mp4_filename)
        subprocess.run('ffmpeg -y -r 30 -pattern_type glob -i {}/*.jpg -c:v libx264 -pix_fmt yuv420p {}'.format(local_pics[0].parent, output_mp4).split(' '), check=True)
        with open(output_mp4, 'rb') as mp4_file:
            _, mp4_file_url = save_file_obj('private/{}'.format(mp4_filename), mp4_file, settings.TIMELAPSE_CONTAINER)

        preidction_json = []
        for print_pic_filename in print_pics:
            try:
                m = re.search('tagged/(\d+)/(\d+).jpg', print_pic_filename)
                p_json = json.loads(redis.printer_p_json_get(m[1], m[2]))
            except (json.decoder.JSONDecodeError, TypeError):    # In case there is no corresponding json, the file will be empty and JSONDecodeError will be thrown
                p_json = [{}]
            preidction_json += p_json
        preidction_json_io = io.BytesIO()
        preidction_json_io.write(json.dumps(preidction_json).encode('UTF-8'))
        preidction_json_io.seek(0)
        _, json_url = save_file_obj('private/{}_p.json'.format(print.id), preidction_json_io, settings.TIMELAPSE_CONTAINER)

        print.tagged_video_url = mp4_file_url
        print.prediction_json_url = json_url
        print.save()

    shutil.rmtree(to_dir, ignore_errors=True)
Exemple #2
0
def compile_timelapse(print_id):
    _print = Print.objects.select_related('printer').get(id=print_id)

    to_dir = os.path.join(tempfile.gettempdir(), str(_print.id))
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)

    ffmpeg_extra_options = orientation_to_ffmpeg_options(_print.printer.settings)

    print_pics = filter_pics_by_start_end(list_file_obj('raw/{}/'.format(_print.printer.id), settings.PICS_CONTAINER), _print.started_at, _print.ended_at())
    print_pics.sort()
    if print_pics:
        local_pics = download_files(print_pics, to_dir)
        mp4_filename = '{}.mp4'.format(_print.id)
        output_mp4 = os.path.join(to_dir, mp4_filename)
        cmd = 'ffmpeg -y -r 30 -pattern_type glob -i {}/*.jpg -c:v libx264 -pix_fmt yuv420p {} {}'.format(local_pics[-1].parent, ffmpeg_extra_options, output_mp4)
        subprocess.run(cmd.split(), check=True)

        with open(output_mp4, 'rb') as mp4_file:
            _, mp4_file_url = save_file_obj('private/{}'.format(mp4_filename), mp4_file, settings.TIMELAPSE_CONTAINER)

        last_pic = os.path.join(to_dir, 'ss.jpg')
        # https://superuser.com/questions/1448665/ffmpeg-how-to-get-last-frame-from-a-video
        subprocess.run('ffmpeg -y -i {} -sseof -1 -update 1 -vframes 1 -q:v 2 {}'.format(output_mp4, last_pic).split(' '), check=True)
        with open(last_pic, 'rb') as poster_file:
            _, poster_file_url = save_file_obj('private/{}_poster.jpg'.format(_print.id), poster_file, settings.TIMELAPSE_CONTAINER)

        _print.video_url = mp4_file_url
        _print.poster_url = poster_file_url
        _print.save()

    # build tagged timelapse
    print_pics = filter_pics_by_start_end(list_file_obj('tagged/{}/'.format(_print.printer.id), settings.PICS_CONTAINER), _print.started_at, _print.ended_at())
    print_pics.sort()
    if print_pics:
        local_pics = download_files(print_pics, to_dir)
        mp4_filename = '{}_tagged.mp4'.format(_print.id)
        output_mp4 = os.path.join(to_dir, mp4_filename)
        cmd = 'ffmpeg -y -r 30 -pattern_type glob -i {}/*.jpg -c:v libx264 -pix_fmt yuv420p {} {}'.format(local_pics[0].parent, ffmpeg_extra_options, output_mp4)
        subprocess.run(cmd.split(), check=True)
        with open(output_mp4, 'rb') as mp4_file:
            _, mp4_file_url = save_file_obj('private/{}'.format(mp4_filename), mp4_file, settings.TIMELAPSE_CONTAINER)

        preidction_json = []
        for print_pic_filename in print_pics:
            try:
                m = re.search('tagged/(\d+)/(\d+).jpg', print_pic_filename)
                p_json = json.loads(redis.printer_p_json_get(m[1], m[2]))
            except (json.decoder.JSONDecodeError, TypeError):    # In case there is no corresponding json, the file will be empty and JSONDecodeError will be thrown
                p_json = [{}]
            preidction_json += p_json
        preidction_json_io = io.BytesIO()
        preidction_json_io.write(json.dumps(preidction_json).encode('UTF-8'))
        preidction_json_io.seek(0)
        _, json_url = save_file_obj('private/{}_p.json'.format(_print.id), preidction_json_io, settings.TIMELAPSE_CONTAINER)

        _print.tagged_video_url = mp4_file_url
        _print.prediction_json_url = json_url
        _print.save()

    shutil.rmtree(to_dir, ignore_errors=True)
Exemple #3
0
def compile_timelapse(self, print_id):
    pprint = Print.objects.get(id=print_id)
    end_time = pprint.finished_at or pprint.cancelled_at

    to_dir = os.path.join(tempfile.gettempdir(), str(pprint.id))
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)

    print_pics = filter_pics_by_start_end(
        list_file_obj('raw/{}/'.format(pprint.printer.id),
                      settings.PICS_CONTAINER), pprint.started_at, end_time)
    print_pics.sort()
    if print_pics:
        local_pics = download_files(print_pics, to_dir)
        last_pic = local_pics[-1]
        mp4_filename = '{}.mp4'.format(pprint.id)
        output_mp4 = os.path.join(to_dir, mp4_filename)
        subprocess.run(
            'ffmpeg -y -pattern_type glob -i {}/*.jpg -c:v libx264 -vf fps=30 -pix_fmt yuv420p {}'
            .format(last_pic.parent, output_mp4).split(' '),
            check=True)
        shutil.copyfile(last_pic,
                        os.path.join(to_dir, '{}.jpg'.format(pprint.id)))

        with open(output_mp4, 'rb') as mp4_file:
            _, mp4_file_url = save_file_obj('private/{}'.format(mp4_filename),
                                            mp4_file,
                                            settings.TIMELAPSE_CONTAINER)
        with open(last_pic, 'rb') as poster_file:
            _, poster_file_url = save_file_obj(
                'private/{}_poster.jpg'.format(pprint.id), poster_file,
                settings.TIMELAPSE_CONTAINER)

        pprint.video_url = mp4_file_url
        pprint.poster_url = poster_file_url
        pprint.save()

    # build tagged timelapse
    print_pics = filter_pics_by_start_end(
        list_file_obj('tagged/{}/'.format(pprint.printer.id),
                      settings.PICS_CONTAINER), pprint.started_at, end_time)
    print_pics.sort()
    if print_pics:
        local_pics = download_files(print_pics, to_dir)
        mp4_filename = '{}_tagged.mp4'.format(pprint.id)
        output_mp4 = os.path.join(to_dir, mp4_filename)
        subprocess.run(
            'ffmpeg -y -pattern_type glob -i {}/*.jpg -c:v libx264 -vf fps=30 -pix_fmt yuv420p {}'
            .format(local_pics[0].parent, output_mp4).split(' '),
            check=True)
        with open(output_mp4, 'rb') as mp4_file:
            _, mp4_file_url = save_file_obj('private/{}'.format(mp4_filename),
                                            mp4_file,
                                            settings.TIMELAPSE_CONTAINER)

        json_files = [
            print_pic.replace('tagged/', 'p/').replace('.jpg', '.json')
            for print_pic in print_pics
        ]
        local_jsons = download_files(json_files, to_dir)
        preidction_json = []
        for p_json_file in local_jsons:
            with open(p_json_file, 'r') as f:
                try:
                    p_json = json.load(f)
                except json.decoder.JSONDecodeError:  # In case there is no corresponding json, the file will be empty and JSONDecodeError will be thrown
                    p_json = [{}]
                preidction_json += p_json
        preidction_json_io = io.BytesIO()
        preidction_json_io.write(json.dumps(preidction_json).encode('UTF-8'))
        preidction_json_io.seek(0)
        _, json_url = save_file_obj('private/{}_p.json'.format(pprint.id),
                                    preidction_json_io,
                                    settings.TIMELAPSE_CONTAINER)

        pprint.tagged_video_url = mp4_file_url
        pprint.prediction_json_url = json_url
        pprint.save()

    shutil.rmtree(to_dir, ignore_errors=True)