Skip to content

Commit

Permalink
Fix frames_to_timeseconds
Browse files Browse the repository at this point in the history
  • Loading branch information
GoldenAnpu committed Dec 18, 2024
1 parent 17883a8 commit 076e841
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 53 deletions.
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true,
"env": {
"PYTHONPATH": "${workspaceFolder}:${PYTHONPATH}"
}
}
]
}
27 changes: 27 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"python.defaultInterpreterPath": ".venv/bin/python",
"files.exclude": {
"**/__pycache__": true,
".venv": true
},
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"black-formatter.args": ["--line-length", "100"],
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
},
"isort.args": ["--profile", "black"],
"debug.inlineValues": "off",
"python.analysis.typeCheckingMode": "off",
"python.analysis.autoImportCompletions": false
}
14 changes: 4 additions & 10 deletions debug.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@ PYTHONUNBUFFERED=1

TASK_ID=16200

context.teamId=314
context.workspaceId=459
modal.state.slyProjectId=11162
modal.state.slyProjectId=11237
modal.state.slyProjectId=11106
context.teamId=567
context.workspaceId=1072
modal.state.slyProjectId=44098

modal.state.targetFps=4
modal.state.targetFps=25
modal.state.resultProjectName=""

DEBUG_APP_DIR="debug_data/sly-app"
DEBUG_TEMPORARY_APP_DIR="debug_data/sly-app"
LOG_LEVEL="debug"

SERVER_ADDRESS="put your value here"
API_TOKEN="put your value here"
AGENT_TOKEN="put your value here"
4 changes: 2 additions & 2 deletions src/debug_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

def load_envs_from_files():
app_dir = os.getcwd()
debug_env_path = os.path.join(app_dir, 'debug.env')
secret_debug_env_path = os.path.join(app_dir, 'secret_debug.env')
debug_env_path = os.path.join(app_dir, "debug.env")
secret_debug_env_path = "~/supervisely.env"

load_dotenv(debug_env_path)
load_dotenv(secret_debug_env_path, override=True)
36 changes: 22 additions & 14 deletions src/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,40 @@
from supervisely.app.fastapi import create
from supervisely.app.content import get_data_dir
from distutils.util import strtobool
from dotenv import load_dotenv

if sly.is_development():
load_dotenv("debug.env")
load_dotenv("~supervisely.env")

app_root_directory = os.getcwd()
sly.logger.info(f'App root directory: {app_root_directory!r}')
sly.logger.info(f"App root directory: {app_root_directory!r}")
sys.path.append(app_root_directory)

data_directory = get_data_dir()
temp_data_directory = os.getenv('DEBUG_TEMPORARY_APP_DIR', '/tmp/sly-app') # to be removed after task execution
sly.logger.info(f'App data directory: {data_directory!r} Temporary data directory: {temp_data_directory!r}')
temp_data_directory = os.getenv(
"DEBUG_TEMPORARY_APP_DIR", "/tmp/sly-app"
) # to be removed after task execution
sly.logger.info(
f"App data directory: {data_directory!r} Temporary data directory: {temp_data_directory!r}"
)

app = FastAPI()
sly_app = create()
app.mount('/sly', sly_app)
app.mount("/sly", sly_app)
api = sly.Api.from_env()

TASK_ID = int(os.environ['TASK_ID'])
TEAM_ID = int(os.environ['context.teamId'])
WORKSPACE_ID = int(os.environ['context.workspaceId'])
PROJECT_ID = int(os.environ['modal.state.slyProjectId'])
DATASET_ID = os.environ.get('modal.state.slyDatasetId', None)
TASK_ID = int(os.environ["TASK_ID"])
TEAM_ID = int(os.environ["context.teamId"])
WORKSPACE_ID = int(os.environ["context.workspaceId"])
PROJECT_ID = int(os.environ["modal.state.slyProjectId"])
DATASET_ID = os.environ.get("modal.state.slyDatasetId", None)
if DATASET_ID is not None:
DATASET_ID = int(DATASET_ID)
CHANGE_RESOLUTION = bool(strtobool(os.environ.get('modal.state.changeResolution', 'false')))
TARGET_HEIGHT = int(os.environ.get('modal.state.targetResolutionHeight', 1280))
TARGET_WIDTH = int(os.environ.get('modal.state.targetResolutionWidth', 720))
CHANGE_RESOLUTION = bool(strtobool(os.environ.get("modal.state.changeResolution", "false")))
TARGET_HEIGHT = int(os.environ.get("modal.state.targetResolutionHeight", 1280))
TARGET_WIDTH = int(os.environ.get("modal.state.targetResolutionWidth", 720))
target_resolution = (TARGET_WIDTH, TARGET_HEIGHT)

TARGET_FPS = float(os.environ['modal.state.targetFps'])
RES_PROJECT_NAME = os.getenv('modal.state.resultProjectName', None)
TARGET_FPS = float(os.environ["modal.state.targetFps"])
RES_PROJECT_NAME = os.getenv("modal.state.resultProjectName", None)
81 changes: 54 additions & 27 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,91 @@
import os
import sys

if '--DebugImportEnvsFromFiles' in sys.argv:
if "--DebugImportEnvsFromFiles" in sys.argv:
import debug_utils

debug_utils.load_envs_from_files()

import supervisely as sly
from supervisely.video_annotation.key_id_map import KeyIdMap
from supervisely.api.module_api import ApiField
from supervisely.api.video.video_api import VideoInfo

import globals as g
from functions import FpsVideoInfo, convert_video


@sly.timeit
def change_framerate(api: sly.Api, target_fps, result_project_name):

if g.DATASET_ID:
datasets = [api.dataset.get_info_by_id(g.DATASET_ID)]
sly.logger.info(f'Processing single dataset ID {g.DATASET_ID} in project ID {g.PROJECT_ID}')
sly.logger.info(f"Processing single dataset ID {g.DATASET_ID} in project ID {g.PROJECT_ID}")
else:
datasets = api.dataset.get_list(g.PROJECT_ID)
sly.logger.info(f'Processing all datasets in project ID {g.PROJECT_ID}')
sly.logger.info(f"Processing all datasets in project ID {g.PROJECT_ID}")

if not result_project_name:
project_info = api.project.get_info_by_id(g.PROJECT_ID)
result_project_name = f'{project_info.name} {target_fps:.6g} FPS'
result_project_name = f"{project_info.name} {target_fps:.6g} FPS"

src_dir, res_dir = (os.path.join(g.temp_data_directory, n) for n in ('source', 'result'))
src_dir, res_dir = (os.path.join(g.temp_data_directory, n) for n in ("source", "result"))
for d in (src_dir, res_dir):
sly.fs.mkdir(d, remove_content_if_exists=True)

meta_json = api.project.get_meta(g.PROJECT_ID)
meta = sly.ProjectMeta.from_json(meta_json)
res_project = api.project.create(g.WORKSPACE_ID, result_project_name,
type=sly.ProjectType.VIDEOS, change_name_if_conflict=True)
res_project = api.project.create(
g.WORKSPACE_ID,
result_project_name,
type=sly.ProjectType.VIDEOS,
change_name_if_conflict=True,
)
api.project.update_meta(res_project.id, meta_json)
dummy_map = KeyIdMap()

progress = sly.Progress('Video recoding', sum(ds.items_count for ds in datasets))
progress = sly.Progress("Video recoding", sum(ds.items_count for ds in datasets))

for dataset in datasets:
res_dataset = api.dataset.create(res_project.id, dataset.name, change_name_if_conflict=True)

videos = api.video.get_list(dataset.id)
for video_info in videos:

if video_info.frames_to_timecodes is None and video_info.link:
video_info = api.video.get_list(
dataset.id,
filters=[
{
ApiField.FIELD: ApiField.ID,
ApiField.OPERATOR: "=",
ApiField.VALUE: video_info.id,
}
],
force_metadata_for_links=True,
)[0]
if video_info.frames_to_timecodes is None:
sly.logger.warning(
f"Video ID {video_info.id}; NAME '{video_info.name}' has no frames to timecodes info. Skipping."
)
continue
ann_info = api.video.annotation.download(video_info.id)
ann = sly.VideoAnnotation.from_json(ann_info, meta, dummy_map)
if ann.frames.figures or ann.objects:
sly.logger.warn(f'Annotation data from video {video_info.name!r} will be discarded.')
sly.logger.warning(
f"Annotation data from video {video_info.name!r} will be discarded."
)

fps_info = FpsVideoInfo(video_info.frames_to_timecodes)
expected_frame_cnt = fps_info.expect_frames_cnt(target_fps)
sly.logger.info(f'Dataset {dataset.name!r} Video {video_info.name!r} Source: {fps_info.fps:.5} FPS, '
f'{fps_info.frames_cnt} frames. Expect: {expected_frame_cnt} frames')
sly.logger.info(
f"Dataset {dataset.name!r} Video {video_info.name!r} Source: {fps_info.fps:.5} FPS, "
f"{fps_info.frames_cnt} frames. Expect: {expected_frame_cnt} frames"
)
if expected_frame_cnt < 2:
raise ValueError('Low FPS value', {'dataset': dataset.id, 'video': video_info.id})
raise ValueError("Low FPS value", {"dataset": dataset.id, "video": video_info.id})

if fps_info.fps_equals(target_fps):
sly.logger.debug(f'Preserving existing frame rate for video {video_info.name!r}')
sly.logger.debug(f"Preserving existing frame rate for video {video_info.name!r}")
api.video.upload_id(res_dataset.id, video_info.name, video_info.id)
# api.video.upload_hash(res_dataset.id, video_info.name, video_info.hash)
else:
Expand All @@ -68,25 +95,25 @@ def change_framerate(api: sly.Api, target_fps, result_project_name):
in_fpath, out_fpath = [os.path.join(d, video_info.name) for d in curr_dirs]

api.video.download_path(video_info.id, in_fpath)
sly.logger.debug(f'Downloaded video to {in_fpath!r}')
sly.logger.debug(f"Downloaded video to {in_fpath!r}")
convert_video(target_fps, in_fpath, out_fpath, g.target_resolution)
sly.logger.debug(f'Converted video to {out_fpath!r}')
sly.logger.debug(f"Converted video to {out_fpath!r}")
api.video.upload_paths(res_dataset.id, (video_info.name,), (out_fpath,))
sly.logger.debug('Uploaded video')
sly.logger.debug("Uploaded video")
progress.iter_done_report()

sly.logger.debug('Finished change_framerate')
sly.logger.debug("Finished change_framerate")


if __name__ == '__main__':
if __name__ == "__main__":
sly.logger.info(
'Script arguments',
"Script arguments",
extra={
'context.teamId': g.TEAM_ID,
'context.workspaceId': g.WORKSPACE_ID,
'modal.state.slyProjectId': g.PROJECT_ID,
'modal.state.targetFps': g.TARGET_FPS,
'modal.state.resultProjectName': g.RES_PROJECT_NAME
"context.teamId": g.TEAM_ID,
"context.workspaceId": g.WORKSPACE_ID,
"modal.state.slyProjectId": g.PROJECT_ID,
"modal.state.targetFps": g.TARGET_FPS,
"modal.state.resultProjectName": g.RES_PROJECT_NAME,
},
)

Expand All @@ -95,4 +122,4 @@ def change_framerate(api: sly.Api, target_fps, result_project_name):
try:
sly.app.fastapi.shutdown()
except KeyboardInterrupt:
sly.logger.info('Application shutdown successfully')
sly.logger.info("Application shutdown successfully")

0 comments on commit 076e841

Please sign in to comment.