import threading from pathlib import Path from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import FileResponse, StreamingResponse from sqlalchemy.orm import Session from database import get_db from schemas import VideoCreate, VideoResponse from services import video_service from services.download_service import download_video, stream_video_live router = APIRouter(prefix="/videos", tags=["videos"]) @router.post("", response_model=list[VideoResponse]) def create_videos(videos_data: list[VideoCreate], db: Session = Depends(get_db)): created_ids = [] for video_data in reversed(videos_data): video_id_match = video_data.youtube_url.split("v=")[-1].split("&")[0] video_service.delete_by_youtube_id(db, video_id_match) video = video_service.create_video(db, video_data) created_ids.append(video.id) videos = [video_service.get_video(db, vid) for vid in created_ids] return [VideoResponse.from_model(v) for v in videos if v] @router.get("", response_model=list[VideoResponse]) def get_all_videos(db: Session = Depends(get_db)): videos = video_service.get_all_videos(db) return [VideoResponse.from_model(v) for v in videos] @router.get("/downloaded", response_model=list[VideoResponse]) def get_downloaded_videos(db: Session = Depends(get_db)): videos = video_service.get_downloaded_videos(db) return [VideoResponse.from_model(v) for v in videos] @router.post("/{video_id}/download") def trigger_download(video_id: int, db: Session = Depends(get_db)): video = video_service.get_video(db, video_id) if not video: raise HTTPException(status_code=404, detail="Video nicht gefunden") if video.file_path: return {"status": "already_downloaded"} thread = threading.Thread(target=download_video, args=(video.id, video.youtube_url)) thread.start() return {"status": "download_started"} @router.get("/{video_id}/stream") def stream_video(video_id: int, db: Session = Depends(get_db)): video = video_service.get_video(db, video_id) if not video: raise HTTPException(status_code=404, detail="Video nicht gefunden") if not video.file_path: return StreamingResponse( stream_video_live(video.youtube_url), media_type="video/mp4", ) path = Path(video.file_path) if not path.exists(): raise HTTPException(status_code=404, detail="Videodatei nicht gefunden") def iter_file(): with open(path, "rb") as f: while chunk := f.read(1024 * 1024): yield chunk return StreamingResponse(iter_file(), media_type="video/mp4") @router.get("/{video_id}/file") def download_file(video_id: int, db: Session = Depends(get_db)): video = video_service.get_video(db, video_id) if not video: raise HTTPException(status_code=404, detail="Video nicht gefunden") if not video.file_path: raise HTTPException(status_code=404, detail="Video noch nicht heruntergeladen") path = Path(video.file_path) if not path.exists(): raise HTTPException(status_code=404, detail="Videodatei nicht gefunden") return FileResponse(path, media_type="video/mp4", filename=f"{video.title}.mp4")