Files
mediaplayer/sentence_api
2026-08-14 19:06:04 +08:00
..
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00
2026-08-14 19:06:04 +08:00

Sentence Boundary API

This service looks up pre-generated sentence boundaries by the SHA-256 hash of the exact video bytes. It does not analyze media during an API request.

Install

From the repository root:

python3 -m venv .venv-sentence-api
. .venv-sentence-api/bin/activate
python -m pip install -r sentence_api/requirements.txt

Generate The Index

Generate boundaries with the same silence detector used by the desktop player:

python -m sentence_api.generate_boundaries \
  "/path/to/lesson.mp4" \
  --index sentence_api/data/sentence_boundaries.json

The command calculates the SHA-256 hash, detects boundaries, converts seconds to milliseconds, infers each end_ms from the next sentence start, and writes the result atomically into the JSON index. The last sentence ends at the media duration.

For a large course library, run this command in an ingestion worker and store the same document in a database or object storage instead of committing the JSON file to the application image.

Run

SENTENCE_BOUNDARIES_FILE=sentence_api/data/sentence_boundaries.json \
python -m uvicorn sentence_api.main:app --host 0.0.0.0 --port 8000

The interactive API documentation is available at /docs.

Request

GET /api/v1/videos/{sha256}/sentence-boundaries

Example using the demo record in the checked-in index:

curl http://127.0.0.1:8000/api/v1/videos/468a4d064f6ec49942b45e25ab93c500d31870f978c4f28ff8b3b408852326e0/sentence-boundaries

The MP4 used during development is also indexed. Its hash is b6631d5cf48f37fed0ecc623563dd48b7ed660689b4d25d2ebac7fecab807ddc, and its generated index contains 244 boundaries.

The response is:

{
  "video_hash": "...",
  "duration_ms": 16000,
  "algorithm_version": "silence-rms-v1",
  "sentences": [
    {
      "index": 0,
      "start_ms": 0,
      "end_ms": 4230,
      "text": null
    }
  ]
}

Unknown hashes return 404. A hash must be a 64-character hexadecimal SHA-256 digest; malformed values return 422.

When testing from a physical Android phone, replace 127.0.0.1 with the computer's LAN IP address. 127.0.0.1 on the phone refers to the phone itself. For production, expose the API over HTTPS.

Android Request Flow

The mobile app should calculate the hash from the selected content:// URI in streaming chunks, request the endpoint, map the returned sentences to SentenceBoundary, and then call controller.loadItem. The hash must be calculated from the exact bytes of the same video served to the player. For HTTPS course videos, the course manifest can carry the hash and avoid hashing the entire remote file on every device.