| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- # Copyright (c) Meta Platforms, Inc. and affiliates.
- # All rights reserved.
- # This source code is licensed under the license found in the
- # LICENSE file in the root directory of this source tree.
- import os
- import shutil
- import subprocess
- from glob import glob
- from pathlib import Path
- from typing import Dict, Optional
- import imagesize
- from app_conf import GALLERY_PATH, POSTERS_PATH, POSTERS_PREFIX
- from data.data_types import Video
- from tqdm import tqdm
- def preload_data() -> Dict[str, Video]:
- """
- Preload data including gallery videos and their posters.
- """
- # Dictionaries for videos and datasets on the backend.
- # Note that since Python 3.7, dictionaries preserve their insert order, so
- # when looping over its `.values()`, elements inserted first also appear first.
- # https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6
- all_videos = {}
- video_path_pattern = os.path.join(GALLERY_PATH, "**/*.mp4")
- video_paths = glob(video_path_pattern, recursive=True)
- for p in tqdm(video_paths):
- video = get_video(p, GALLERY_PATH)
- all_videos[video.code] = video
- return all_videos
- def get_video(
- filepath: os.PathLike,
- absolute_path: Path,
- file_key: Optional[str] = None,
- generate_poster: bool = True,
- width: Optional[int] = None,
- height: Optional[int] = None,
- verbose: Optional[bool] = False,
- ) -> Video:
- """
- Get video object given
- """
- # Use absolute_path to include the parent directory in the video
- video_path = os.path.relpath(filepath, absolute_path.parent)
- poster_path = None
- if generate_poster:
- poster_id = os.path.splitext(os.path.basename(filepath))[0]
- poster_filename = f"{str(poster_id)}.jpg"
- poster_path = f"{POSTERS_PREFIX}/{poster_filename}"
- # Extract the first frame from video
- poster_output_path = os.path.join(POSTERS_PATH, poster_filename)
- ffmpeg = shutil.which("ffmpeg")
- subprocess.call(
- [
- ffmpeg,
- "-y",
- "-i",
- str(filepath),
- "-pix_fmt",
- "yuv420p",
- "-frames:v",
- "1",
- "-update",
- "1",
- "-strict",
- "unofficial",
- str(poster_output_path),
- ],
- stdout=None if verbose else subprocess.DEVNULL,
- stderr=None if verbose else subprocess.DEVNULL,
- )
- # Extract video width and height from poster. This is important to optimize
- # rendering previews in the mosaic video preview.
- width, height = imagesize.get(poster_output_path)
- return Video(
- code=video_path,
- path=video_path if file_key is None else file_key,
- poster_path=poster_path,
- width=width,
- height=height,
- )
|