- Add FastAPI server for video metadata registration - PostgreSQL database models for videos, video_streams, audio_streams, subtitle_streams - Batch registration script for .probe.json files - RESTful API endpoints for CRUD operations - Search functionality by title, artist, codec, resolution
117 lines
3.6 KiB
Python
117 lines
3.6 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from sqlalchemy import (
|
|
Column,
|
|
String,
|
|
Integer,
|
|
BigInteger,
|
|
Float,
|
|
Text,
|
|
ForeignKey,
|
|
DateTime,
|
|
)
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import relationship
|
|
from app.database import Base
|
|
|
|
|
|
class Video(Base):
|
|
__tablename__ = "videos"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
file_path = Column(String(512), unique=True, nullable=False)
|
|
file_name = Column(String(255), nullable=False)
|
|
file_extension = Column(String(10))
|
|
file_size = Column(BigInteger)
|
|
format_name = Column(String(50))
|
|
format_long_name = Column(String(100))
|
|
duration = Column(Float)
|
|
bit_rate = Column(BigInteger)
|
|
nb_streams = Column(Integer)
|
|
start_time = Column(Float, default=0)
|
|
title = Column(String(255))
|
|
artist = Column(String(255))
|
|
description = Column(Text)
|
|
probed_at = Column(DateTime)
|
|
registered_at = Column(DateTime, default=datetime.utcnow)
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
video_streams = relationship(
|
|
"VideoStream", back_populates="video", cascade="all, delete-orphan"
|
|
)
|
|
audio_streams = relationship(
|
|
"AudioStream", back_populates="video", cascade="all, delete-orphan"
|
|
)
|
|
subtitle_streams = relationship(
|
|
"SubtitleStream", back_populates="video", cascade="all, delete-orphan"
|
|
)
|
|
|
|
|
|
class VideoStream(Base):
|
|
__tablename__ = "video_streams"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
video_id = Column(
|
|
UUID(as_uuid=True), ForeignKey("videos.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
stream_index = Column(Integer)
|
|
codec_name = Column(String(30))
|
|
codec_long_name = Column(String(100))
|
|
profile = Column(String(30))
|
|
level = Column(Integer)
|
|
width = Column(Integer)
|
|
height = Column(Integer)
|
|
coded_width = Column(Integer)
|
|
coded_height = Column(Integer)
|
|
aspect_ratio = Column(String(20))
|
|
pix_fmt = Column(String(30))
|
|
field_order = Column(String(20))
|
|
frame_rate = Column(String(20))
|
|
start_time = Column(Float)
|
|
duration = Column(Float)
|
|
bit_rate = Column(BigInteger)
|
|
nb_frames = Column(BigInteger)
|
|
color_range = Column(String(10))
|
|
color_space = Column(String(20))
|
|
has_b_frames = Column(Integer)
|
|
sample_aspect_ratio = Column(String(20))
|
|
|
|
video = relationship("Video", back_populates="video_streams")
|
|
|
|
|
|
class AudioStream(Base):
|
|
__tablename__ = "audio_streams"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
video_id = Column(
|
|
UUID(as_uuid=True), ForeignKey("videos.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
stream_index = Column(Integer)
|
|
codec_name = Column(String(30))
|
|
codec_long_name = Column(String(100))
|
|
profile = Column(String(30))
|
|
channels = Column(Integer)
|
|
channel_layout = Column(String(30))
|
|
sample_rate = Column(Integer)
|
|
sample_fmt = Column(String(20))
|
|
bit_rate = Column(BigInteger)
|
|
duration = Column(Float)
|
|
language = Column(String(10))
|
|
|
|
video = relationship("Video", back_populates="audio_streams")
|
|
|
|
|
|
class SubtitleStream(Base):
|
|
__tablename__ = "subtitle_streams"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
video_id = Column(
|
|
UUID(as_uuid=True), ForeignKey("videos.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
stream_index = Column(Integer)
|
|
codec_name = Column(String(30))
|
|
language = Column(String(10))
|
|
|
|
video = relationship("Video", back_populates="subtitle_streams")
|