Skip to content

Commit

Permalink
[cli] add a command to generate tiles and update file previews metada…
Browse files Browse the repository at this point in the history
…tas in the same time
  • Loading branch information
EvanBldy committed Sep 19, 2023
1 parent e5b5f5e commit 1c06bf2
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 52 deletions.
124 changes: 106 additions & 18 deletions zou/app/services/preview_files_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,20 +650,18 @@ def generate_tiles_for_movie_previews():
path = extract_tile_from_preview_file(preview_file.serialize())
file_store.add_picture("tiles", str(preview_file.id), path)
print(
f"Tile generated preview file for {preview_file.id}",
f"Tile generated for preview file {preview_file.id}",
)
except Exception as e:
print(
"Failed to generate tile for preview file %s: %s",
str(preview_file.id),
e,
f"Failed to generate tile for preview file {preview_file.id}: {e}"
)
return preview_files


def reset_movie_file_metadata():
def reset_movie_files_metadata():
"""
Reset preview file size information of open projects.
Reset preview files size informations of open projects.
"""
preview_files = (
PreviewFile.query.join(Task)
Expand All @@ -683,9 +681,8 @@ def reset_movie_file_metadata():
str(preview_file.id),
"mp4",
)
size = movie.get_movie_size(preview_file_path)
file_size = os.path.getsize(preview_file_path)
width, height = size
width, height = movie.get_movie_size(preview_file_path)
update_preview_file_raw(
preview_file,
{
Expand All @@ -695,19 +692,17 @@ def reset_movie_file_metadata():
},
)
print(
f"Size information stored for {preview_file.id}",
f"Size information stored preview file {preview_file.id}",
)
except Exception as e:
print(
"Failed to store information for preview file %s: %s",
str(preview_file.id),
e,
f"Failed to store information for preview file {preview_file.id}: {e}"
)


def reset_picture_file_metadata():
def reset_picture_files_metadata():
"""
Reset preview file size information of open projects.
Reset preview files size informations of open projects.
"""
preview_files = (
PreviewFile.query.join(Task)
Expand Down Expand Up @@ -738,11 +733,104 @@ def reset_picture_file_metadata():
},
)
print(
f"Size information stored for {preview_file.id}",
f"Size information stored for preview file {preview_file.id}",
)
except Exception as e:
print(
"Failed to store information for preview file %s: %s",
str(preview_file.id),
e,
f"Failed to store information for preview file {preview_file.id}: {e}"
)


def generate_tiles_and_reset_preview_files_metadata():
"""
Generate tiles for all movie previews and reset previews file size
informations of open projects.
"""
preview_files = (
PreviewFile.query.join(Task)
.join(Project)
.join(ProjectStatus)
.filter(ProjectStatus.name.in_(("Active", "open", "Open")))
.filter(PreviewFile.status.not_in(("broken", "processing")))
.filter(PreviewFile.extension.in_(("mp4", "png")))
)
preview_file_already_in_cache = False
for preview_file in preview_files:
preview_file_id = str(preview_file.id)
prefix = "previews" if preview_file.extension == "mp4" else "original"
if config.FS_BACKEND != "local":
preview_file_already_in_cache = os.path.isfile(
os.path.join(
config.TMP_DIR,
"cache-%s-%s.%s"
% (prefix, preview_file_id, preview_file.extension),
)
)
try:
try:
preview_file_path = fs.get_file_path_and_file(
config,
file_store.get_local_movie_path
if preview_file.extension == "mp4"
else file_store.get_local_picture_path,
file_store.open_movie
if preview_file.extension == "mp4"
else file_store.open_picture,
prefix,
preview_file_id,
preview_file.extension,
)
except Exception as e:
print(f"Failed to get preview file {preview_file_id}: {e}")
continue
try:
if preview_file.extension == "mp4":
project = get_project_from_preview_file(preview_file_id)
fps = get_preview_file_fps(project)
extracted_tile_path = movie.generate_tile(
preview_file_path, fps
)
file_store.add_picture(
"tiles", preview_file_id, extracted_tile_path
)
print(
f"Tile generated for preview file {preview_file_id}",
)
except Exception as e:
print(
f"Failed to generate tile for preview file {preview_file_id}: {e}"
)
try:
if preview_file.extension == "mp4":
width, height = movie.get_movie_size(preview_file_path)
else:
width, height = thumbnail_utils.get_dimensions(
preview_file_path
)
file_size = os.path.getsize(preview_file_path)
update_preview_file_raw(
preview_file,
{
"width": width,
"height": height,
"file_size": file_size,
},
)
print(
f"Size information stored for preview file {preview_file_id}",
)
except Exception as e:
print(
f"Failed to store information for preview file {preview_file_id}: {e}",
)
finally:
if (
config.FS_BACKEND != "local"
and not preview_file_already_in_cache
):
try:
os.remove(preview_file_path)
except:
pass

return preview_files
13 changes: 9 additions & 4 deletions zou/app/utils/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,11 +631,16 @@ def generate_tiles():
preview_files_service.generate_tiles_for_movie_previews()


def reset_movie_file_metadata():
def reset_movie_files_metadata():
with app.app_context():
preview_files_service.reset_movie_file_metadata()
preview_files_service.reset_movie_files_metadata()


def reset_picture_file_metadata():
def reset_picture_files_metadata():
with app.app_context():
preview_files_service.reset_picture_file_metadata()
preview_files_service.reset_picture_files_metadata()


def generate_tiles_and_reset_preview_files_metadata():
with app.app_context():
preview_files_service.generate_tiles_and_reset_preview_files_metadata()
17 changes: 13 additions & 4 deletions zou/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,19 +469,28 @@ def generate_tiles():


@cli.command()
def reset_movie_file_metadata():
def reset_movie_files_metadata():
"""
Store height and width metadata for all movie previews in the database.
"""
commands.reset_movie_file_metadata()
commands.reset_movie_files_metadata()


@cli.command()
def reset_picture_file_metadata():
def reset_picture_files_metadata():
"""
Store height and width metadata for all picture previews in the database.
"""
commands.reset_picture_file_metadata()
commands.reset_picture_files_metadata()


@cli.command()
def generate_tiles_and_reset_preview_files_metadata():
"""
Generate tiles and store height and width metadata for all pictures/movies
previews in the database.
"""
commands.generate_tiles_and_reset_preview_files_metadata()


if __name__ == "__main__":
Expand Down
27 changes: 1 addition & 26 deletions zou/utils/movie.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,30 +94,6 @@ def extract_frame_from_movie(movie_path, frame_number, movie_fps):
return file_target_path


def get_all_frames(movie_path):
"""
Generate thumbnails to represent the movie given at movie path. It
takes a picture at each frame of the movie.
"""
folder_path = os.path.join(os.getcwd(), "movie_frames")
os.makedirs(folder_path, exist_ok=True)
file_source_name = os.path.basename(movie_path)
file_target_name = f"{file_source_name[:-4]}_%d.png"
file_target_path = os.path.join(folder_path, file_target_name)

try:
(
ffmpeg.input(movie_path)
.output(file_target_path, vsync=0)
.run(quiet=True)
)
except ffmpeg._run.Error as e:
print(f"Error generating thumbnails: {e}")
raise e

return folder_path


def generate_tile(movie_path, movie_fps):
"""
Generates a tile from a movie.
Expand All @@ -126,7 +102,6 @@ def generate_tile(movie_path, movie_fps):
file_source_name = os.path.basename(movie_path)
file_target_name = f"{file_source_name[:-4]}_tile.png"
file_target_path = os.path.join(folder_path, file_target_name)

probe = ffmpeg.probe(movie_path)
duration_in_seconds = float(probe["streams"][0]["duration"])
float_movie_fps = float(movie_fps)
Expand All @@ -139,7 +114,7 @@ def generate_tile(movie_path, movie_fps):
try:
ffmpeg.input(movie_path).output(
file_target_path, vf=f"scale={width}:{height},tile=8x{rows}"
).run(quiet=True)
).overwrite_output().run(quiet=True)
except ffmpeg._run.Error as e:
log_ffmpeg_error(e, "An error occured while generating the tile.")
raise e
Expand Down

0 comments on commit 1c06bf2

Please sign in to comment.