feat: 暂停显示选集、亮度音量手势调节、播放进度续播
This commit is contained in:
85
docs/superpowers/plans/2026-05-27-player-enhancements.md
Normal file
85
docs/superpowers/plans/2026-05-27-player-enhancements.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Player Enhancements Implementation Plan
|
||||
|
||||
> **Goal:** Add pause-to-show-controls, brightness/volume gestures, and playback position resume to PlayerActivity.
|
||||
|
||||
**Architecture:** Touch gesture detection on playerView, ExoPlayer listener for pause state, PlayHistory entity extension for position, AudioManager for volume, Window attributes for brightness.
|
||||
|
||||
**Tech Stack:** Kotlin, Android, ExoPlayer Media3, Room, AudioManager
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add playbackPosition to PlayHistory entity and DAO
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/src/main/java/com/videoapp/tv/data/PlayHistory.kt`
|
||||
- Modify: `app/src/main/java/com/videoapp/tv/data/PlayHistoryDao.kt`
|
||||
|
||||
- [ ] **Step 1: Add playbackPosition field to PlayHistory entity**
|
||||
|
||||
Add `val playbackPosition: Long? = null` to the data class. Since the DB is `fallbackToDestructiveMigration()`, no migration needed.
|
||||
|
||||
- [ ] **Step 2: Add updatePosition method to PlayHistoryDao**
|
||||
|
||||
```kotlin
|
||||
@Query("UPDATE play_history SET playbackPosition = :position WHERE id = :id")
|
||||
suspend fun updatePosition(id: Long, position: Long)
|
||||
```
|
||||
|
||||
### Task 2: Save and resume playback position in PlayerActivity
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/src/main/java/com/videoapp/tv/PlayerActivity.kt`
|
||||
- Modify: `app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt`
|
||||
|
||||
- [ ] **Step 1: Add fields and read resume position**
|
||||
|
||||
Add `resumePosition: Long?` field, read from intent `"resume_position"`.
|
||||
|
||||
- [ ] **Step 2: Modify playWithExoPlayer to seek to saved position**
|
||||
|
||||
After `prepare()`, add a listener to seek to `resumePosition` when ready, then clear `resumePosition`.
|
||||
|
||||
- [ ] **Step 3: Add periodic position saving**
|
||||
|
||||
Add a `positionSaveHandler` and `positionSaveRunnable` that saves current position every 5 seconds.
|
||||
|
||||
- [ ] **Step 4: Save position on pause/destroy**
|
||||
|
||||
In `onPause` and `onDestroy`, save current playback position before releasing player.
|
||||
|
||||
- [ ] **Step 5: Pass playbackPosition from SearchFragment**
|
||||
|
||||
In `openPlayerFromHistory`, pass `playHistory.playbackPosition` as `"resume_position"`.
|
||||
|
||||
### Task 3: Pause shows controls
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/src/main/java/com/videoapp/tv/PlayerActivity.kt`
|
||||
|
||||
- [ ] **Step 1: Add ExoPlayer Listener for playWhenReady changes**
|
||||
|
||||
In `initExoPlayer`, add a `Player.Listener` that calls `showControls()` on pause and restarts auto-hide on play.
|
||||
|
||||
### Task 4: Brightness/Volume touch gestures
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/src/main/java/com/videoapp/tv/PlayerActivity.kt`
|
||||
- Modify: `app/src/main/res/layout/activity_player.xml`
|
||||
|
||||
- [ ] **Step 1: Replace click listener with touch listener on playerView**
|
||||
|
||||
Replace `OnClickListener` with `OnTouchListener`. Track `startY`, `isAdjusting`, `isBrightnessMode`, `startBrightness`, `startVolume`.
|
||||
|
||||
- [ ] **Step 2: Handle ACTION_DOWN / MOVE / UP**
|
||||
|
||||
- DOWN: record startY, check x < width/2 for brightness mode
|
||||
- MOVE: calculate delta, adjust brightness or volume, show indicator
|
||||
- UP: if delta < threshold (20px), treat as click → toggleControls
|
||||
|
||||
- [ ] **Step 3: Add floating indicator overlay TextView in layout**
|
||||
|
||||
Add a `brightness_volume_indicator` TextView to activity_player.xml, centered, initially GONE.
|
||||
|
||||
- [ ] **Step 4: Implement showIndicator method**
|
||||
|
||||
Show the indicator with current brightness/volume percentage for 1 second after adjustment stops.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Player Enhancements Design
|
||||
|
||||
## 1. Pause Shows Controls
|
||||
|
||||
- Add `Player.Listener` to ExoPlayer, monitor `onPlayWhenReadyChanged`
|
||||
- When `playWhenReady` becomes false: show control panel, cancel auto-hide timer
|
||||
- When `playWhenReady` becomes true: restart auto-hide timer
|
||||
- WebView playback: not supported (can't detect pause)
|
||||
|
||||
## 2. Brightness/Volume Gestures
|
||||
|
||||
- Replace click listener with `OnTouchListener` on playerView/playerWebView
|
||||
- `ACTION_DOWN`: record startY, determine left/right half of screen
|
||||
- Left half: brightness mode
|
||||
- Right half: volume mode
|
||||
- `ACTION_MOVE`: calculate deltaY, adjust brightness/volume proportionally
|
||||
- `ACTION_UP`: if delta < threshold, treat as click (toggle controls); reset state
|
||||
- Brightness: `window.attributes.screenBrightness` (activity-scoped, no permission)
|
||||
- Volume: `AudioManager.setStreamVolume(STREAM_MUSIC, ...)`
|
||||
- Show floating indicator (TextView overlay) during adjustment
|
||||
|
||||
## 3. Playback Position Resume
|
||||
|
||||
- Add `playbackPosition: Long?` to `PlayHistory` entity
|
||||
- Add `updatePosition(id, position)` to `PlayHistoryDao`
|
||||
- Save position every 5 seconds via handler, and on pause/destroy
|
||||
- On player entry: read position from history, seek to it after prepare
|
||||
- Pass `resume_position` via Intent from SearchFragment
|
||||
- ExoPlayer only (WebView excluded)
|
||||
Reference in New Issue
Block a user