[New Feature] Support SAM 2.1 (#59)
* support sam 2.1 * refine config path and ckpt path * update README
This commit is contained in:
92
demo/backend/server/data/loader.py
Normal file
92
demo/backend/server/data/loader.py
Normal file
@@ -0,0 +1,92 @@
|
||||
# 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,
|
||||
)
|
Reference in New Issue
Block a user