Files
momentry_studio/docs/core-api-fix-video-range.md
Momentry Studio 5951aca086 feat: frame-based positioning and mark system foundation
Core Changes:
- Fix SearchView to use start_frame/end_frame directly (no time*fps conversion)
- Add hard_delete support to delete_trace API
- VideoPlayer: Main timeline + Mark system foundation
- Proxy: Add local routes for auth, media, identity-matches, cluster-results
- Add .gitignore to exclude build artifacts and dependencies

Design Documents:
- Multi-track Mark system design (.opencode/plans/)
- Video editing positioning standards research

Files Modified:
- src/views/SearchView.vue: Frame positioning, ensureMinDuration (240 frames)
- src/views/PeopleView.vue: batchDeleteGroups with hard_delete
- src/api/index.ts: delete_trace with hard_delete body
- src/components/VideoPlayer.vue: Timeline + Mark UI
- src-tauri/src/proxy.rs: New local routes
- AGENTS.md: Update documentation
2026-07-24 20:19:47 +08:00

186 lines
4.9 KiB
Markdown

# Core API Fix Request: Video Range Requests Support
## Issue
Video player in Studio cannot seek (跳轉) because Core API video endpoint does not support HTTP Range requests.
## Current Behavior
```bash
$ curl -I "http://localhost:3002/api/v1/file/{uuid}/video?start_time=0&end_time=5"
HTTP/1.1 200 OK
content-type: video/mp4
content-length: 1918410
# Missing: Accept-Ranges header
# Missing: 206 Partial Content support
```
## Expected Behavior
```bash
$ curl -I "http://localhost:3002/api/v1/file/{uuid}/video" -H "Range: bytes=0-1000"
HTTP/1.1 206 Partial Content
content-type: video/mp4
content-range: bytes 0-1000/1918410
accept-ranges: bytes
content-length: 1001
```
## Why This Matters
1. **Browser seeking requires Range support** - HTML5 `<video>` element uses Range requests to seek to different timestamps
2. **Current workaround is inefficient** - Users must download entire video or use `start_time` param (re-downloads video)
3. **High bitrate videos suffer most** - 4K/10Mbps videos cannot be quickly navigated
## Implementation Requirements
### 1. Add `Accept-Ranges: bytes` header to video endpoint
```
GET /api/v1/file/{uuid}/video
Response Headers:
Accept-Ranges: bytes
```
### 2. Handle Range requests with 206 Partial Content
```rust
// Pseudo-code for Rust implementation
if let Some(range_header) = request.headers().get("Range") {
let (start, end) = parse_range(range_header)?;
let file_chunk = read_file_range(file_path, start, end)?;
Response::builder()
.status(206)
.header("Content-Range", format!("bytes {}-{}/{}", start, end, file_size))
.header("Accept-Ranges", "bytes")
.header("Content-Length", end - start + 1)
.body(file_chunk)
} else {
// Full file response
Response::builder()
.status(200)
.header("Accept-Ranges", "bytes")
.body(full_file)
}
```
### 3. Support multiple Range formats
- `Range: bytes=0-999` (first 1000 bytes)
- `Range: bytes=1000-` (from byte 1000 to end)
- `Range: bytes=-500` (last 500 bytes)
## Affected Files (Core API)
- `src/api/files.rs` - Video streaming endpoint
- Possibly `src/api/video.rs` if exists
## Testing
```bash
# Test 1: Initial request should include Accept-Ranges
curl -I "http://localhost:3002/api/v1/file/{uuid}/video"
# Expect: Accept-Ranges: bytes
# Test 2: Range request should return 206
curl -I "http://localhost:3002/api/v1/file/{uuid}/video" -H "Range: bytes=0-1000"
# Expect: HTTP/1.1 206 Partial Content
# Expect: Content-Range: bytes 0-1000/{total}
# Test 3: Browser seeking should work
# Open Studio, play video, click on timeline
# Video should seek without re-downloading
```
## Priority
**High** - Critical for user experience when navigating long videos
## Related Studio Files
- `src/components/VideoPlayer.vue` - Uses `<video>` element with native controls
- `src-tauri/src/proxy.rs` - Already streams video, will pass through Range headers
## Notes
- Studio proxy already supports streaming (lines 325-367 in proxy.rs)
- Just need Core API to handle Range requests properly
- This is standard HTTP behavior for video streaming
---
## Additional Request: Adaptive Bitrate / Resolution Selection
### Problem
High bitrate videos (4K, 10+ Mbps) cause playback lag in browser due to software decoding limitations.
### Solution Options
#### Option A: Resolution Parameter
```bash
GET /api/v1/file/{uuid}/video?start_time=0&end_time=60&resolution=720p
GET /api/v1/file/{uuid}/video?start_time=0&end_time=60&resolution=480p
```
**Implementation:**
- Use FFmpeg to transcode on-the-fly or pre-generate proxy versions
- Store proxy videos at lower bitrates (720p @ 2Mbps, 480p @ 1Mbps)
#### Option B: Quality Parameter (1-100)
```bash
GET /api/v1/file/{uuid}//video?start_time=0&end_time=60&quality=50
```
#### Option C: Max Bitrate Parameter
```bash
GET /api/v1/file/{uuid}/video?start_time=0&end_time=60&max_bitrate=2000
```
### Recommended Approach
**Pre-generate proxy videos during processing:**
```rust
// During file processing, generate multiple versions:
// - Original: {uuid}_original.mp4 (preserve original quality)
// - 720p: {uuid}_720p.mp4 (2 Mbps)
// - 480p: {uuid}_480p.mp4 (1 Mbps)
```
**Storage Impact:**
- Original 100MB video → ~105MB total (5% overhead for proxies)
**API Changes:**
```rust
pub fn get_video_stream(
file_uuid: String,
start_time: f64,
end_time: f64,
resolution: Option<String>, // "original" | "720p" | "480p"
) -> Result<VideoStream, Error>
```
### Frontend Integration
Studio VideoPlayer can add quality selector:
```vue
<select v-model="selectedResolution">
<option value="original">Original (1080p)</option>
<option value="720p">HD (720p)</option>
<option value="480p">SD (480p)</option>
</select>
```
### Benefits
1. **Eliminates lag** on high bitrate videos
2. **Faster loading** with smaller file sizes
3. **Bandwidth savings** for remote access
4. **Better UX** - smooth playback on all devices