new features
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
import uuid
|
||||
from os import path
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@@ -8,11 +10,14 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from cpv3.infrastructure.auth import get_current_user
|
||||
from cpv3.infrastructure.deps import get_storage
|
||||
from cpv3.infrastructure.storage.base import StorageService
|
||||
from cpv3.infrastructure.storage.utils import get_user_folder
|
||||
from cpv3.db.session import get_db
|
||||
from cpv3.modules.media.schemas import (
|
||||
ArtifactMediaFileCreate,
|
||||
ArtifactMediaFileRead,
|
||||
ArtifactMediaFileUpdate,
|
||||
FrameItem,
|
||||
FrameRangeResponse,
|
||||
MediaConverterParams,
|
||||
MediaFileCreate,
|
||||
MediaFileRead,
|
||||
@@ -20,7 +25,13 @@ from cpv3.modules.media.schemas import (
|
||||
MediaProbeSchema,
|
||||
MediaSilencerParams,
|
||||
)
|
||||
from cpv3.modules.media.service import convert_to_mp4, probe_media, remove_silence
|
||||
from cpv3.modules.media.service import (
|
||||
convert_to_mp4,
|
||||
get_frames_folder,
|
||||
probe_media,
|
||||
read_frames_metadata,
|
||||
remove_silence,
|
||||
)
|
||||
from cpv3.modules.media.repository import ArtifactRepository, MediaFileRepository
|
||||
from cpv3.modules.files.schemas import FileInfoResponse
|
||||
from cpv3.modules.users.models import User
|
||||
@@ -46,12 +57,13 @@ async def silence_remove(
|
||||
current_user: User = Depends(get_current_user),
|
||||
storage: StorageService = Depends(get_storage),
|
||||
) -> FileInfoResponse:
|
||||
_ = current_user
|
||||
user_folder = get_user_folder(current_user)
|
||||
resolved_folder = f"{user_folder}/{body.folder}" if body.folder else f"{user_folder}/output_files"
|
||||
|
||||
info = await remove_silence(
|
||||
storage,
|
||||
file_key=body.file_path,
|
||||
out_folder=body.folder,
|
||||
out_folder=resolved_folder,
|
||||
min_silence_duration_ms=body.min_silence_duration_ms,
|
||||
silence_threshold_db=body.silence_threshold_db,
|
||||
padding_ms=body.padding_ms,
|
||||
@@ -71,9 +83,10 @@ async def convert(
|
||||
current_user: User = Depends(get_current_user),
|
||||
storage: StorageService = Depends(get_storage),
|
||||
) -> FileInfoResponse:
|
||||
_ = current_user
|
||||
user_folder = get_user_folder(current_user)
|
||||
resolved_folder = f"{user_folder}/{body.folder}" if body.folder else f"{user_folder}/output_files"
|
||||
|
||||
info = await convert_to_mp4(storage, file_key=body.file_path, out_folder=body.folder)
|
||||
info = await convert_to_mp4(storage, file_key=body.file_path, out_folder=resolved_folder)
|
||||
return FileInfoResponse(
|
||||
file_path=info.file_path,
|
||||
file_url=info.file_url,
|
||||
@@ -82,6 +95,36 @@ async def convert(
|
||||
)
|
||||
|
||||
|
||||
@media_router.get("/frames/", response_model=FrameRangeResponse)
|
||||
async def get_frames(
|
||||
file_key: str = Query(..., description="S3 key of the source video"),
|
||||
start: float = Query(0.0, ge=0, description="Start time in seconds"),
|
||||
end: float = Query(..., gt=0, description="End time in seconds"),
|
||||
current_user: User = Depends(get_current_user),
|
||||
storage: StorageService = Depends(get_storage),
|
||||
) -> FrameRangeResponse:
|
||||
"""Return presigned URLs for extracted frames within a time range."""
|
||||
user_folder = get_user_folder(current_user)
|
||||
frames_folder = get_frames_folder(user_folder, file_key)
|
||||
|
||||
metadata = await read_frames_metadata(storage, frames_folder=frames_folder)
|
||||
if metadata is None:
|
||||
return FrameRangeResponse(interval=1.0, frames=[])
|
||||
|
||||
interval = metadata.interval
|
||||
first_index = max(1, math.floor(start / interval) + 1)
|
||||
last_index = min(metadata.frame_count, math.ceil(end / interval) + 1)
|
||||
|
||||
frames: list[FrameItem] = []
|
||||
for i in range(first_index, last_index + 1):
|
||||
key = path.join(frames_folder, f"{i:06d}.jpg")
|
||||
timestamp = (i - 1) * interval
|
||||
url = await storage.url(key)
|
||||
frames.append(FrameItem(timestamp=timestamp, url=url))
|
||||
|
||||
return FrameRangeResponse(interval=interval, frames=frames)
|
||||
|
||||
|
||||
@mediafiles_router.get("/mediafiles/", response_model=list[MediaFileRead])
|
||||
async def list_mediafiles(
|
||||
current_user: User = Depends(get_current_user),
|
||||
|
||||
Reference in New Issue
Block a user