autoglm-gui 0.4.6__tar.gz → 0.4.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/api/media.py +109 -7
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/scrcpy_stream.py +42 -21
- autoglm_gui-0.4.6/AutoGLM_GUI/static/assets/about-BgmYMjz1.js → autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/about-DIdU3ZqP.js +1 -1
- autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/chat-_-u1G4Ee.js +25 -0
- autoglm_gui-0.4.6/AutoGLM_GUI/static/assets/index-sfTWLHvP.js → autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/index--ElIPD22.js +1 -1
- autoglm_gui-0.4.6/AutoGLM_GUI/static/assets/index-Dpft8C1z.js → autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/index-BuFMN8G5.js +1 -1
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/static/index.html +1 -1
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/PKG-INFO +1 -1
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/pyproject.toml +1 -1
- autoglm_gui-0.4.6/AutoGLM_GUI/static/assets/chat-CnjZadB7.js +0 -25
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/.gitignore +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/__main__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/adb_plus/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/adb_plus/screenshot.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/adb_plus/touch.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/api/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/api/agents.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/api/control.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/api/devices.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/config.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/schemas.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/server.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/state.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/static/assets/index-DCrxTz-A.css +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/AutoGLM_GUI/version.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/LICENSE +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/README.md +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/actions/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/actions/handler.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/adb/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/adb/connection.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/adb/device.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/adb/input.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/adb/screenshot.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/agent.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/config/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/config/apps.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/config/i18n.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/config/prompts.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/config/prompts_en.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/config/prompts_zh.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/model/__init__.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/phone_agent/model/client.py +0 -0
- {autoglm_gui-0.4.6 → autoglm_gui-0.4.7}/scrcpy-server-v3.3.3 +0 -0
|
@@ -68,7 +68,10 @@ def take_screenshot(request: ScreenshotRequest) -> ScreenshotResponse:
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
@router.websocket("/api/video/stream")
|
|
71
|
-
async def video_stream_ws(
|
|
71
|
+
async def video_stream_ws(
|
|
72
|
+
websocket: WebSocket,
|
|
73
|
+
device_id: str | None = None,
|
|
74
|
+
):
|
|
72
75
|
"""Stream real-time H.264 video from scrcpy server via WebSocket(多设备支持)."""
|
|
73
76
|
await websocket.accept()
|
|
74
77
|
|
|
@@ -78,6 +81,20 @@ async def video_stream_ws(websocket: WebSocket, device_id: str | None = None):
|
|
|
78
81
|
|
|
79
82
|
print(f"[video/stream] WebSocket connection for device {device_id}")
|
|
80
83
|
|
|
84
|
+
# Debug: Save stream to file for analysis
|
|
85
|
+
# Set to True for debugging (default: False)
|
|
86
|
+
debug_save = False
|
|
87
|
+
debug_file = None
|
|
88
|
+
if debug_save:
|
|
89
|
+
import os
|
|
90
|
+
from pathlib import Path
|
|
91
|
+
|
|
92
|
+
debug_dir = Path("debug_streams")
|
|
93
|
+
debug_dir.mkdir(exist_ok=True)
|
|
94
|
+
debug_file_path = debug_dir / f"{device_id}_{int(__import__('time').time())}.h264"
|
|
95
|
+
debug_file = open(debug_file_path, "wb")
|
|
96
|
+
print(f"[video/stream] DEBUG: Saving stream to {debug_file_path}")
|
|
97
|
+
|
|
81
98
|
if device_id not in scrcpy_locks:
|
|
82
99
|
scrcpy_locks[device_id] = asyncio.Lock()
|
|
83
100
|
|
|
@@ -92,6 +109,54 @@ async def video_stream_ws(websocket: WebSocket, device_id: str | None = None):
|
|
|
92
109
|
print(f"[video/stream] Starting scrcpy server for device {device_id}")
|
|
93
110
|
await scrcpy_streamers[device_id].start()
|
|
94
111
|
print(f"[video/stream] Scrcpy server started for device {device_id}")
|
|
112
|
+
|
|
113
|
+
# Read initial chunks and accumulate into a single buffer
|
|
114
|
+
# Then parse the entire buffer to find complete NAL units
|
|
115
|
+
streamer = scrcpy_streamers[device_id]
|
|
116
|
+
accumulated_buffer = bytearray()
|
|
117
|
+
target_size = 50 * 1024 # Accumulate at least 50KB
|
|
118
|
+
|
|
119
|
+
print(f"[video/stream] Accumulating initial data (target: {target_size} bytes)...")
|
|
120
|
+
for attempt in range(10):
|
|
121
|
+
try:
|
|
122
|
+
# Disable auto-caching - we'll parse the entire buffer at once
|
|
123
|
+
chunk = await streamer.read_h264_chunk(auto_cache=False)
|
|
124
|
+
accumulated_buffer.extend(chunk)
|
|
125
|
+
print(
|
|
126
|
+
f"[video/stream] Read chunk ({len(chunk)} bytes, total: {len(accumulated_buffer)} bytes)"
|
|
127
|
+
)
|
|
128
|
+
except Exception as e:
|
|
129
|
+
print(f"[video/stream] Failed to read chunk: {e}")
|
|
130
|
+
await asyncio.sleep(0.5)
|
|
131
|
+
continue
|
|
132
|
+
|
|
133
|
+
# Check if we have enough data
|
|
134
|
+
if len(accumulated_buffer) >= target_size:
|
|
135
|
+
break
|
|
136
|
+
|
|
137
|
+
# Now parse the entire accumulated buffer at once
|
|
138
|
+
# This ensures NAL units spanning multiple chunks are detected as complete
|
|
139
|
+
print(f"[video/stream] Parsing accumulated buffer ({len(accumulated_buffer)} bytes)...")
|
|
140
|
+
streamer._cache_nal_units(bytes(accumulated_buffer))
|
|
141
|
+
|
|
142
|
+
# Get initialization data
|
|
143
|
+
init_data = streamer.get_initialization_data()
|
|
144
|
+
if not init_data:
|
|
145
|
+
raise RuntimeError(
|
|
146
|
+
f"Failed to find complete SPS/PPS/IDR in {len(accumulated_buffer)} bytes"
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Send initialization data to first client
|
|
150
|
+
await websocket.send_bytes(init_data)
|
|
151
|
+
print(
|
|
152
|
+
f"[video/stream] Sent initial data ({len(init_data)} bytes) to first client"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Debug: Save to file
|
|
156
|
+
if debug_file:
|
|
157
|
+
debug_file.write(init_data)
|
|
158
|
+
debug_file.flush()
|
|
159
|
+
|
|
95
160
|
except Exception as e:
|
|
96
161
|
import traceback
|
|
97
162
|
|
|
@@ -108,15 +173,39 @@ async def video_stream_ws(websocket: WebSocket, device_id: str | None = None):
|
|
|
108
173
|
print(f"[video/stream] Reusing streamer for device {device_id}")
|
|
109
174
|
|
|
110
175
|
streamer = scrcpy_streamers[device_id]
|
|
111
|
-
|
|
112
|
-
|
|
176
|
+
# CRITICAL: Send complete initialization data (SPS+PPS+IDR)
|
|
177
|
+
# Without IDR frame, decoder cannot start and will show black screen
|
|
178
|
+
|
|
179
|
+
# Wait for initialization data to be ready (max 5 seconds)
|
|
180
|
+
init_data = None
|
|
181
|
+
for attempt in range(10):
|
|
182
|
+
init_data = streamer.get_initialization_data()
|
|
183
|
+
if init_data:
|
|
184
|
+
break
|
|
185
|
+
print(
|
|
186
|
+
f"[video/stream] Waiting for initialization data (attempt {attempt + 1}/10)..."
|
|
187
|
+
)
|
|
188
|
+
await asyncio.sleep(0.5)
|
|
189
|
+
|
|
190
|
+
if init_data:
|
|
113
191
|
await websocket.send_bytes(init_data)
|
|
114
|
-
print(f"[video/stream] Sent SPS/PPS for device {device_id}")
|
|
115
|
-
else:
|
|
116
192
|
print(
|
|
117
|
-
f"[video/stream]
|
|
193
|
+
f"[video/stream] Sent initialization data (SPS+PPS+IDR, {len(init_data)} bytes) for device {device_id}"
|
|
118
194
|
)
|
|
119
195
|
|
|
196
|
+
# Debug: Save to file
|
|
197
|
+
if debug_file:
|
|
198
|
+
debug_file.write(init_data)
|
|
199
|
+
debug_file.flush()
|
|
200
|
+
else:
|
|
201
|
+
error_msg = f"Initialization data not ready for device {device_id} after 5 seconds"
|
|
202
|
+
print(f"[video/stream] ERROR: {error_msg}")
|
|
203
|
+
try:
|
|
204
|
+
await websocket.send_json({"error": error_msg})
|
|
205
|
+
except Exception:
|
|
206
|
+
pass
|
|
207
|
+
return
|
|
208
|
+
|
|
120
209
|
streamer = scrcpy_streamers[device_id]
|
|
121
210
|
|
|
122
211
|
stream_failed = False
|
|
@@ -124,8 +213,16 @@ async def video_stream_ws(websocket: WebSocket, device_id: str | None = None):
|
|
|
124
213
|
chunk_count = 0
|
|
125
214
|
while True:
|
|
126
215
|
try:
|
|
127
|
-
|
|
216
|
+
# Disable auto_cache - we only cache once during initialization
|
|
217
|
+
# Later chunks may have incomplete NAL units that would corrupt the cache
|
|
218
|
+
h264_chunk = await streamer.read_h264_chunk(auto_cache=False)
|
|
128
219
|
await websocket.send_bytes(h264_chunk)
|
|
220
|
+
|
|
221
|
+
# Debug: Save to file
|
|
222
|
+
if debug_file:
|
|
223
|
+
debug_file.write(h264_chunk)
|
|
224
|
+
debug_file.flush()
|
|
225
|
+
|
|
129
226
|
chunk_count += 1
|
|
130
227
|
if chunk_count % 100 == 0:
|
|
131
228
|
print(
|
|
@@ -160,4 +257,9 @@ async def video_stream_ws(websocket: WebSocket, device_id: str | None = None):
|
|
|
160
257
|
scrcpy_streamers[device_id].stop()
|
|
161
258
|
del scrcpy_streamers[device_id]
|
|
162
259
|
|
|
260
|
+
# Debug: Close file
|
|
261
|
+
if debug_file:
|
|
262
|
+
debug_file.close()
|
|
263
|
+
print(f"[video/stream] DEBUG: Closed debug file")
|
|
264
|
+
|
|
163
265
|
print(f"[video/stream] Device {device_id}: Stream ended")
|
|
@@ -307,11 +307,14 @@ class ScrcpyStreamer:
|
|
|
307
307
|
|
|
308
308
|
raise ConnectionError("Failed to connect to scrcpy server")
|
|
309
309
|
|
|
310
|
-
def _find_nal_units(
|
|
310
|
+
def _find_nal_units(
|
|
311
|
+
self, data: bytes
|
|
312
|
+
) -> list[tuple[int, int, int, bool]]:
|
|
311
313
|
"""Find NAL units in H.264 data.
|
|
312
314
|
|
|
313
315
|
Returns:
|
|
314
|
-
List of (start_pos, nal_type, nal_size) tuples
|
|
316
|
+
List of (start_pos, nal_type, nal_size, is_complete) tuples
|
|
317
|
+
is_complete=False if NAL unit extends to chunk boundary (may be truncated)
|
|
315
318
|
"""
|
|
316
319
|
nal_units = []
|
|
317
320
|
i = 0
|
|
@@ -336,18 +339,22 @@ class ScrcpyStreamer:
|
|
|
336
339
|
|
|
337
340
|
# Find next start code to determine NAL unit size
|
|
338
341
|
next_start = nal_start + 1
|
|
342
|
+
found_next = False
|
|
339
343
|
while next_start < data_len - 3:
|
|
340
344
|
if (
|
|
341
345
|
data[next_start : next_start + 4] == b"\x00\x00\x00\x01"
|
|
342
346
|
or data[next_start : next_start + 3] == b"\x00\x00\x01"
|
|
343
347
|
):
|
|
348
|
+
found_next = True
|
|
344
349
|
break
|
|
345
350
|
next_start += 1
|
|
346
351
|
else:
|
|
347
352
|
next_start = data_len
|
|
348
353
|
|
|
349
354
|
nal_size = next_start - i
|
|
350
|
-
|
|
355
|
+
# NAL unit is complete only if we found the next start code
|
|
356
|
+
is_complete = found_next
|
|
357
|
+
nal_units.append((i, nal_type, nal_size, is_complete))
|
|
351
358
|
|
|
352
359
|
i = next_start
|
|
353
360
|
|
|
@@ -356,13 +363,13 @@ class ScrcpyStreamer:
|
|
|
356
363
|
def _cache_nal_units(self, data: bytes) -> None:
|
|
357
364
|
"""Parse and cache INITIAL complete NAL units (SPS, PPS, IDR).
|
|
358
365
|
|
|
359
|
-
IMPORTANT:
|
|
360
|
-
NAL units
|
|
361
|
-
|
|
366
|
+
IMPORTANT: Caches NAL units with size validation.
|
|
367
|
+
For small NAL units (SPS/PPS), we cache even if at chunk boundary.
|
|
368
|
+
For large NAL units (IDR), we require minimum size to ensure completeness.
|
|
362
369
|
"""
|
|
363
370
|
nal_units = self._find_nal_units(data)
|
|
364
371
|
|
|
365
|
-
for start, nal_type, size in nal_units:
|
|
372
|
+
for start, nal_type, size, is_complete in nal_units:
|
|
366
373
|
nal_data = data[start : start + size]
|
|
367
374
|
|
|
368
375
|
if nal_type == 7: # SPS
|
|
@@ -375,11 +382,11 @@ class ScrcpyStreamer:
|
|
|
375
382
|
f"{b:02x}" for b in nal_data[: min(12, len(nal_data))]
|
|
376
383
|
)
|
|
377
384
|
print(
|
|
378
|
-
f"[ScrcpyStreamer] ✓ Cached
|
|
385
|
+
f"[ScrcpyStreamer] ✓ Cached SPS ({size} bytes, complete={is_complete}): {hex_preview}..."
|
|
379
386
|
)
|
|
380
387
|
elif size < 10:
|
|
381
388
|
print(
|
|
382
|
-
f"[ScrcpyStreamer] ✗ Skipped
|
|
389
|
+
f"[ScrcpyStreamer] ✗ Skipped short SPS ({size} bytes)"
|
|
383
390
|
)
|
|
384
391
|
|
|
385
392
|
elif nal_type == 8: # PPS
|
|
@@ -392,24 +399,33 @@ class ScrcpyStreamer:
|
|
|
392
399
|
f"{b:02x}" for b in nal_data[: min(12, len(nal_data))]
|
|
393
400
|
)
|
|
394
401
|
print(
|
|
395
|
-
f"[ScrcpyStreamer] ✓ Cached
|
|
402
|
+
f"[ScrcpyStreamer] ✓ Cached PPS ({size} bytes, complete={is_complete}): {hex_preview}..."
|
|
396
403
|
)
|
|
397
404
|
elif size < 6:
|
|
398
405
|
print(
|
|
399
|
-
f"[ScrcpyStreamer] ✗ Skipped
|
|
406
|
+
f"[ScrcpyStreamer] ✗ Skipped short PPS ({size} bytes)"
|
|
400
407
|
)
|
|
401
408
|
|
|
402
409
|
elif nal_type == 5: # IDR frame
|
|
403
|
-
#
|
|
404
|
-
#
|
|
405
|
-
if self.cached_sps and self.cached_pps:
|
|
410
|
+
# CRITICAL: Only cache COMPLETE IDR frames
|
|
411
|
+
# Incomplete IDR frames cause "error while decoding MB" errors
|
|
412
|
+
if self.cached_sps and self.cached_pps and is_complete and size >= 1024:
|
|
406
413
|
is_first = self.cached_idr is None
|
|
407
414
|
self.cached_idr = nal_data
|
|
408
415
|
if is_first:
|
|
409
416
|
print(
|
|
410
|
-
f"[ScrcpyStreamer] ✓ Cached
|
|
417
|
+
f"[ScrcpyStreamer] ✓ Cached COMPLETE IDR frame ({size} bytes)"
|
|
411
418
|
)
|
|
412
419
|
# Don't log every IDR update (too verbose)
|
|
420
|
+
elif not is_complete:
|
|
421
|
+
if size > 1024: # Only log if it's a large incomplete IDR
|
|
422
|
+
print(
|
|
423
|
+
f"[ScrcpyStreamer] ⚠ Skipped INCOMPLETE IDR ({size} bytes, extends to chunk boundary)"
|
|
424
|
+
)
|
|
425
|
+
elif size < 1024:
|
|
426
|
+
print(
|
|
427
|
+
f"[ScrcpyStreamer] ✗ Skipped small IDR ({size} bytes)"
|
|
428
|
+
)
|
|
413
429
|
|
|
414
430
|
# Lock SPS/PPS once we have complete initial parameters
|
|
415
431
|
if self.cached_sps and self.cached_pps and not self.sps_pps_locked:
|
|
@@ -435,7 +451,9 @@ class ScrcpyStreamer:
|
|
|
435
451
|
|
|
436
452
|
# Find all IDR frames
|
|
437
453
|
idr_positions = [
|
|
438
|
-
(start, size)
|
|
454
|
+
(start, size)
|
|
455
|
+
for start, nal_type, size, _ in nal_units
|
|
456
|
+
if nal_type == 5
|
|
439
457
|
]
|
|
440
458
|
|
|
441
459
|
if not idr_positions:
|
|
@@ -497,11 +515,14 @@ class ScrcpyStreamer:
|
|
|
497
515
|
return init_data
|
|
498
516
|
return None
|
|
499
517
|
|
|
500
|
-
async def read_h264_chunk(self) -> bytes:
|
|
518
|
+
async def read_h264_chunk(self, auto_cache: bool = True) -> bytes:
|
|
501
519
|
"""Read H.264 data chunk from socket.
|
|
502
520
|
|
|
521
|
+
Args:
|
|
522
|
+
auto_cache: If True, automatically cache SPS/PPS/IDR from this chunk
|
|
523
|
+
|
|
503
524
|
Returns:
|
|
504
|
-
bytes: Raw H.264 data
|
|
525
|
+
bytes: Raw H.264 data
|
|
505
526
|
|
|
506
527
|
Raises:
|
|
507
528
|
ConnectionError: If socket is closed or error occurs
|
|
@@ -524,9 +545,9 @@ class ScrcpyStreamer:
|
|
|
524
545
|
f"[ScrcpyStreamer] Large chunk received: {len(data) / 1024:.1f} KB"
|
|
525
546
|
)
|
|
526
547
|
|
|
527
|
-
#
|
|
528
|
-
|
|
529
|
-
|
|
548
|
+
# Optionally cache SPS/PPS/IDR from this chunk
|
|
549
|
+
if auto_cache:
|
|
550
|
+
self._cache_nal_units(data)
|
|
530
551
|
|
|
531
552
|
# NOTE: We don't automatically prepend SPS/PPS here because:
|
|
532
553
|
# 1. NAL units may be truncated across chunks
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as o}from"./index
|
|
1
|
+
import{j as o}from"./index--ElIPD22.js";function t(){return o.jsx("div",{className:"p-2",children:o.jsx("h3",{children:"About"})})}export{t as component};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import{j as l,r as p,g as Ie,a as Oe,s as Ue,b as Ne,c as $e,d as Te,e as He,f as ze,i as Ye,h as Ve,k as We,l as Ge}from"./index--ElIPD22.js";function Xe({id:g,model:ae,status:U,isInitialized:R,isActive:b,onClick:H}){const z=U==="device";return l.jsx("button",{onClick:H,className:`w-full text-left px-4 py-3 rounded-lg transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] h-12 shrink-0 ${b?"bg-blue-500 text-white shadow-md":"bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700"}`,children:l.jsxs("div",{className:"flex items-center justify-between gap-2",children:[l.jsxs("div",{className:"flex items-center gap-3 min-w-0 flex-1",children:[l.jsx("div",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${z?"bg-green-400 shadow-[0_0_4px_rgba(74,222,128,0.6)]":"bg-gray-400"}`,title:z?"在线":"离线"}),l.jsxs("div",{className:"min-w-0 flex-1",children:[l.jsx("div",{className:`font-medium text-sm truncate ${b?"text-white":"text-gray-900 dark:text-gray-100"}`,children:ae||"未知设备"}),l.jsx("div",{className:`text-xs truncate ${b?"text-blue-100":"text-gray-500 dark:text-gray-400"}`,children:g})]})]}),R&&l.jsx("div",{className:`flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center ${b?"bg-white/20":"bg-green-100 dark:bg-green-900"}`,children:l.jsx("svg",{className:`w-3 h-3 ${b?"text-white":"text-green-600 dark:text-green-400"}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})})]})})}const Ke=()=>{try{const g=localStorage.getItem("sidebar-collapsed");return g!==null?JSON.parse(g):!1}catch(g){return console.warn("Failed to load sidebar collapsed state:",g),!1}};function Je({devices:g,currentDeviceId:ae,onSelectDevice:U,onOpenConfig:R}){const[b,H]=p.useState(Ke);p.useEffect(()=>{localStorage.setItem("sidebar-collapsed",JSON.stringify(b))},[b]),p.useEffect(()=>{const k=S=>{(S.metaKey||S.ctrlKey)&&S.key==="b"&&(S.preventDefault(),H(!b))};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[b]);const z=()=>{H(!b)};return l.jsxs(l.Fragment,{children:[b&&l.jsx("button",{onClick:z,className:"fixed left-0 top-20 w-8 h-16 bg-blue-500 hover:bg-blue-600 text-white rounded-r-full shadow-lg transition-all duration-300 z-50 flex items-center justify-center",title:"展开侧边栏",children:l.jsx("svg",{className:"w-4 h-4 transition-transform duration-300",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})}),l.jsxs("div",{className:`${b?"w-0 -ml-8":"w-64"} transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] h-full min-h-0 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-700 flex flex-col overflow-hidden`,children:[l.jsxs("div",{className:"border-b border-gray-200 dark:border-gray-700 flex items-center justify-between p-4 whitespace-nowrap",children:[l.jsxs("div",{children:[l.jsxs("h2",{className:"text-lg font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2",children:[l.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),"设备列表"]}),l.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:["共 ",g.length," 个设备"]})]}),l.jsx("button",{onClick:z,className:"p-1.5 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-all duration-300 ease-[cubic-bezier(0.4,0.0,0.2,1)]",title:"收缩侧边栏",children:l.jsx("svg",{className:"w-4 h-4 text-gray-500 dark:text-gray-400 transition-transform duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)]",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})})]}),l.jsx("div",{className:"flex-1 overflow-y-auto p-3 space-y-2 min-h-0",children:g.length===0?l.jsxs("div",{className:"text-center py-8 text-gray-500 dark:text-gray-400",children:[l.jsx("svg",{className:"w-12 h-12 mx-auto mb-2 opacity-50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),l.jsx("p",{className:"text-sm",children:"未检测到设备"}),l.jsx("p",{className:"text-xs mt-1",children:"请连接 ADB 设备"})]}):g.map(k=>l.jsx(Xe,{id:k.id,model:k.model,status:k.status,isInitialized:k.is_initialized,isActive:k.id===ae,onClick:()=>U(k.id)},k.id))}),l.jsx("div",{className:"p-3 border-t border-gray-200 dark:border-gray-700 space-y-2 whitespace-nowrap",children:l.jsxs("button",{onClick:R,className:"w-full px-4 py-2 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] font-medium text-gray-700 dark:text-gray-300 flex items-center justify-center gap-2",children:[l.jsxs("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]}),"全局配置"]})})]})]})}var Fe={exports:{}};const qe={},Ze=Object.freeze(Object.defineProperty({__proto__:null,default:qe},Symbol.toStringTag,{value:"Module"})),Qe=Ie(Ze);var et=Fe.exports,_e;function tt(){return _e||(_e=1,(function(g,ae){(function(U,R){g.exports=R(Qe)})(et,(function(U){function R(n,s){(s==null||s>n.length)&&(s=n.length);for(var e=0,r=Array(s);e<s;e++)r[e]=n[e];return r}function b(n){if(Array.isArray(n))return n}function H(n){if(Array.isArray(n))return R(n)}function z(n){if(n===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return n}function k(n,s){if(!(n instanceof s))throw new TypeError("Cannot call a class as a function")}function S(n,s){for(var e=0;e<s.length;e++){var r=s[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,B(r.key),r)}}function T(n,s,e){return s&&S(n.prototype,s),e&&S(n,e),Object.defineProperty(n,"prototype",{writable:!1}),n}function y(n,s){var e=typeof Symbol<"u"&&n[Symbol.iterator]||n["@@iterator"];if(!e){if(Array.isArray(n)||(e=oe(n))||s){e&&(n=e);var r=0,t=function(){};return{s:t,n:function(){return r>=n.length?{done:!0}:{done:!1,value:n[r++]}},e:function(c){throw c},f:t}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
|
|
2
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var i,a=!0,o=!1;return{s:function(){e=e.call(n)},n:function(){var c=e.next();return a=c.done,c},e:function(c){o=!0,i=c},f:function(){try{a||e.return==null||e.return()}finally{if(o)throw i}}}}function j(n){var s=Q();return function(){var e,r=N(n);if(s){var t=N(this).constructor;e=Reflect.construct(r,arguments,t)}else e=r.apply(this,arguments);return ye(this,e)}}function F(n,s,e){return(s=B(s))in n?Object.defineProperty(n,s,{value:e,enumerable:!0,configurable:!0,writable:!0}):n[s]=e,n}function N(n){return N=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(s){return s.__proto__||Object.getPrototypeOf(s)},N(n)}function V(n,s){if(typeof s!="function"&&s!==null)throw new TypeError("Super expression must either be null or a function");n.prototype=Object.create(s&&s.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),Object.defineProperty(n,"prototype",{writable:!1}),s&&xe(n,s)}function Q(){try{var n=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(Q=function(){return!!n})()}function me(n){if(typeof Symbol<"u"&&n[Symbol.iterator]!=null||n["@@iterator"]!=null)return Array.from(n)}function ee(n,s){var e=n==null?null:typeof Symbol<"u"&&n[Symbol.iterator]||n["@@iterator"];if(e!=null){var r,t,i,a,o=[],c=!0,u=!1;try{if(i=(e=e.call(n)).next,s!==0)for(;!(c=(r=i.call(e)).done)&&(o.push(r.value),o.length!==s);c=!0);}catch(d){u=!0,t=d}finally{try{if(!c&&e.return!=null&&(a=e.return(),Object(a)!==a))return}finally{if(u)throw t}}return o}}function se(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
3
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function W(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
|
|
4
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ye(n,s){if(s&&(typeof s=="object"||typeof s=="function"))return s;if(s!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return z(n)}function xe(n,s){return xe=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,r){return e.__proto__=r,e},xe(n,s)}function J(n,s){return b(n)||ee(n,s)||oe(n,s)||se()}function G(n){return H(n)||me(n)||oe(n)||W()}function O(n,s){if(typeof n!="object"||!n)return n;var e=n[Symbol.toPrimitive];if(e!==void 0){var r=e.call(n,s);if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)}function B(n){var s=O(n,"string");return typeof s=="symbol"?s:s+""}function te(n){"@babel/helpers - typeof";return te=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(s){return typeof s}:function(s){return s&&typeof Symbol=="function"&&s.constructor===Symbol&&s!==Symbol.prototype?"symbol":typeof s},te(n)}function oe(n,s){if(n){if(typeof n=="string")return R(n,s);var e={}.toString.call(n).slice(8,-1);return e==="Object"&&n.constructor&&(e=n.constructor.name),e==="Map"||e==="Set"?Array.from(n):e==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?R(n,s):void 0}}var $,re;function ce(n,s){$=n,re=s}function C(n){if($){for(var s=arguments.length,e=new Array(s>1?s-1:0),r=1;r<s;r++)e[r-1]=arguments[r];$.apply(void 0,[n].concat(e))}}function w(n){if(re){for(var s=arguments.length,e=new Array(s>1?s-1:0),r=1;r<s;r++)e[r-1]=arguments[r];re.apply(void 0,[n].concat(e))}}var pe=(function(){function n(s){k(this,n),this.listener={},this.type=s|""}return T(n,[{key:"on",value:function(e,r){return this.listener[e]||(this.listener[e]=[]),this.listener[e].push(r),!0}},{key:"off",value:function(e,r){if(this.listener[e]){var t=this.listener[e].indexOf(r);return t>-1&&this.listener[e].splice(t,1),!0}return!1}},{key:"offAll",value:function(){this.listener={}}},{key:"dispatch",value:function(e){for(var r=arguments.length,t=new Array(r>1?r-1:0),i=1;i<r;i++)t[i-1]=arguments[i];return this.listener[e]?(this.listener[e].map(function(a){a.apply(null,t)}),!0):!1}}]),n})(),le=(function(){function n(){k(this,n)}return T(n,null,[{key:"init",value:function(){n.types={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],hev1:[],hvcC:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]};var e;for(e in n.types)n.types.hasOwnProperty(e)&&(n.types[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);var r=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),t=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]);n.HDLR_TYPES={video:r,audio:t};var i=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),a=new Uint8Array([0,0,0,0,0,0,0,0]);n.STTS=n.STSC=n.STCO=a,n.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),n.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0]),n.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),n.STSD=new Uint8Array([0,0,0,0,0,0,0,1]);var o=new Uint8Array([105,115,111,109]),c=new Uint8Array([97,118,99,49]),u=new Uint8Array([0,0,0,1]);n.FTYP=n.box(n.types.ftyp,o,u,o,c),n.DINF=n.box(n.types.dinf,n.box(n.types.dref,i))}},{key:"box",value:function(e){for(var r=arguments.length,t=new Array(r>1?r-1:0),i=1;i<r;i++)t[i-1]=arguments[i];for(var a=8,o=t.length,c=o,u;o--;)a+=t[o].byteLength;for(u=new Uint8Array(a),u[0]=a>>24&255,u[1]=a>>16&255,u[2]=a>>8&255,u[3]=a&255,u.set(e,4),o=0,a=8;o<c;++o)u.set(t[o],a),a+=t[o].byteLength;return u}},{key:"hdlr",value:function(e){return n.box(n.types.hdlr,n.HDLR_TYPES[e])}},{key:"mdat",value:function(e){return n.box(n.types.mdat,e)}},{key:"mdhd",value:function(e,r){return n.box(n.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,e>>24&255,e>>16&255,e>>8&255,e&255,r>>>24&255,r>>>16&255,r>>>8&255,r&255,85,196,0,0]))}},{key:"mdia",value:function(e){return n.box(n.types.mdia,n.mdhd(e.timescale,e.duration),n.hdlr(e.type),n.minf(e))}},{key:"mfhd",value:function(e){return n.box(n.types.mfhd,new Uint8Array([0,0,0,0,e>>24,e>>16&255,e>>8&255,e&255]))}},{key:"minf",value:function(e){return e.type==="audio"?n.box(n.types.minf,n.box(n.types.smhd,n.SMHD),n.DINF,n.stbl(e)):n.box(n.types.minf,n.box(n.types.vmhd,n.VMHD),n.DINF,n.stbl(e))}},{key:"moof",value:function(e,r,t){return n.box(n.types.moof,n.mfhd(e),n.traf(t,r))}},{key:"moov",value:function(e,r,t){for(var i=e.length,a=[];i--;)a[i]=n.trak(e[i]);return n.box.apply(null,[n.types.moov,n.mvhd(t,r)].concat(a).concat(n.mvex(e)))}},{key:"mvex",value:function(e){for(var r=e.length,t=[];r--;)t[r]=n.trex(e[r]);return n.box.apply(null,[n.types.mvex].concat(t))}},{key:"mvhd",value:function(e,r){var t=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,e>>24&255,e>>16&255,e>>8&255,e&255,r>>>24&255,r>>>16&255,r>>>8&255,r&255,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return n.box(n.types.mvhd,t)}},{key:"sdtp",value:function(e){var r=e.samples||[],t=new Uint8Array(4+r.length),i,a;for(a=0;a<r.length;a++)i=r[a].flags,t[a+4]=i.dependsOn<<4|i.isDependedOn<<2|i.hasRedundancy;return n.box(n.types.sdtp,t)}},{key:"stbl",value:function(e){return n.box(n.types.stbl,n.stsd(e),n.box(n.types.stts,n.STTS),n.box(n.types.stsc,n.STSC),n.box(n.types.stsz,n.STSZ),n.box(n.types.stco,n.STCO))}},{key:"avc1",value:function(e){var r=[],t=[],i,a,o;for(i=0;i<e.sps.length;i++)a=e.sps[i],o=a.byteLength,r.push(o>>>8&255),r.push(o&255),r=r.concat(Array.prototype.slice.call(a));for(i=0;i<e.pps.length;i++)a=e.pps[i],o=a.byteLength,t.push(o>>>8&255),t.push(o&255),t=t.concat(Array.prototype.slice.call(a));var c=n.box(n.types.avcC,new Uint8Array([1,r[3],r[4],r[5],255,224|e.sps.length].concat(r).concat([e.pps.length]).concat(t))),u=e.width,d=e.height;return n.box(n.types.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,u>>8&255,u&255,d>>8&255,d&255,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),c,n.box(n.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"hev1",value:function(e){for(var r=[],t=[],i=[],a,o,c=0;c<(((u=e.vps)===null||u===void 0?void 0:u.length)||0);c++){var u;a=e.vps[c],o=a.byteLength,r.push(o>>>8&255,o&255),r=r.concat(Array.prototype.slice.call(a))}for(var d=0;d<(((h=e.sps)===null||h===void 0?void 0:h.length)||0);d++){var h;a=e.sps[d],o=a.byteLength,t.push(o>>>8&255,o&255),t=t.concat(Array.prototype.slice.call(a))}for(var f=0;f<(((x=e.pps)===null||x===void 0?void 0:x.length)||0);f++){var x;a=e.pps[f],o=a.byteLength,i.push(o>>>8&255,o&255),i=i.concat(Array.prototype.slice.call(a))}var v=e.hvcC,_=v.profile_space,I=v.tier_flag,A=v.profile_idc,E=v.profile_compatibility_flags,P=v.constraint_indicator_flags,fe=v.level_idc,ue=v.chroma_format_idc,Z=n.box(n.types.hvcC,new Uint8Array([1,_<<6|I<<5|A,E>>24&255,E>>16&255,E>>8&255,E&255].concat(G(P),[fe,240,0,252,252|ue,248,248,0,0,3,3,32,0,1],G(r),[33,0,1],G(t),[34,0,1],G(i)))),he=e.width,D=e.height;return n.box(n.types.hev1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,he>>8&255,he&255,D>>8&255,D&255,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),Z,n.box(n.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"esds",value:function(e){var r=e.config.byteLength,t=new Uint8Array(26+r+3);return t.set([0,0,0,0,3,23+r,0,1,0,4,15+r,64,21,0,0,0,0,0,0,0,0,0,0,0,5,r]),t.set(e.config,26),t.set([6,1,2],26+r),t}},{key:"mp4a",value:function(e){var r=e.audiosamplerate;return n.box(n.types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,e.channelCount,0,16,0,0,0,0,r>>8&255,r&255,0,0]),n.box(n.types.esds,n.esds(e)))}},{key:"stsd",value:function(e){return e.type==="audio"?n.box(n.types.stsd,n.STSD,n.mp4a(e)):e.codec.startsWith("hvc1")?n.box(n.types.stsd,n.STSD,n.hev1(e)):n.box(n.types.stsd,n.STSD,n.avc1(e))}},{key:"tkhd",value:function(e){var r=e.id,t=e.duration,i=e.width,a=e.height,o=e.volume;return n.box(n.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,r>>24&255,r>>16&255,r>>8&255,r&255,0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,t&255,0,0,0,0,0,0,0,0,0,0,0,0,o>>0&255,o%1*10>>0&255,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,i>>8&255,i&255,0,0,a>>8&255,a&255,0,0]))}},{key:"traf",value:function(e,r){var t=n.sdtp(e),i=e.id;return n.box(n.types.traf,n.box(n.types.tfhd,new Uint8Array([0,0,0,0,i>>24,i>>16&255,i>>8&255,i&255])),n.box(n.types.tfdt,new Uint8Array([0,0,0,0,r>>24,r>>16&255,r>>8&255,r&255])),n.trun(e,t.length+16+16+8+16+8+8),t)}},{key:"trak",value:function(e){return e.duration=e.duration||4294967295,n.box(n.types.trak,n.tkhd(e),n.mdia(e))}},{key:"trex",value:function(e){var r=e.id;return n.box(n.types.trex,new Uint8Array([0,0,0,0,r>>24,r>>16&255,r>>8&255,r&255,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]))}},{key:"trun",value:function(e,r){var t=e.samples||[],i=t.length,a=12+16*i,o=new Uint8Array(a),c,u,d,h,f,x;for(r+=8+a,o.set([0,0,15,1,i>>>24&255,i>>>16&255,i>>>8&255,i&255,r>>>24&255,r>>>16&255,r>>>8&255,r&255],0),c=0;c<i;c++)u=t[c],d=u.duration,h=u.size,f=u.flags,x=u.cts,o.set([d>>>24&255,d>>>16&255,d>>>8&255,d&255,h>>>24&255,h>>>16&255,h>>>8&255,h&255,f.isLeading<<2|f.dependsOn,f.isDependedOn<<6|f.hasRedundancy<<4|f.paddingValue<<1|f.isNonSync,f.degradPrio&61440,f.degradPrio&15,x>>>24&255,x>>>16&255,x>>>8&255,x&255],12+16*c);return n.box(n.types.trun,o)}},{key:"initSegment",value:function(e,r,t){n.types||n.init();var i=n.moov(e,r,t),a;return a=new Uint8Array(n.FTYP.byteLength+i.byteLength),a.set(n.FTYP),a.set(i,n.FTYP.byteLength),a}}]),n})(),ve=(function(){function n(){k(this,n)}return T(n,null,[{key:"samplingRateMap",get:function(){return[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350]}},{key:"getHeaderLength",value:function(e){return e[1]&1?7:9}},{key:"getFrameLength",value:function(e){return(e[3]&3)<<11|e[4]<<3|(e[5]&224)>>>5}},{key:"isAACPattern",value:function(e){return e[0]===255&&(e[1]&240)===240&&(e[1]&6)===0}},{key:"extractAAC",value:function(e){var r=0,t=e.byteLength,i=[],a,o;if(!n.isAACPattern(e))return w("Invalid ADTS audio format"),{valid:!1};a=n.getHeaderLength(e);for(var c=e.subarray(0,a);r<t;)o=n.getFrameLength(e),i.push(e.subarray(a,o)),e=e.slice(o),r+=o;return{valid:!0,header:c,slices:i}}}]),n})(),be=1,m=(function(n){V(e,n);var s=j(e);function e(){return k(this,e),s.apply(this,arguments)}return T(e,[{key:"flush",value:function(){this.mp4track.len=0,this.mp4track.samples=[]}},{key:"isReady",value:function(){return!this.readyToDecode||!this.samples.length?null:!0}}],[{key:"getTrackID",value:function(){return be++}}]),e})(pe),X=(function(n){V(e,n);var s=j(e);function e(r,t,i){var a;return k(this,e),a=s.call(this,"AACRemuxer"),a.frameDuration=i,a.readyToDecode=!1,a.header=null,a.nextDts=0,a.dts=0,a.mp4track={id:m.getTrackID(),type:"audio",channelCount:0,len:0,fragmented:!0,timescale:r,duration:t,samples:[],config:"",codec:""},a.samples=[],a}return T(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.header=null,this.mp4track.codec="",this.mp4track.channelCount="",this.mp4track.config="",this.mp4track.timescale=this.timescale,this.nextDts=0,this.dts=0}},{key:"feed",value:function(t,i){var a=ve.extractAAC(t),o=a.valid,c=a.header,u=a.slices;return this.header||(this.header=c),o&&u.length>0?(this.remux(this.getAudioFrames(u,i)),!0):(w("Failed to extract audio data from:",t),this.dispatch("outOfData"),!1)}},{key:"getAudioFrames",value:function(t,i){var a=[],o=0,c=0,u=y(t),d;try{for(u.s();!(d=u.n()).done;){var h=d.value;a.push({units:h})}}catch(f){u.e(f)}finally{u.f()}return o=i?i/a.length|0:this.frameDuration,c=i?i-o*a.length:0,a.map(function(f){f.duration=o,c>0&&(f.duration++,c--)}),a}},{key:"remux",value:function(t){if(t.length>0)for(var i=0;i<t.length;i++){var a=t[i],o=a.units,c=o.byteLength;this.samples.push({units:o,size:c,duration:a.duration}),this.mp4track.len+=c,this.readyToDecode||this.setAACConfig()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var t=new Uint8Array(this.mp4track.len),i=0,a=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift();if(u.units,c=u.duration,c<=0){C("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,dependsOn:1}},t.set(u.units,i),i+=u.size,a.push(o)}return a.length?new Uint8Array(t.buffer,0,this.mp4track.len):null}},{key:"setAACConfig",value:function(){var t,i,a,o=new Uint8Array(2);this.header&&(t=((this.header[2]&192)>>>6)+1,i=(this.header[2]&60)>>>2,a=(this.header[2]&1)<<2,a|=(this.header[3]&192)>>>6,o[0]=t<<3,o[0]|=(i&14)>>1,o[1]|=(i&1)<<7,o[1]|=a<<3,this.mp4track.codec="mp4a.40."+t,this.mp4track.channelCount=a,this.mp4track.config=o,this.readyToDecode=!0)}}]),e})(m),Y=(function(){function n(s){k(this,n),this.data=s,this.index=0,this.bitLength=s.byteLength*8}return T(n,[{key:"setData",value:function(e){this.data=e,this.index=0,this.bitLength=e.byteLength*8}},{key:"bitsAvailable",get:function(){return this.bitLength-this.index}},{key:"skipBits",value:function(e){if(this.bitsAvailable<e)return!1;this.index+=e}},{key:"readBits",value:function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,t=this.getBits(e,this.index,r);return t}},{key:"getBits",value:function(e,r){var t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(this.bitsAvailable<e)return 0;var i=r%8,a=this.data[r/8|0]&255>>>i,o=8-i;if(o>=e)return t&&(this.index+=e),a>>o-e;t&&(this.index+=o);var c=e-o;return a<<c|this.getBits(c,r+o,t)}},{key:"skipLZ",value:function(){var e;for(e=0;e<this.bitLength-this.index;++e)if(this.getBits(1,this.index+e,!1)!==0)return this.index+=e,e;return e}},{key:"skipUEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"skipEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"readUEG",value:function(){var e=this.skipLZ();return this.readBits(e+1)-1}},{key:"readEG",value:function(){var e=this.readUEG();return 1&e?1+e>>>1:-1*(e>>>1)}},{key:"readBoolean",value:function(){return this.readBits(1)===1}},{key:"readUByte",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1;return this.readBits(e*8)}},{key:"readUShort",value:function(){return this.readBits(16)}},{key:"readUInt",value:function(){return this.readBits(32)}}]),n})(),q=(function(){function n(){k(this,n)}return T(n,null,[{key:"extractNALu",value:function(e){for(var r=0,t=e.byteLength,i=[],a=0,o=0;r<t;){var c=e[r++];if(c===0)o++;else if(c===1&&o>=2){var u=o+1;a!==r-u&&i.push(e.subarray(a,r-u)),a=r,o=0}else o=0}var d=null;return a<t&&(d=e.subarray(a,t)),[i,d]}},{key:"skipScalingList",value:function(e,r){for(var t=8,i=8,a,o=0;o<r;o++)i!==0&&(a=e.readEG(),i=(t+a+256)%256),t=i===0?t:i}},{key:"readSPS",value:function(e){var r=new Y(e),t=0,i=0,a=0,o=0,c=1,u,d,h,f,x,v,_=0;r.readUByte();for(var I=[],A=1,E=e.byteLength,P=A;P<E;P++)P+2<E&&r.readBits(24,!1)===3?(I.push(r.readBits(8)),I.push(r.readBits(8)),P+=2,r.readBits(8)):I.push(r.readBits(8));if(r.setData(new Uint8Array(I)),u=r.readUByte(),r.readBits(5),r.skipBits(3),r.readUByte(),r.skipUEG(),u===100||u===110||u===122||u===244||u===44||u===83||u===86||u===118||u===128){var fe=r.readUEG();if(fe===3&&r.skipBits(1),r.skipUEG(),r.skipUEG(),r.skipBits(1),r.readBoolean()){v=fe!==3?8:12;for(var ue=0;ue<v;++ue)r.readBoolean()&&(ue<6?n.skipScalingList(r,16):n.skipScalingList(r,64))}}r.skipUEG();var Z=r.readUEG();if(Z===0)r.readUEG();else if(Z===1){r.skipBits(1),r.skipEG(),r.skipEG(),d=r.readUEG();for(var he=0;he<d;++he)r.skipEG()}if(r.skipUEG(),r.skipBits(1),h=r.readUEG(),f=r.readUEG(),x=r.readBits(1),x===0&&r.skipBits(1),r.skipBits(1),r.readBoolean()&&(t=r.readUEG(),i=r.readUEG(),a=r.readUEG(),o=r.readUEG()),r.readBoolean()){if(r.readBoolean()){var D,de=r.readUByte();switch(de){case 1:D=[1,1];break;case 2:D=[12,11];break;case 3:D=[10,11];break;case 4:D=[16,11];break;case 5:D=[40,33];break;case 6:D=[24,11];break;case 7:D=[20,11];break;case 8:D=[32,11];break;case 9:D=[80,33];break;case 10:D=[18,11];break;case 11:D=[15,11];break;case 12:D=[64,33];break;case 13:D=[160,99];break;case 14:D=[4,3];break;case 15:D=[3,2];break;case 16:D=[2,1];break;case 255:{D=[r.readUByte()<<8|r.readUByte(),r.readUByte()<<8|r.readUByte()];break}}D&&D[0]>0&&D[1]>0&&(c=D[0]/D[1])}if(r.readBoolean()&&r.skipBits(1),r.readBoolean()&&(r.skipBits(4),r.readBoolean()&&r.skipBits(24)),r.readBoolean()&&(r.skipUEG(),r.skipUEG()),r.readBoolean()){var ge=r.readUInt(),we=r.readUInt(),Se=r.readBoolean(),Pe=we/(2*ge);Se&&(_=Pe)}}return{fps:_>0?_:void 0,width:Math.ceil(((h+1)*16-t*2-i*2)*c),height:(2-x)*(f+1)*16-(x?2:4)*(a+o)}}}]),n})(),ne=(function(){function n(s){k(this,n),this.payload=s,this.nri=(this.payload[0]&96)>>5,this.nalUnitType=this.payload[0]&31,this._sliceType=null,this._isFirstSlice=!1}return T(n,[{key:"toString",value:function(){return"".concat(n.TYPES[this.type()]||"UNKNOWN",": NRI: ").concat(this.getNri())}},{key:"getNri",value:function(){return this.nri}},{key:"type",value:function(){return this.nalUnitType}},{key:"isKeyframe",get:function(){return this.nalUnitType===n.IDR}},{key:"isVCL",get:function(){return this.nalUnitType==n.IDR||this.nalUnitType==n.NDR}},{key:"parseHeader",value:function(){var e=new Y(this.getPayload());e.readUByte(),this._isFirstSlice=e.readUEG()===0,this._sliceType=e.readUEG()}},{key:"isFirstSlice",get:function(){return this._isFirstSlice||this.parseHeader(),this._isFirstSlice}},{key:"sliceType",get:function(){return this._sliceType||this.parseHeader(),this._sliceType}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize()),r=new DataView(e.buffer);return r.setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"NDR",get:function(){return 1}},{key:"IDR",get:function(){return 5}},{key:"SEI",get:function(){return 6}},{key:"SPS",get:function(){return 7}},{key:"PPS",get:function(){return 8}},{key:"AUD",get:function(){return 9}},{key:"TYPES",get:function(){var e;return e={},F(e,n.IDR,"IDR"),F(e,n.SEI,"SEI"),F(e,n.SPS,"SPS"),F(e,n.PPS,"PPS"),F(e,n.NDR,"NDR"),F(e,n.AUD,"AUD"),e}}]),n})();function ie(n,s){var e=new Uint8Array((n.byteLength|0)+(s.byteLength|0));return e.set(n,0),e.set(s,n.byteLength|0),e}function ke(n){var s,e,r,t="";return s=Math.floor(n),e=parseInt(s/3600,10)%24,r=parseInt(s/60,10)%60,s=s<0?0:s%60,e>0&&(t+=(e<10?"0"+e:e)+":"),t+=(r<10?"0"+r:r)+":"+(s<10?"0"+s:s),t}var L=(function(n){V(e,n);var s=j(e);function e(r,t,i){var a;return k(this,e),a=s.call(this,"H264Remuxer"),a.frameDuration=i,a.readyToDecode=!1,a.nextDts=0,a.dts=0,a.mp4track={id:m.getTrackID(),type:"video",len:0,fragmented:!0,sps:"",pps:"",fps:30,width:0,height:0,timescale:r,duration:t,samples:[]},a.samples=[],a.remainingData=new Uint8Array,a.kfCounter=0,a.pendingUnits={},a}return T(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.sps="",this.mp4track.pps="",this.nextDts=0,this.dts=0,this.remainingData=new Uint8Array,this.kfCounter=0,this.pendingUnits={}}},{key:"feed",value:function(t,i,a){var o=[],c;t=ie(this.remainingData,t);var u=q.extractNALu(t),d=J(u,2);return o=d[0],c=d[1],this.remainingData=c||new Uint8Array,o.length>0?(this.remux(this.getVideoFrames(o,i,a)),!0):(w("Failed to extract any NAL units from video data:",c),this.dispatch("outOfData"),!1)}},{key:"getVideoFrames",value:function(t,i,a){var o=this,c=[],u=[],d=0,h=0,f=!1,x=!1;this.pendingUnits.units&&(c=this.pendingUnits.units,x=this.pendingUnits.vcl,f=this.pendingUnits.keyFrame,this.pendingUnits={});var v=y(t),_;try{for(v.s();!(_=v.n()).done;){var I=_.value,A=new ne(I);c.length&&x&&(A.isFirstSlice||!A.isVCL)&&(u.push({units:c,keyFrame:f}),c=[],f=!1,x=!1),c.push(A),f=f||A.isKeyframe,x=x||A.isVCL}}catch(P){v.e(P)}finally{v.f()}if(c.length)if(!i)this.pendingUnits={units:c,keyFrame:f,vcl:x};else if(x)u.push({units:c,keyFrame:f});else{var E=u.length-1;E>=0&&(u[E].units=u[E].units.concat(c))}return d=i?i/u.length|0:this.frameDuration,h=i?i-d*u.length:0,u.map(function(P){P.duration=d,P.compositionTimeOffset=a,h>0&&(P.duration++,h--),o.kfCounter++,P.keyFrame&&o.dispatch("keyframePosition",o.kfCounter*d/1e3)}),C("jmuxer: No. of H264 frames of the last chunk: ".concat(u.length)),u}},{key:"remux",value:function(t){var i=y(t),a;try{for(i.s();!(a=i.n()).done;){var o=a.value,c=[],u=0,d=y(o.units),h;try{for(d.s();!(h=d.n()).done;){var f=h.value;this.parseNAL(f)&&(c.push(f),u+=f.getSize())}}catch(x){d.e(x)}finally{d.f()}c.length>0&&this.readyToDecode&&(this.mp4track.len+=u,this.samples.push({units:c,size:u,keyFrame:o.keyFrame,duration:o.duration,compositionTimeOffset:o.compositionTimeOffset}))}}catch(x){i.e(x)}finally{i.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var t=new Uint8Array(this.mp4track.len),i=0,a=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift(),d=u.units;if(c=u.duration,c<=0){C("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:u.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:u.keyFrame?0:1,dependsOn:u.keyFrame?2:1}};var h=y(d),f;try{for(h.s();!(f=h.n()).done;){var x=f.value;t.set(x.getData(),i),i+=x.getSize()}}catch(v){h.e(v)}finally{h.f()}a.push(o)}return a.length?new Uint8Array(t.buffer,0,this.mp4track.len):null}},{key:"parseSPS",value:function(t){var i=q.readSPS(new Uint8Array(t));this.mp4track.fps=i.fps||this.mp4track.fps,this.mp4track.width=i.width,this.mp4track.height=i.height,this.mp4track.sps=[new Uint8Array(t)],this.mp4track.codec="avc1.";for(var a=new DataView(t.buffer,t.byteOffset+1,4),o=0;o<3;++o){var c=a.getUint8(o).toString(16);c.length<2&&(c="0"+c),this.mp4track.codec+=c}}},{key:"parsePPS",value:function(t){this.mp4track.pps=[new Uint8Array(t)]}},{key:"parseNAL",value:function(t){if(!t)return!1;if(t.isVCL)return!0;var i=!1;switch(t.type()){case ne.PPS:this.mp4track.pps||this.parsePPS(t.getPayload()),i=!0;break;case ne.SPS:this.mp4track.sps||this.parseSPS(t.getPayload()),i=!0;break;case ne.AUD:C("AUD - ignoing");break;case ne.SEI:C("SEI - ignoing");break}return!this.readyToDecode&&this.mp4track.pps&&this.mp4track.sps&&(this.readyToDecode=!0),i}}]),e})(m),K=(function(){function n(){k(this,n)}return T(n,null,[{key:"extractNALu",value:function(e){for(var r=0,t=e.byteLength,i=[],a=0,o=0;r<t;){var c=e[r++];if(c===0)o++;else if(c===1&&o>=2){var u=o+1;a!==r-u&&i.push(e.subarray(a,r-u)),a=r,o=0}else o=0}var d=null;return a<t&&(d=e.subarray(a,t)),[i,d]}},{key:"removeEmulationPreventionBytes",value:function(e){for(var r=[],t=0,i=0;i<e.length;i++){var a=e[i];if(t===2&&a===3){t=0;continue}r.push(a),a===0?t++:t=0}return new Uint8Array(r)}},{key:"readSPS",value:function(e){var r=new Y(e);r.readUByte(),r.readUByte(),r.readBits(4),r.readBits(3),r.readBits(1);for(var t=r.readBits(2),i=r.readBits(1),a=r.readBits(5),o=r.readUInt(),c=new Uint8Array(6),u=0;u<6;u++)c[u]=r.readUByte();var d=r.readUByte();r.readUEG();var h=r.readUEG();h===3&&r.readBits(1);var f=r.readUEG(),x=r.readUEG(),v=r.readBoolean(),_=0,I=0,A=0,E=0;v&&(_=r.readUEG(),I=r.readUEG(),A=r.readUEG(),E=r.readUEG());var P=null,fe=r.readBoolean();if(fe){var ue=r.readBoolean();if(ue){var Z=r.readUByte();Z===255&&(r.readUShort(),r.readUShort())}var he=r.readBoolean();he&&r.readBoolean();var D=r.readBoolean();if(D){r.readBits(3),r.readBoolean();var de=r.readBoolean();de&&(r.readUByte(),r.readUByte(),r.readUByte())}var ge=r.readBoolean();ge&&(r.readUEG(),r.readUEG()),r.readBoolean(),r.readBoolean(),r.readBoolean();var we=r.readBoolean();if(we){var Se=r.readUInt(),Pe=r.readUInt();r.readBoolean(),Se&&(P=Pe/(2*Se))}}var Be=h===1||h===2?2:1,Re=h===1?2:1,Le=f-Be*(I+_),Me=x-Re*(A+E);return{width:Le,height:Me,profile_space:t,tier_flag:i,profile_idc:a,profile_compatibility_flags:o,constraint_indicator_flags:c,level_idc:d,chroma_format_idc:h,fps:P}}}]),n})(),M=(function(){function n(s){k(this,n),this.payload=s,this.nalUnitType=(s[0]&126)>>1,this.nuhLayerId=(s[0]&1)<<5|(s[1]&248)>>3,this.nuhTemporalIdPlus1=s[1]&7,this._isFirstSlice=null,this._sliceType=null}return T(n,[{key:"toString",value:function(){return"".concat(n.TYPES[this.type()]||"UNKNOWN ("+this.type()+")",": Layer: ").concat(this.nuhLayerId,", Temporal Id: ").concat(this.nuhTemporalIdPlus1)}},{key:"type",value:function(){return this.nalUnitType}},{key:"isKeyframe",get:function(){return[n.IDR_W_RADL,n.IDR_N_LP,n.CRA].includes(this.nalUnitType)}},{key:"isVCL",get:function(){return this.nalUnitType<=31}},{key:"parseHeader",value:function(){var e=new Y(this.getPayload());e.readUByte(),e.readUByte(),this._isFirstSlice=e.readBoolean(),this.isKeyframe&&e.readBits(1),e.readUEG(),this._sliceType=e.readUEG()}},{key:"isFirstSlice",get:function(){return this._isFirstSlice||this.parseHeader(),this._isFirstSlice}},{key:"sliceType",get:function(){return this._sliceType||this.parseHeader(),this._sliceType}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize()),r=new DataView(e.buffer);return r.setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"TRAIL_N",get:function(){return 0}},{key:"TRAIL_R",get:function(){return 1}},{key:"IDR_W_RADL",get:function(){return 19}},{key:"IDR_N_LP",get:function(){return 20}},{key:"CRA",get:function(){return 21}},{key:"VPS",get:function(){return 32}},{key:"SPS",get:function(){return 33}},{key:"PPS",get:function(){return 34}},{key:"AUD",get:function(){return 35}},{key:"SEI",get:function(){return 39}},{key:"SEI2",get:function(){return 40}},{key:"TYPES",get:function(){var e;return e={},F(e,n.TRAIL_N,"TRAIL_N"),F(e,n.TRAIL_R,"TRAIL_R"),F(e,n.IDR_W_RADL,"IDR"),F(e,n.IDR_N_LP,"IDR2"),F(e,n.CRA,"CRA"),F(e,n.VPS,"VPS"),F(e,n.SPS,"SPS"),F(e,n.PPS,"PPS"),F(e,n.AUD,"AUD"),F(e,n.SEI,"SEI"),F(e,n.SEI2,"SEI2"),e}}]),n})(),Ce=(function(n){V(e,n);var s=j(e);function e(r,t,i){var a;return k(this,e),a=s.call(this,"H264Remuxer"),a.frameDuration=i,a.readyToDecode=!1,a.nextDts=0,a.dts=0,a.mp4track={id:m.getTrackID(),type:"video",len:0,fragmented:!0,vps:"",sps:"",pps:"",hvcC:{},fps:30,width:0,height:0,timescale:r,duration:t,samples:[]},a.samples=[],a.remainingData=new Uint8Array,a.kfCounter=0,a.pendingUnits={},a}return T(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.vps="",this.mp4track.sps="",this.mp4track.pps="",this.mp4track.hvcC={},this.nextDts=0,this.dts=0,this.remainingData=new Uint8Array,this.kfCounter=0,this.pendingUnits={}}},{key:"feed",value:function(t,i,a){var o=[],c;t=ie(this.remainingData,t);var u=K.extractNALu(t),d=J(u,2);return o=d[0],c=d[1],this.remainingData=c||new Uint8Array,o.length>0?(this.remux(this.getVideoFrames(o,i,a)),!0):(w("Failed to extract any NAL units from video data:",c),this.dispatch("outOfData"),!1)}},{key:"getVideoFrames",value:function(t,i,a){var o=this,c=[],u=[],d=0,h=0,f=!1,x=!1;this.pendingUnits.units&&(c=this.pendingUnits.units,x=this.pendingUnits.vcl,f=this.pendingUnits.keyFrame,this.pendingUnits={});var v=y(t),_;try{for(v.s();!(_=v.n()).done;){var I=_.value,A=new M(I);c.length&&x&&(A.isFirstSlice||!A.isVCL)&&(u.push({units:c,keyFrame:f}),c=[],f=!1,x=!1),c.push(A),f=f||A.isKeyframe,x=x||A.isVCL}}catch(P){v.e(P)}finally{v.f()}if(c.length)if(!i)this.pendingUnits={units:c,keyFrame:f,vcl:x};else if(x)u.push({units:c,keyFrame:f});else{var E=u.length-1;E>=0&&(u[E].units=u[E].units.concat(c))}return d=i?i/u.length|0:this.frameDuration,h=i?i-d*u.length:0,u.map(function(P){P.duration=d,P.compositionTimeOffset=a,h>0&&(P.duration++,h--),o.kfCounter++,P.keyFrame&&o.dispatch("keyframePosition",o.kfCounter*d/1e3)}),C("jmuxer: No. of H265 frames of the last chunk: ".concat(u.length)),u}},{key:"remux",value:function(t){var i=y(t),a;try{for(i.s();!(a=i.n()).done;){var o=a.value,c=[],u=0,d=y(o.units),h;try{for(d.s();!(h=d.n()).done;){var f=h.value;this.parseNAL(f)&&(c.push(f),u+=f.getSize())}}catch(x){d.e(x)}finally{d.f()}c.length>0&&this.readyToDecode&&(this.mp4track.len+=u,this.samples.push({units:c,size:u,keyFrame:o.keyFrame,duration:o.duration,compositionTimeOffset:o.compositionTimeOffset}))}}catch(x){i.e(x)}finally{i.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var t=new Uint8Array(this.mp4track.len),i=0,a=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift(),d=u.units;if(c=u.duration,c<=0){C("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:u.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:u.keyFrame?0:1,dependsOn:u.keyFrame?2:1}};var h=y(d),f;try{for(h.s();!(f=h.n()).done;){var x=f.value;t.set(x.getData(),i),i+=x.getSize()}}catch(v){h.e(v)}finally{h.f()}a.push(o)}return a.length?new Uint8Array(t.buffer,0,this.mp4track.len):null}},{key:"parseSPS",value:function(t){this.mp4track.sps=[new Uint8Array(t)],t=K.removeEmulationPreventionBytes(t);var i=K.readSPS(new Uint8Array(t));this.mp4track.fps=i.fps||this.mp4track.fps,this.mp4track.width=i.width,this.mp4track.height=i.height,this.mp4track.codec="hvc1.".concat(i.profile_idc,".").concat(i.profile_compatibility_flags.toString(16))+".L".concat(i.level_idc).concat(i.tier_flag?"H":"L")+".".concat(i.constraint_indicator_flags.map(function(a){return a.toString(16)}).join(".").toUpperCase()),this.mp4track.hvcC={profile_space:i.profile_space,tier_flag:i.tier_flag,profile_idc:i.profile_idc,profile_compatibility_flags:i.profile_compatibility_flags,constraint_indicator_flags:i.constraint_indicator_flags,level_idc:i.level_idc,chroma_format_idc:i.chroma_format_idc}}},{key:"parsePPS",value:function(t){this.mp4track.pps=[t]}},{key:"parseVPS",value:function(t){this.mp4track.vps=[t]}},{key:"parseNAL",value:function(t){if(!t)return!1;if(t.isVCL)return!0;var i=!1;switch(t.type()){case M.VPS:this.mp4track.vps||this.parseVPS(t.getPayload()),i=!0;break;case M.SPS:this.mp4track.sps||this.parseSPS(t.getPayload()),i=!0;break;case M.PPS:this.mp4track.pps||this.parsePPS(t.getPayload()),i=!0;break;case M.AUD:C("AUD - ignoing");break;case M.SEI:case M.SEI2:C("SEI - ignoing");break}return!this.readyToDecode&&this.mp4track.vps&&this.mp4track.sps&&this.mp4track.pps&&(this.readyToDecode=!0),i}}]),e})(m),De=(function(n){V(e,n);var s=j(e);function e(r,t,i,a){var o;return k(this,e),o=s.call(this,"remuxer"),o.videoCodec=i,o.frameDuration=a,o.initialized=!1,o.tracks={},o.seq=1,o.env=r,o.timescale=1e3,o.mediaDuration=t?4294967295:0,o}return T(e,[{key:"addTrack",value:function(t){var i=this;if((t==="video"||t==="both")&&(this.videoCodec=="H265"?this.tracks.video=new Ce(this.timescale,this.mediaDuration,this.frameDuration):this.tracks.video=new L(this.timescale,this.mediaDuration,this.frameDuration),this.tracks.video.on("outOfData",function(){i.dispatch("missingVideoFrames")}),this.tracks.video.on("keyframePosition",function(o){i.dispatch("keyframePosition",o)})),t==="audio"||t==="both"){var a=new X(this.timescale,this.mediaDuration,this.frameDuration);this.tracks.audio=a,this.tracks.video.on("outOfData",function(){i.dispatch("missingAudioFrames")})}}},{key:"reset",value:function(){for(var t in this.tracks)this.tracks[t].resetTrack();this.initialized=!1}},{key:"destroy",value:function(){this.tracks={},this.offAll()}},{key:"flush",value:function(){if(!this.initialized){if(!this.isReady())return;this.dispatch("ready"),this.initSegment(),this.initialized=!0}for(var t in this.tracks){var i=this.tracks[t],a=i.getPayload();if(a&&a.byteLength){var o=le.moof(this.seq,i.dts,i.mp4track),c=le.mdat(a),u=ie(o,c),d={type:t,payload:u,dts:i.dts};t==="video"&&(d.fps=i.mp4track.fps),this.dispatch("buffer",d);var h=ke(i.dts/this.timescale);C("put segment (".concat(t,"): dts: ").concat(i.dts," frames: ").concat(i.mp4track.samples.length," second: ").concat(h)),i.flush(),this.seq++}}}},{key:"initSegment",value:function(){var t=[];for(var i in this.tracks){var a=this.tracks[i];if(this.env=="browser"){var o={type:i,payload:le.initSegment([a.mp4track],this.mediaDuration,this.timescale)};this.dispatch("buffer",o)}else t.push(a.mp4track)}if(this.env=="node"){var c={type:"all",payload:le.initSegment(t,this.mediaDuration,this.timescale)};this.dispatch("buffer",c)}C("Initial segment generated.")}},{key:"isReady",value:function(){for(var t in this.tracks)if(!this.tracks[t].readyToDecode||!this.tracks[t].samples.length)return!1;return!0}},{key:"feed",value:function(t){var i=!1;if(t.video&&this.tracks.video&&(i|=this.tracks.video.feed(t.video,t.duration,t.compositionTimeOffset)),t.audio&&this.tracks.audio&&(i|=this.tracks.audio.feed(t.audio,t.duration)),!i){w("Input object must have video and/or audio property. Make sure it is a valid typed array");return}this.flush()}}]),e})(pe),je=(function(n){V(e,n);var s=j(e);function e(r,t){var i;return k(this,e),i=s.call(this,"buffer"),i.type=t,i.queue=new Uint8Array,i.cleaning=!1,i.pendingCleaning=0,i.cleanOffset=30,i.cleanRanges=[],i.sourceBuffer=r,i.sourceBuffer.addEventListener("updateend",function(){if(i.pendingCleaning>0&&(i.initCleanup(i.pendingCleaning),i.pendingCleaning=0),i.cleaning=!1,i.cleanRanges.length){i.doCleanup();return}}),i.sourceBuffer.addEventListener("error",function(){i.dispatch("error",{type:i.type,name:"buffer",error:"buffer error"})}),i}return T(e,[{key:"destroy",value:function(){this.queue=null,this.sourceBuffer=null,this.offAll()}},{key:"doCleanup",value:function(){if(!this.cleanRanges.length){this.cleaning=!1;return}var t=this.cleanRanges.shift();C("".concat(this.type," remove range [").concat(t[0]," - ").concat(t[1],")")),this.cleaning=!0,this.sourceBuffer.remove(t[0],t[1])}},{key:"initCleanup",value:function(t){try{if(this.sourceBuffer.updating){this.pendingCleaning=t;return}if(this.sourceBuffer.buffered&&this.sourceBuffer.buffered.length&&!this.cleaning){for(var i=0;i<this.sourceBuffer.buffered.length;++i){var a=this.sourceBuffer.buffered.start(i),o=this.sourceBuffer.buffered.end(i);t-a>this.cleanOffset&&(o=t-this.cleanOffset,a<o&&this.cleanRanges.push([a,o]))}this.doCleanup()}}catch(c){w("Error occured while cleaning ".concat(this.type," buffer - ").concat(c.name,": ").concat(c.message))}}},{key:"doAppend",value:function(){if(this.queue.length&&!(!this.sourceBuffer||this.sourceBuffer.updating))try{this.sourceBuffer.appendBuffer(this.queue),this.queue=new Uint8Array}catch(i){var t="unexpectedError";i.name==="QuotaExceededError"?(C("".concat(this.type," buffer quota full")),t="QuotaExceeded"):(w("Error occured while appending ".concat(this.type," buffer - ").concat(i.name,": ").concat(i.message)),t="InvalidStateError"),this.dispatch("error",{type:this.type,name:t,error:"buffer error"})}}},{key:"feed",value:function(t){this.queue=ie(this.queue,t)}}]),e})(pe),Ae=(function(n){V(e,n);var s=j(e);function e(r){var t;k(this,e),t=s.call(this,"jmuxer"),t.isReset=!1;var i={node:"",mode:"both",videoCodec:"H264",flushingTime:500,maxDelay:500,clearBuffer:!0,fps:30,readFpsFromTrack:!1,debug:!1,onReady:function(){},onData:function(){},onError:function(){},onUnsupportedCodec:function(){},onMissingVideoFrames:function(){},onMissingAudioFrames:function(){},onKeyframePosition:function(){},onLoggerLog:console.log,onLoggerErr:console.error};return t.options=Object.assign({},i,r),t.env=(typeof process>"u"?"undefined":te(process))==="object"&&typeof window>"u"?"node":"browser",t.options.debug&&ce(t.options.onLoggerLog,t.options.onLoggerErr),t.options.fps||(t.options.fps=30),t.frameDuration=1e3/t.options.fps|0,t.remuxController=new De(t.env,r.live,t.options.videoCodec,t.frameDuration),t.remuxController.addTrack(t.options.mode),t.initData(),t.remuxController.on("buffer",t.onBuffer.bind(z(t))),t.env=="browser"&&(t.remuxController.on("ready",t.createBuffer.bind(z(t))),t.initBrowser()),t.remuxController.on("missingVideoFrames",function(){typeof t.options.onMissingVideoFrames=="function"&&t.options.onMissingVideoFrames.call(null)}),t.remuxController.on("missingAudioFrames",function(){typeof t.options.onMissingAudioFrames=="function"&&t.options.onMissingAudioFrames.call(null)}),t.clearBuffer&&t.remuxController.on("keyframePosition",function(a){t.kfPosition.push(a)}),typeof t.options.onKeyframePosition=="function"&&t.remuxController.on("keyframePosition",function(a){t.options.onKeyframePosition.call(null,a)}),t}return T(e,[{key:"initData",value:function(){this.lastCleaningTime=Date.now(),this.kfPosition=[],this.pendingUnits={},this.remainingData=new Uint8Array,this.startInterval()}},{key:"initBrowser",value:function(){typeof this.options.node=="string"&&this.options.node==""&&w("no video element were found to render, provide a valid video element"),this.node=typeof this.options.node=="string"?document.getElementById(this.options.node):this.options.node,this.mseReady=!1,this.setupMSE()}},{key:"createStream",value:function(){var t=this.feed.bind(this),i=this.destroy.bind(this);return this.stream=new U.Duplex({writableObjectMode:!0,read:function(o){},write:function(o,c,u){t(o),u()},final:function(o){i(),o()}}),this.stream}},{key:"setupMSE",value:function(){if(window.MediaSource=window.MediaSource||window.WebKitMediaSource||window.ManagedMediaSource,!window.MediaSource)throw"Oops! Browser does not support Media Source Extension or Managed Media Source (IOS 17+).";if(this.isMSESupported=!!window.MediaSource,this.mediaSource=new window.MediaSource,this.url=URL.createObjectURL(this.mediaSource),window.MediaSource===window.ManagedMediaSource)try{this.node.removeAttribute("src"),this.node.disableRemotePlayback=!0;var t=document.createElement("source");t.type="video/mp4",t.src=this.url,this.node.appendChild(t),this.node.load()}catch{this.node.src=this.url}else this.node.src=this.url;this.mseEnded=!1,this.mediaSource.addEventListener("sourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("sourceclose",this.onMSEClose.bind(this)),this.mediaSource.addEventListener("webkitsourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("webkitsourceclose",this.onMSEClose.bind(this))}},{key:"endMSE",value:function(){if(!this.mseEnded)try{this.mseEnded=!0,this.mediaSource.endOfStream()}catch{w("mediasource is not available to end")}}},{key:"feed",value:function(t){!t||!this.remuxController||(t.duration=t.duration?parseInt(t.duration):0,this.remuxController.feed(t))}},{key:"destroy",value:function(){if(this.stopInterval(),this.stream&&(this.remuxController.flush(),this.stream.push(null),this.stream=null),this.remuxController&&(this.remuxController.destroy(),this.remuxController=null),this.bufferControllers){for(var t in this.bufferControllers)this.bufferControllers[t].destroy();this.bufferControllers=null,this.endMSE()}this.node=!1,this.mseReady=!1,this.videoStarted=!1,this.mediaSource=null}},{key:"reset",value:function(){if(this.stopInterval(),this.isReset=!0,this.node.pause(),this.remuxController&&this.remuxController.reset(),this.bufferControllers){for(var t in this.bufferControllers)this.bufferControllers[t].destroy();this.bufferControllers=null,this.endMSE()}this.initData(),this.env=="browser"&&this.initBrowser(),C("JMuxer was reset")}},{key:"createBuffer",value:function(){if(!(!this.mseReady||!this.remuxController||!this.remuxController.isReady()||this.bufferControllers)){this.bufferControllers={};for(var t in this.remuxController.tracks){var i=this.remuxController.tracks[t];if(!e.isSupported("".concat(t,'/mp4; codecs="').concat(i.mp4track.codec,'"')))return w("Browser does not support codec: ".concat(t,'/mp4; codecs="').concat(i.mp4track.codec,'"')),typeof this.options.onUnsupportedCodec=="function"&&this.options.onUnsupportedCodec.call(null,i.mp4track.codec),!1;var a=this.mediaSource.addSourceBuffer("".concat(t,'/mp4; codecs="').concat(i.mp4track.codec,'"'));this.bufferControllers[t]=new je(a,t),this.bufferControllers[t].on("error",this.onBufferError.bind(this))}}}},{key:"startInterval",value:function(){var t=this;this.interval=setInterval(function(){t.options.flushingTime?t.applyAndClearBuffer():t.bufferControllers&&t.cancelDelay()},this.options.flushingTime||1e3)}},{key:"stopInterval",value:function(){this.interval&&clearInterval(this.interval)}},{key:"cancelDelay",value:function(){if(this.node.buffered&&this.node.buffered.length>0&&!this.node.seeking){var t=this.node.buffered.end(0);t-this.node.currentTime>this.options.maxDelay/1e3&&(C("delay"),this.node.paused&&this.node.play().catch(w),this.node.currentTime=t-.001)}}},{key:"releaseBuffer",value:function(){for(var t in this.bufferControllers)this.bufferControllers[t].doAppend()}},{key:"applyAndClearBuffer",value:function(){this.bufferControllers&&(this.releaseBuffer(),this.clearBuffer())}},{key:"getSafeClearOffsetOfBuffer",value:function(t){for(var i=this.options.mode==="audio"&&t||0,a,o=0;o<this.kfPosition.length&&!(this.kfPosition[o]>=t);o++)a=this.kfPosition[o];return a&&(this.kfPosition=this.kfPosition.filter(function(c){return c<a&&(i=c),c>=a})),i}},{key:"clearBuffer",value:function(){if(this.options.clearBuffer&&Date.now()-this.lastCleaningTime>1e4){for(var t in this.bufferControllers){var i=this.getSafeClearOffsetOfBuffer(this.node.currentTime);this.bufferControllers[t].initCleanup(i)}this.lastCleaningTime=Date.now()}}},{key:"onBuffer",value:function(t){this.options.readFpsFromTrack&&typeof t.fps<"u"&&this.options.fps!=t.fps&&(this.options.fps=t.fps,this.frameDuration=Math.ceil(1e3/t.fps),C("JMuxer changed FPS to ".concat(t.fps," from track data"))),this.env=="browser"?this.bufferControllers&&this.bufferControllers[t.type]&&this.bufferControllers[t.type].feed(t.payload):this.stream&&this.stream.push(t.payload),this.options.onData&&this.options.onData(t.payload),this.options.flushingTime===0&&this.applyAndClearBuffer()}},{key:"onMSEOpen",value:function(){this.mseReady=!0,URL.revokeObjectURL(this.url),typeof this.options.onReady=="function"&&this.options.onReady.call(null,this.isReset)}},{key:"onMSEClose",value:function(){this.mseReady=!1,this.videoStarted=!1}},{key:"onBufferError",value:function(t){if(t.name=="QuotaExceeded"){C("JMuxer cleaning ".concat(t.type," buffer due to QuotaExceeded error")),this.bufferControllers[t.type].initCleanup(this.node.currentTime);return}else t.name=="InvalidStateError"?(C("JMuxer is reseting due to InvalidStateError"),this.reset()):this.endMSE();typeof this.options.onError=="function"&&this.options.onError.call(null,t)}}],[{key:"isSupported",value:function(t){return window.MediaSource&&window.MediaSource.isTypeSupported(t)}}]),e})(pe);return Ae}))})(Fe)),Fe.exports}var rt=tt();const nt=Oe(rt),it=400,Ee=50;function st({deviceId:g,className:ae,onFallback:U,fallbackTimeout:R=5e3,enableControl:b=!1,onTapSuccess:H,onTapError:z,onSwipeSuccess:k,onSwipeError:S,onStreamReady:T}){const y=p.useRef(null),j=p.useRef(null),F=p.useRef(null),N=p.useRef(g),[V,Q]=p.useState("connecting"),[me,ee]=p.useState(null),se=p.useRef(null),W=p.useRef(!1),ye=p.useRef(new Uint8Array(0)),[xe,J]=p.useState([]),G=p.useRef(!1),O=p.useRef(null),[B,te]=p.useState(null),oe=p.useRef(null),$=p.useRef(null),re=p.useRef(0),ce=p.useRef(null),C=p.useRef(null),[w,pe]=p.useState(null),le=p.useRef(0),ve=p.useRef(0),be=p.useRef(0),m=p.useRef(0),X=p.useRef(0),Y=p.useRef(0),q=3,ne=1e3,ie=p.useRef(U),ke=p.useRef(R),L=p.useRef(T),K=(n,s,e)=>{const r=e.getBoundingClientRect(),t=r.width,i=r.height,a=e.videoWidth,o=e.videoHeight;if(a===0||o===0)return console.warn("[ScrcpyPlayer] Video dimensions not available yet"),null;const c=a/o,u=t/i;let d,h,f,x;u>c?(h=i,d=c*i,f=(t-d)/2,x=0):(d=t,h=t/c,f=0,x=(i-h)/2);const v=n-f,_=s-x;if(v<0||v>d||_<0||_>h)return console.warn("[ScrcpyPlayer] Click outside video area (in letterbox)"),null;const I=Math.round(v/d*a),A=Math.round(_/h*o);return console.log(`[ScrcpyPlayer] Coordinate transform:
|
|
5
|
+
Click: (${n}, ${s})
|
|
6
|
+
Display: ${t}x${i}
|
|
7
|
+
Video: ${a}x${o}
|
|
8
|
+
Rendered: ${d}x${h} at offset (${f}, ${x})
|
|
9
|
+
Device: (${I}, ${A})`),{x:I,y:A}},M=async n=>{if(!b||!y.current||V!=="connected")return;G.current=!0,O.current={x:n.clientX,y:n.clientY,time:Date.now()};const s=y.current.getBoundingClientRect(),e=n.clientX-s.left,r=n.clientY-s.top,t=K(e,r,y.current);if(!t||!w)return;const i=y.current.videoWidth,a=y.current.videoHeight,o=w.width/i,c=w.height/a,u=Math.round(t.x*o),d=Math.round(t.y*c);try{await He(u,d,g),console.log(`[Touch] DOWN: (${u}, ${d}) for device ${g}`)}catch(h){console.error("[Touch] DOWN failed:",h)}},Ce=n=>{if(!G.current||!O.current)return;te({id:Date.now(),startX:O.current.x,startY:O.current.y,endX:n.clientX,endY:n.clientY});const s=y.current?.getBoundingClientRect();if(!s||!y.current||!w)return;const e=n.clientX-s.left,r=n.clientY-s.top,t=K(e,r,y.current);if(!t)return;const i=y.current.videoWidth,a=y.current.videoHeight,o=w.width/i,c=w.height/a,u=Math.round(t.x*o),d=Math.round(t.y*c),h=Date.now();h-re.current>=Ee?(re.current=h,Te(u,d,g).catch(f=>{console.error("[Touch] MOVE failed:",f)})):(ce.current={x:u,y:d},C.current&&clearTimeout(C.current),C.current=setTimeout(()=>{if(ce.current){const{x:f,y:x}=ce.current;re.current=Date.now(),Te(f,x,g).catch(v=>{console.error("[Touch] MOVE (throttled) failed:",v)}),ce.current=null}},Ee-(h-re.current)))},De=async n=>{if(!G.current||!O.current)return;const s=n.clientX-O.current.x,e=n.clientY-O.current.y,r=Date.now()-O.current.time;if(te(null),G.current=!1,C.current&&(clearTimeout(C.current),C.current=null),ce.current=null,Math.sqrt(s*s+e*e)<10&&r<200){Ae(n),O.current=null;return}const i=y.current?.getBoundingClientRect();if(!i||!y.current||!w){O.current=null;return}const a=n.clientX-i.left,o=n.clientY-i.top,c=K(a,o,y.current);if(!c){O.current=null;return}const u=y.current.videoWidth,d=y.current.videoHeight,h=w.width/u,f=w.height/d,x=Math.round(c.x*h),v=Math.round(c.y*f);try{await Ue(x,v,g),console.log(`[Touch] UP: (${x}, ${v}) for device ${g}`),H?.()}catch(_){console.error("[Touch] UP failed:",_),z?.(String(_))}O.current=null},je=async n=>{if(!b||!y.current||V!=="connected")return;const s=Date.now(),e=n.deltaY;$.current||($.current={deltaY:0,lastTime:s,mouseX:n.clientX,mouseY:n.clientY}),$.current.deltaY+=e,$.current.lastTime=s;const r=.3;$.current.mouseX=Math.round($.current.mouseX*(1-r)+n.clientX*r),$.current.mouseY=Math.round($.current.mouseY*(1-r)+n.clientY*r),oe.current&&clearTimeout(oe.current),oe.current=setTimeout(async()=>{if(!$.current||!y.current)return;const t=$.current;if($.current=null,t.mouseX===void 0||t.mouseY===void 0)return;const i=y.current.getBoundingClientRect(),a=t.mouseX,o=t.mouseY,c=Math.abs(t.deltaY),u=Math.min(Math.max(300,c),800),d=K(a-i.left,o-i.top,y.current);if(!d||!w){console.warn("[ScrcpyPlayer] Cannot execute scroll: coordinate transformation failed");return}const h=y.current.videoWidth,f=y.current.videoHeight,x=w.width/h,v=w.height/f,_=Math.round(d.x*x),I=Math.round(d.y*v);let A,E;t.deltaY>0?(A=I,E=I-c):(A=I,E=I+c);const P=Math.abs(E-A),fe=Math.max(P/w.height*i.height,20),ue=Math.min(Math.max(u*.8,200),800),Z=document.createElement("div");Z.style.cssText=`
|
|
10
|
+
position: fixed;
|
|
11
|
+
left: ${a}px;
|
|
12
|
+
top: ${o}px;
|
|
13
|
+
width: 20px;
|
|
14
|
+
height: 20px;
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
z-index: 50;
|
|
17
|
+
transform: translateX(-50%) translateY(-50%);
|
|
18
|
+
background: radial-gradient(circle,
|
|
19
|
+
rgba(59, 130, 246, 0.8) 0%,
|
|
20
|
+
rgba(59, 130, 246, 0.4) 30%,
|
|
21
|
+
rgba(59, 130, 246, 0.2) 60%,
|
|
22
|
+
rgba(59, 130, 246, 0) 100%);
|
|
23
|
+
border-radius: 50%;
|
|
24
|
+
box-shadow: 0 0 10px rgba(59, 130, 246, 0.6);
|
|
25
|
+
`;const he=Date.now(),D=setInterval(()=>{const de=Date.now()-he,ge=Math.min(de/ue,1),we=t.deltaY>0?o-fe*ge:o+fe*ge;Z.style.top=we+"px",ge>=1&&clearInterval(D)},16);document.body.appendChild(Z),setTimeout(()=>{Z.parentNode&&Z.parentNode.removeChild(Z),clearInterval(D)},ue);try{const de=await $e(_,A,_,E,u,g);de.success?k?.():S?.(de.error||"Scroll failed")}catch(de){S?.(String(de))}},it)},Ae=async n=>{if(!b||!y.current||V!=="connected"||y.current.videoWidth===0||y.current.videoHeight===0||!w)return;const s=y.current.getBoundingClientRect(),e=n.clientX-s.left,r=n.clientY-s.top,t=K(e,r,y.current);if(!t)return;const i=y.current.videoWidth,a=y.current.videoHeight,o=w.width/i,c=w.height/a,u=Math.round(t.x*o),d=Math.round(t.y*c),h=Date.now();J(f=>[...f,{id:h,x:n.clientX,y:n.clientY}]),setTimeout(()=>{J(f=>f.filter(x=>x.id!==h))},500);try{const f=await ze(u,d,g);f.success?H?.():z?.(f.error||"Unknown error")}catch(f){z?.(String(f))}};return p.useEffect(()=>{ie.current=U,ke.current=R,L.current=T},[U,R,T]),p.useEffect(()=>{(async()=>{try{const s=await Ne(g);s.success&&(pe({width:s.width,height:s.height}),console.log(`[ScrcpyPlayer] Device actual resolution: ${s.width}x${s.height} for device ${g}`))}catch(s){console.error("[ScrcpyPlayer] Failed to fetch device resolution:",s)}})()},[g]),p.useEffect(()=>{N.current=g;let n=null,s=null;const e=async()=>{if(!y.current)return;console.log("[ScrcpyPlayer] connect() called"),m.current=Date.now(),Q("connecting"),ee(null);const r=t=>{const i=[];for(let a=0;a<t.length-3;a++)t[a]===0&&t[a+1]===0&&(t[a+2]===0&&t[a+3]===1?(i.push(a),a+=3):t[a+2]===1&&(i.push(a),a+=2));return i};if(F.current){console.log("[ScrcpyPlayer] Closing existing WebSocket");try{F.current.onclose=null,F.current.onerror=null,F.current.onmessage=null,F.current.close()}catch(t){console.error("[ScrcpyPlayer] Error closing old WebSocket:",t)}F.current=null}if(j.current){console.log("[ScrcpyPlayer] Destroying old jMuxer instance");try{j.current.destroy()}catch(t){console.error("[ScrcpyPlayer] Error destroying old jMuxer:",t)}j.current=null}ye.current=new Uint8Array(0),console.log("[ScrcpyPlayer] Cleared NAL buffer"),await new Promise(t=>setTimeout(t,300));try{console.log("[ScrcpyPlayer] Creating new jMuxer instance (after cleanup delay)"),j.current=new nt({node:y.current,mode:"video",flushingTime:0,fps:30,debug:!1,clearBuffer:!0,onError:o=>{if(console.error("[jMuxer] Decoder error:",o),o.name==="InvalidStateError"&&o.error==="buffer error"){const c=Date.now(),u=c-Y.current;if(u<ne){console.warn(`[jMuxer] Reset debounced (${u}ms since last reset)`);return}if(Y.current=c,X.current++,console.warn(`[jMuxer] ⚠️ Buffer error detected (attempt ${X.current}/${q})`),X.current<=q&&j.current)try{console.log("[jMuxer] Attempting lightweight reset()..."),j.current.reset(),console.log("[jMuxer] ✓ Reset successful");return}catch(h){console.error("[jMuxer] Reset failed:",h)}console.log("[jMuxer] Reset successful, reconnecting to get fresh initialization data..."),be.current=c;const d=t;s&&setTimeout(()=>{N.current===d?s&&s():console.log(`[jMuxer] Device changed (${d} -> ${N.current}), skip reconnect`)},100)}},onMissingVideoFrames:o=>{console.warn("[jMuxer] Missing video frames detected:",o)}});const t=N.current,i=`ws://localhost:8000/api/video/stream?device_id=${encodeURIComponent(t)}`,a=new WebSocket(i);F.current=a,a.binaryType="arraybuffer",a.onopen=()=>{console.log(`[ScrcpyPlayer] WebSocket connected for device ${t}`),Q("connected"),X.current=0,Y.current=0,L.current&&L.current({close:()=>{a.close()}}),se.current=setTimeout(()=>{W.current||(console.log("[ScrcpyPlayer] No data received within timeout, triggering fallback"),Q("error"),ee("Video stream timeout"),a.close(),ie.current&&ie.current())},ke.current)},a.onmessage=o=>{if(typeof o.data=="string"){try{const c=JSON.parse(o.data);console.error("[ScrcpyPlayer] Server error:",c),ee(c.error||"Unknown error"),Q("error"),ie.current&&!W.current&&ie.current()}catch{console.error("[ScrcpyPlayer] Received non-JSON string:",o.data)}return}if(!W.current){const c=new Uint8Array(o.data),u=Array.from(c.slice(0,20)).map(f=>f.toString(16).padStart(2,"0")).join(" ");console.log(`[ScrcpyPlayer] First message (${c.length} bytes): ${u}...`);const h=r(c).map(f=>c[f+(c[f+2]===1?3:4)]&31);console.log(`[ScrcpyPlayer] First message NAL types: ${h.join(", ")} (7=SPS, 8=PPS, 5=IDR)`),(!h.includes(7)||!h.includes(8))&&console.warn("[ScrcpyPlayer] WARNING: First message missing SPS/PPS! This will cause black screen.")}W.current||(W.current=!0,console.log("[ScrcpyPlayer] First video data received, canceling fallback timer"),se.current&&(clearTimeout(se.current),se.current=null));try{if(j.current&&o.data.byteLength>0){const c=new Uint8Array(o.data);c[0]===0&&c[1]===0&&(c[2]===0||c[2]===1)||console.warn(`[ScrcpyPlayer] Data missing start code: first bytes = ${Array.from(c.slice(0,8)).map(f=>f.toString(16).padStart(2,"0")).join(" ")}`),j.current.feed({video:c}),le.current++;const d=Date.now(),h=d-ve.current;if(h>5e3){const f=le.current/h*1e3,x=y.current,v=x&&x.buffered.length>0?x.buffered.end(0)-x.currentTime:0;console.log(`[ScrcpyPlayer] Stats: ${f.toFixed(1)} fps, buffer: ${v.toFixed(2)}s`),v>2&&console.warn(`[ScrcpyPlayer] ⚠ High latency detected: ${v.toFixed(2)}s buffer`),le.current=0,ve.current=d}}}catch(c){console.error("[ScrcpyPlayer] Feed error:",c)}},a.onerror=o=>{console.error("[ScrcpyPlayer] WebSocket error:",o),ee("Connection error"),Q("error")},a.onclose=()=>{console.log("[ScrcpyPlayer] WebSocket closed"),Q("disconnected"),L.current&&L.current(null);const o=t;n=setTimeout(()=>{N.current===o?(console.log("[ScrcpyPlayer] Attempting to reconnect..."),e()):console.log(`[ScrcpyPlayer] Device changed (${o} -> ${N.current}), skip reconnect`)},3e3)}}catch(t){console.error("[ScrcpyPlayer] Initialization error:",t),ee("Initialization failed"),Q("error")}};return s=e,e(),()=>{if(n&&clearTimeout(n),se.current&&(clearTimeout(se.current),se.current=null),F.current&&(F.current.close(),F.current=null),C.current&&(clearTimeout(C.current),C.current=null),j.current){try{j.current.destroy()}catch(r){console.error("[ScrcpyPlayer] Cleanup error:",r)}j.current=null}}},[g]),l.jsxs("div",{className:`relative w-full h-full flex items-center justify-center ${ae||""}`,children:[l.jsx("video",{ref:y,autoPlay:!0,muted:!0,playsInline:!0,onError:n=>{const e=n.currentTarget.error;e&&console.error("[Video Element] Error occurred:",{code:e.code,message:e.message,MEDIA_ERR_ABORTED:e.code===1,MEDIA_ERR_NETWORK:e.code===2,MEDIA_ERR_DECODE:e.code===3,MEDIA_ERR_SRC_NOT_SUPPORTED:e.code===4})},onMouseDown:M,onMouseMove:Ce,onMouseUp:De,onMouseLeave:async()=>{if(G.current&&y.current&&w){if(O.current){const n=y.current.getBoundingClientRect(),s=K(O.current.x-n.left,O.current.y-n.top,y.current);if(s){const e=w.width/y.current.videoWidth,r=w.height/y.current.videoHeight,t=Math.round(s.x*e),i=Math.round(s.y*r);try{await Ue(t,i,g),console.log(`[Touch] UP (mouse leave) for device ${g}`)}catch(a){console.error("[Touch] UP (mouse leave) failed:",a)}}}G.current=!1,te(null),O.current=null}},onWheel:je,className:`max-w-full max-h-full object-contain ${b?"cursor-pointer":""}`,style:{backgroundColor:"#000"}}),b&&B&&l.jsxs("svg",{className:"fixed inset-0 pointer-events-none z-40",children:[l.jsx("line",{x1:B.startX,y1:B.startY,x2:B.endX,y2:B.endY,stroke:"rgba(59, 130, 246, 0.8)",strokeWidth:"3",strokeLinecap:"round"}),l.jsx("circle",{cx:B.startX,cy:B.startY,r:"6",fill:"rgba(59, 130, 246, 0.8)"}),l.jsx("circle",{cx:B.endX,cy:B.endY,r:"6",fill:"rgba(239, 68, 68, 0.8)"})]}),b&&xe.map(n=>l.jsx("div",{className:"fixed pointer-events-none z-50",style:{left:n.x,top:n.y},children:l.jsx("div",{className:"ripple-circle"})},n.id)),V!=="connected"&&l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-black/50 backdrop-blur-sm",children:l.jsxs("div",{className:"text-center text-white",children:[V==="connecting"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"w-8 h-8 border-4 border-white border-t-transparent rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"正在连接..."})]}),V==="disconnected"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"w-8 h-8 border-4 border-yellow-500 border-t-transparent rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"连接断开,正在重连..."})]}),V==="error"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"text-red-500 text-xl mb-2",children:"✗"}),l.jsx("p",{className:"text-red-400",children:"连接失败"}),me&&l.jsx("p",{className:"text-sm text-gray-400 mt-1",children:me})]})]})})]})}function at({deviceId:g,deviceName:ae,config:U}){const[R,b]=p.useState([]),[H,z]=p.useState(""),[k,S]=p.useState(!1),[T,y]=p.useState(null),[j,F]=p.useState(!1),[N,V]=p.useState(null),[Q,me]=p.useState(!0),[ee,se]=p.useState(!1),[W,ye]=p.useState("auto"),[xe,J]=p.useState(null),[G,O]=p.useState(()=>{try{const m=localStorage.getItem("display-tabs-visible");return m!==null?JSON.parse(m):!0}catch(m){return console.warn("Failed to load tabs visibility state:",m),!0}});p.useEffect(()=>{localStorage.setItem("display-tabs-visible",JSON.stringify(G))},[G]);const B=p.useRef(null),te=p.useRef(null),oe=p.useRef(null),$=p.useRef(!1),re=p.useCallback(async()=>{if(!U){console.warn("[DevicePanel] config is required for handleInit");return}try{await Ye({model_config:{base_url:U.baseUrl||void 0,api_key:U.apiKey||void 0,model_name:U.modelName||void 0},agent_config:{device_id:g}}),F(!0),y(null)}catch(m){const X=m instanceof Error?m.message:"初始化失败,请检查配置";y(X)}},[g,U]),ce=p.useCallback(async()=>{const m=H.trim();if(!m||k)return;j||await re();const X={id:Date.now().toString(),role:"user",content:m,timestamp:new Date};b(L=>[...L,X]),z(""),S(!0),y(null);const Y=[],q=[],ne=(Date.now()+1).toString(),ie={id:ne,role:"agent",content:"",timestamp:new Date,thinking:[],actions:[],isStreaming:!0};b(L=>[...L,ie]);const ke=Ve(X.content,g,L=>{Y.push(L.thinking),q.push(L.action),b(K=>K.map(M=>M.id===ne?{...M,thinking:[...Y],actions:[...q],steps:L.step}:M))},L=>{b(K=>K.map(M=>M.id===ne?{...M,content:L.message,success:L.success,isStreaming:!1}:M)),S(!1),B.current=null},L=>{b(K=>K.map(M=>M.id===ne?{...M,content:`错误: ${L.message}`,success:!1,isStreaming:!1}:M)),S(!1),y(L.message),B.current=null});B.current=ke},[H,k,j,g,re]),C=p.useCallback(async()=>{B.current&&B.current.close(),b([]),S(!1),y(null),B.current=null,await We(g)},[g]),w=()=>{oe.current?.scrollIntoView({behavior:"smooth"})};p.useEffect(()=>{w()},[R]),p.useEffect(()=>()=>{console.log(`[DevicePanel] 设备 ${g} 卸载,清理资源`),B.current&&(B.current.close(),B.current=null),te.current&&(te.current.close(),te.current=null)},[g]),p.useEffect(()=>{if(!g||!(W==="screenshot"||W==="auto"&&ee))return;const X=async()=>{if(!$.current){$.current=!0;try{const q=await Ne(g);q.success&&V(q)}catch(q){console.error("Failed to fetch screenshot:",q)}finally{$.current=!1}}};X();const Y=setInterval(X,500);return()=>clearInterval(Y)},[g,ee,W]);const pe=m=>{m.key==="Enter"&&(m.metaKey||m.ctrlKey)&&(m.preventDefault(),ce())},le=p.useCallback(m=>{te.current=m},[]),ve=p.useCallback(()=>{se(!0),me(!1)},[]),be=()=>{O(!G)};return l.jsxs("div",{className:"flex-1 flex gap-4 p-4 items-stretch justify-center min-h-0",children:[l.jsxs("div",{className:"flex flex-col w-full max-w-2xl min-h-0 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-lg bg-white dark:bg-gray-800",children:[l.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 rounded-t-2xl",children:[l.jsxs("div",{children:[l.jsx("h2",{className:"text-lg font-semibold",children:ae}),l.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400",children:g})]}),l.jsxs("div",{className:"flex gap-2",children:[j?l.jsx("span",{className:"px-3 py-1 bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full text-sm",children:"已初始化"}):l.jsx("button",{onClick:re,className:"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm",children:"初始化设备"}),l.jsx("button",{onClick:C,className:"px-4 py-2 bg-gray-200 dark:bg-gray-700 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors text-sm",children:"重置"})]})]}),T&&l.jsx("div",{className:"mx-4 mt-4 p-3 bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-200 rounded-lg text-sm",children:T}),l.jsxs("div",{className:"flex-1 overflow-y-auto p-4 space-y-4 min-h-0",children:[R.length===0?l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400 mt-8",children:[l.jsx("p",{className:"text-lg",children:"设备已选择"}),l.jsx("p",{className:"text-sm mt-2",children:"输入任务描述,让 AI 帮你操作手机"})]}):null,R.map(m=>l.jsx("div",{className:`flex ${m.role==="user"?"justify-end":"justify-start"}`,children:m.role==="agent"?l.jsxs("div",{className:"max-w-[80%] space-y-2",children:[m.thinking?.map((X,Y)=>l.jsxs("div",{className:"bg-gray-100 dark:bg-gray-700 rounded-2xl px-4 py-3 border-l-4 border-blue-500",children:[l.jsxs("div",{className:"text-xs text-gray-500 dark:text-gray-400 mb-1",children:["💭 步骤 ",Y+1," - 思考过程"]}),l.jsx("p",{className:"text-sm whitespace-pre-wrap",children:X}),m.actions?.[Y]&&l.jsxs("details",{className:"mt-2 text-xs",children:[l.jsx("summary",{className:"cursor-pointer text-blue-500 hover:text-blue-600",children:"查看动作"}),l.jsx("pre",{className:"mt-1 p-2 bg-gray-800 text-gray-200 rounded overflow-x-auto text-xs",children:JSON.stringify(m.actions[Y],null,2)})]})]},Y)),m.content&&l.jsxs("div",{className:`rounded-2xl px-4 py-3 ${m.success===!1?"bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200":"bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200"}`,children:[l.jsx("p",{className:"whitespace-pre-wrap",children:m.content}),m.steps!==void 0&&l.jsxs("p",{className:"text-xs mt-2 opacity-70",children:["总步数: ",m.steps]})]}),m.isStreaming&&l.jsx("div",{className:"text-sm text-gray-500 dark:text-gray-400 animate-pulse",children:"正在执行..."})]}):l.jsx("div",{className:"max-w-[70%] rounded-2xl px-4 py-3 bg-blue-500 text-white",children:l.jsx("p",{className:"whitespace-pre-wrap",children:m.content})})},m.id)),l.jsx("div",{ref:oe})]}),l.jsx("div",{className:"p-4 border-t border-gray-200 dark:border-gray-700 rounded-b-2xl",children:l.jsxs("div",{className:"flex gap-2",children:[l.jsx("input",{type:"text",value:H,onChange:m=>z(m.target.value),onKeyDown:pe,placeholder:j?"输入任务描述...":"请先初始化设备",disabled:k,className:"flex-1 px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"}),l.jsx("button",{onClick:ce,disabled:k||!H.trim(),className:"px-6 py-3 bg-blue-500 text-white rounded-xl hover:bg-blue-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:"发送"})]})})]}),l.jsxs("div",{className:"w-full max-w-xs min-h-0 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-lg bg-gray-900 overflow-hidden relative",children:[!G&&l.jsx("button",{onClick:be,className:"absolute top-2 right-2 z-10 w-8 h-8 bg-gray-500 hover:bg-blue-600 text-white rounded-full shadow-lg transition-all duration-300 flex items-center justify-center opacity-20 hover:opacity-100 cursor-pointer",title:"显示选项卡",children:l.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"})})}),l.jsxs("div",{className:`${G?"absolute top-2 right-2":"hidden"} z-10 flex gap-1 bg-black/70 rounded-lg p-1`,children:[l.jsx("button",{onClick:()=>ye("auto"),className:`px-3 py-1 text-xs rounded transition-colors ${W==="auto"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"自动"}),l.jsx("button",{onClick:()=>ye("video"),className:`px-3 py-1 text-xs rounded transition-colors ${W==="video"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"视频流"}),l.jsx("button",{onClick:()=>ye("screenshot"),className:`px-3 py-1 text-xs rounded transition-colors ${W==="screenshot"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"截图"}),l.jsx("button",{onClick:be,className:"ml-1 px-2 py-1 text-xs rounded transition-colors bg-gray-600 text-gray-300 hover:bg-gray-500",title:"隐藏选项卡",children:l.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),W==="video"||W==="auto"&&Q&&!ee?l.jsxs(l.Fragment,{children:[xe&&l.jsx("div",{className:"absolute top-14 right-2 z-20 px-3 py-2 bg-blue-500 text-white text-sm rounded-lg shadow-lg",children:xe}),l.jsx(st,{deviceId:g,className:"w-full h-full",enableControl:!0,onFallback:ve,onTapSuccess:()=>{J("Tap executed"),setTimeout(()=>J(null),2e3)},onTapError:m=>{J(`Tap failed: ${m}`),setTimeout(()=>J(null),3e3)},onSwipeSuccess:()=>{J("Swipe executed"),setTimeout(()=>J(null),2e3)},onSwipeError:m=>{J(`Swipe failed: ${m}`),setTimeout(()=>J(null),3e3)},onStreamReady:le,fallbackTimeout:1e5})]}):l.jsx("div",{className:"w-full h-full flex items-center justify-center bg-gray-900 min-h-0",children:N&&N.success?l.jsxs("div",{className:"relative w-full h-full flex items-center justify-center min-h-0",children:[l.jsx("img",{src:`data:image/png;base64,${N.image}`,alt:"Device Screenshot",className:"max-w-full max-h-full object-contain",style:{width:N.width>N.height?"100%":"auto",height:N.width>N.height?"auto":"100%"}}),N.is_sensitive&&l.jsx("div",{className:"absolute top-12 right-2 px-2 py-1 bg-yellow-500 text-white text-xs rounded",children:"敏感内容"}),l.jsxs("div",{className:"absolute bottom-2 left-2 px-2 py-1 bg-blue-500 text-white text-xs rounded",children:["截图模式 (0.5s 刷新)",W==="auto"&&ee&&" - 视频流不可用"]})]}):N?.error?l.jsxs("div",{className:"text-center text-red-500 dark:text-red-400",children:[l.jsx("p",{className:"mb-2",children:"截图失败"}),l.jsx("p",{className:"text-xs",children:N.error})]}):l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[l.jsx("div",{className:"w-8 h-8 border-4 border-gray-300 border-t-blue-500 rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"加载中..."})]})})]})]})}function ct(){const[g,ae]=p.useState([]),[U,R]=p.useState(""),[b,H]=p.useState({baseUrl:"",apiKey:"",modelName:""}),[z,k]=p.useState(!1);return p.useEffect(()=>{const S=async()=>{try{const y=await Ge();ae(y.devices),y.devices.length>0&&!U&&R(y.devices[0].id),U&&!y.devices.find(j=>j.id===U)&&R(y.devices[0]?.id||"")}catch(y){console.error("Failed to load devices:",y)}};S();const T=setInterval(S,3e3);return()=>clearInterval(T)},[U]),l.jsxs("div",{className:"h-full flex relative min-h-0",children:[z&&l.jsx("div",{className:"absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50",children:l.jsxs("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-2xl w-96 shadow-xl border border-gray-200 dark:border-gray-700",children:[l.jsx("h2",{className:"text-xl font-bold mb-4 text-gray-900 dark:text-gray-100",children:"Agent 配置"}),l.jsxs("div",{className:"space-y-4",children:[l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"Base URL"}),l.jsx("input",{type:"text",value:b.baseUrl,onChange:S=>H({...b,baseUrl:S.target.value}),placeholder:"留空使用默认值",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"API Key"}),l.jsx("input",{type:"password",value:b.apiKey,onChange:S=>H({...b,apiKey:S.target.value}),placeholder:"留空使用默认值",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"Model Name"}),l.jsx("input",{type:"text",value:b.modelName,onChange:S=>H({...b,modelName:S.target.value}),placeholder:"留空使用默认值",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[l.jsx("button",{onClick:()=>k(!1),className:"px-4 py-2 text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200",children:"取消"}),l.jsx("button",{onClick:()=>k(!1),className:"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors",children:"确认配置"})]})]})]})}),l.jsx(Je,{devices:g,currentDeviceId:U,onSelectDevice:R,onOpenConfig:()=>k(!0)}),l.jsx("div",{className:"flex-1 relative flex items-stretch justify-center min-h-0",children:g.length===0?l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-50 dark:bg-gray-900",children:l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[l.jsx("svg",{className:"w-16 h-16 mx-auto mb-4 opacity-50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),l.jsx("h3",{className:"text-lg font-medium mb-2",children:"欢迎使用 AutoGLM Chat"}),l.jsx("p",{className:"text-sm",children:"未检测到设备,请连接 ADB 设备"})]})}):g.map(S=>l.jsx("div",{className:`w-full h-full flex items-stretch justify-center min-h-0 ${S.id===U?"":"hidden"}`,children:l.jsx(at,{deviceId:S.id,deviceName:S.model,config:b,isVisible:S.id===U})},S.id))})]})}export{ct as component};
|