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

93 lines
2.6 KiB
Markdown

# 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:
```bash
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:
```bash
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
```bash
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
```http
GET /api/v1/videos/{sha256}/sentence-boundaries
```
Example using the demo record in the checked-in index:
```bash
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:
```json
{
"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.