Files
youtube-app/backend/routes/videos.py
2026-04-05 15:38:01 +02:00

91 lines
3.2 KiB
Python

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
from services.stream_service import 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")