Refactor video player and camera angle switching
- Removed inline JSON data for video clips; replaced with API endpoint to fetch video data. - Simplified camera angle switching UI with a 3-column button grid around a Model Y graphic. - Updated camera view mapping to use 'back' instead of 'rear'. - Enhanced noise canvas handling during video loading. - Streamlined clip playback logic and added auto-play for next clips in the same camera. - Improved search and sorting functionality by removing unnecessary elements. - Updated HTML structure for better accessibility and user experience.
This commit is contained in:
1 parent
06dc4f5f51
commit
d12d5e5414
5 files changed
+508
-805
No files matched your search
+49
-11
@@ -46,11 +46,18 @@ CAMERA_VIEW_MAPPING = {
|
||||
'front': 'Front',
|
||||
'left_repeater': 'Left Repeater',
|
||||
'right_repeater': 'Right Repeater',
|
||||
'rear': 'Rear',
|
||||
'back': 'Back',
|
||||
'left_pillar': 'Left Pillar',
|
||||
'right_pillar': 'Right Pillar'
|
||||
}
|
||||
|
||||
# Camera button layout order: three columns around the car graphic
|
||||
CAMERA_LAYOUT = [
|
||||
['left_repeater', 'left_pillar'],
|
||||
['front', 'back'],
|
||||
['right_repeater', 'right_pillar'],
|
||||
]
|
||||
|
||||
# In-memory scan cache. Scanning a large TeslaCam tree on every request is
|
||||
# expensive, so the result is cached and only refreshed after this many seconds
|
||||
# (or when /refresh is hit). Override via the SCAN_CACHE_TTL env var.
|
||||
@@ -157,20 +164,34 @@ def logout():
|
||||
@login_required
|
||||
def index():
|
||||
"""
|
||||
Main page listing all videos categorized by human-readable camera view.
|
||||
Main page: video player with camera-angle switching via a 3-column
|
||||
button grid around a top-down Model Y graphic.
|
||||
"""
|
||||
all_videos = scan_teslacam_videos()
|
||||
|
||||
# Map raw camera keys to display names for rendering
|
||||
categorized_videos = {}
|
||||
for camera_view, video_list in all_videos.items():
|
||||
display_name = get_camera_display_name(camera_view)
|
||||
categorized_videos[display_name] = {
|
||||
'raw_key': camera_view,
|
||||
'videos': video_list
|
||||
}
|
||||
# Build camera info list for the button grid
|
||||
camera_list = []
|
||||
for col in CAMERA_LAYOUT:
|
||||
col_cams = []
|
||||
for key in col:
|
||||
videos = all_videos.get(key, [])
|
||||
col_cams.append({
|
||||
'key': key,
|
||||
'display': get_camera_display_name(key),
|
||||
'count': len(videos),
|
||||
'first_url': videos[0]['url'] if videos else None,
|
||||
})
|
||||
camera_list.append(col_cams)
|
||||
|
||||
return render_template('index.html', categorized_videos=categorized_videos)
|
||||
# Default to the oldest front video
|
||||
front_videos = all_videos.get('front', [])
|
||||
default_url = front_videos[0]['url'] if front_videos else None
|
||||
|
||||
return render_template(
|
||||
'index.html',
|
||||
camera_list=camera_list,
|
||||
default_url=default_url,
|
||||
)
|
||||
|
||||
|
||||
@app.route('/camera/<camera_view>')
|
||||
@@ -215,6 +236,23 @@ def refresh():
|
||||
return 'Cache refreshed', 200
|
||||
|
||||
|
||||
@app.route('/api/videos')
|
||||
@login_required
|
||||
def api_videos():
|
||||
"""
|
||||
Returns all scanned videos as JSON, grouped by camera view.
|
||||
Used by the frontend for camera-angle switching.
|
||||
"""
|
||||
all_videos = scan_teslacam_videos()
|
||||
result = {}
|
||||
for cam_key, video_list in all_videos.items():
|
||||
result[cam_key] = {
|
||||
'display': get_camera_display_name(cam_key),
|
||||
'videos': video_list
|
||||
}
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@app.route('/health')
|
||||
def health():
|
||||
"""
|
||||
|
||||
Reference in new issue
Block a user