Skip to content

SaumilP/kotlin-vod-backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kot-video-api 🎬📡

📖 Overview

kot-video-api is a Kotlin + Spring Boot service that streams video files over HTTP with support for byte-range (RFC 7233-style) requests. This enables media players to seek efficiently by requesting only the required portions of a file.

The default branch (master) includes:

  • Video streaming via GET /videos/start (HTTP Range + conditional request support)
  • Playback tracking (sessions + event ingestion) backed by Postgres + Flyway

The playback tracking work was originally developed on feature/add-playback-sessions-api and has since been merged into master.


✨ Features

Streaming (master)

  • HTTP Range Requests: supports Range: bytes=... for partial content responses.
  • Multi-range Responses: supports multiple requested ranges (multipart/byteranges).
  • Conditional Requests:
    • If-None-Match (ETag-based)
    • If-Modified-Since
    • If-Match
    • If-Unmodified-Since
  • ETag + caching headers: sets ETag, Last-Modified, Expires, Accept-Ranges.
  • Rate limiting (server-side): streams through a Guava RateLimiter (currently configured to ~5 Mbps).

Playback Tracking (master)

  • Playback sessions API: POST /playback/sessions → returns session_id (authenticated).
  • Event ingestion API: POST /playback/events supports batched ingestion with validation and dedupe.
  • Persistence: Postgres tables for sessions/events/idempotency + Flyway migrations.
  • Integration tests: Testcontainers-based Postgres tests.

See: docs/PLAYBACK_TRACKING.md


✅ Requirements

For master

  • Java 21 (Gradle toolchain)
  • Docker (required for Testcontainers integration tests)
  • Postgres (required to run the app with playback tracking enabled; see configuration below)

🚀 Installation

1) Clone

git clone https://github.com/SaumilP/kot-video-api.git
cd kot-video-api

2) Configure dependencies

For local dev you’ll typically want a running Postgres instance, or you can set spring.flyway.enabled=false and skip playback endpoints.

3) Run the app

Using the Gradle wrapper:

./gradlew bootRun

By default the server runs on:

  • server.port=8082

🔧 Configuration

Configuration lives in:

  • src/main/resources/application.properties

video.home

video.home controls the directory where video files are served from:

video.home=/path/to/your/videos/

Override examples:

  • By editing src/main/resources/application.properties
  • Or via environment variables (Spring Boot relaxed binding), e.g.:
    • VIDEO_HOME=/path/to/videos

Note: the streaming endpoint expects a file name passed via query param, and constructs the full path as video.home + fileName.

Database (Postgres)

The app expects a Postgres database (for playback tracking tables + Flyway migrations). Defaults:

spring.datasource.url=jdbc:postgresql://localhost:5432/kot_video_api
spring.datasource.username=kot_video_api
spring.datasource.password=kot_video_api

Recommended overrides (env vars):

  • DB_URL
  • DB_USER
  • DB_PASSWORD

Flyway

spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration

Auth (basic)

Session creation is protected via HTTP Basic auth. Defaults:

spring.security.user.name=dev
spring.security.user.password=dev

Override (env vars):

  • APP_USER
  • APP_PASSWORD

🛠️ Usage

Streaming endpoint

GET /videos/start?fl=<filename>

Streams a file relative to video.home.

Example (full file):

curl -v "http://localhost:8082/videos/start?fl=myvideo.mp4"

Example (range request for seeking):

curl -v \
  -H "Range: bytes=0-999999" \
  "http://localhost:8082/videos/start?fl=myvideo.mp4" \
  --output part.bin

Example (player-style request):

curl -v \
  -H "Accept: video/mp4" \
  -H "Range: bytes=2000000-" \
  "http://localhost:8082/videos/start?fl=myvideo.mp4" \
  --output tail.bin

Response behaviors

  • If the file does not exist: 404
  • If the Range header is invalid: 416 with Content-Range: bytes */<length>
  • For a single satisfiable range: 206 Partial Content
  • For multiple ranges: 206 and Content-Type: multipart/byteranges; boundary=...

Playback tracking endpoints

See docs/PLAYBACK_TRACKING.md for full contracts.


📦 Technologies

  • Kotlin (JVM)
  • Spring Boot (Web, Validation, JDBC, Security)
  • Postgres + Flyway
  • Gradle (Kotlin DSL)
  • Guava (RateLimiter)
  • JUnit + Testcontainers

🗂️ Repository Structure

Detailed structure docs:

  • docs/REPOSITORY_STRUCTURE.md
  • docs/ARCHITECTURE.md
  • docs/PLAYBACK_TRACKING.md

Quick view:

  • build.gradle.kts — Gradle build (Spring Boot + Kotlin + DB deps)
  • src/main/kotlin/org/sandcastle/apps/KotVideoApiApplication.kt — Spring Boot entrypoint + /videos controller
  • src/main/kotlin/org/sandcastle/apps/MultipartFileSender.kt — main streaming/range logic
  • src/main/kotlin/org/sandcastle/apps/Range.kt — byte-range parsing + copy helpers + rate limiting
  • src/main/kotlin/org/sandcastle/apps/HttpUtils.kt — basic header matching helpers
  • src/main/kotlin/org/sandcastle/apps/playback/** — playback session + events ingestion
  • src/main/resources/db/migration/** — Flyway migrations

🔗 Flow Chart

See architecture diagrams:

  • docs/ARCHITECTURE.md

🤝 Contributing

  1. Fork the repo
  2. Create a feature branch: git checkout -b feature/my-change
  3. Run tests: ./gradlew test
  4. Open a PR

Guidelines:

  • Keep changes focused and well-tested.
  • Prefer small, reviewable PRs.

📄 Documentation

  • docs/ARCHITECTURE.md — diagrams + component overview
  • docs/REPOSITORY_STRUCTURE.md — full repo tree with explanations
  • docs/PLAYBACK_TRACKING.md — playback session/events API + schema details

❤️ Acknowledgements

  • The streaming implementation uses common HTTP range-serving patterns adapted for Kotlin/Spring Boot.
  • Guava RateLimiter is used to throttle streaming throughput.

📝 Changelog

This changelog is derived from git history.

  • 2024-04-14d4d1a32 — “Functional api”
    Baseline video streaming API.

  • 2026-03-02e5d3143 — “Feature 🏗️ : Add playback APIs”
    Adds playback tracking APIs + Postgres/Flyway/Testcontainers + build upgrades.

  • 2026-03-027f61299 — “Merge pull request #18 …”
    Merges the playback tracking branch into master.

Contributors

Languages