@byteplus/react-native-live-pull 1.1.2-rc.1 → 1.1.3-rc.0

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.
@@ -1,5 +1,6 @@
1
1
  package com.volcengine.velive.rn.pull.pictureInpicture;
2
2
 
3
+ import android.animation.ValueAnimator;
3
4
  import android.app.Service;
4
5
  import android.content.BroadcastReceiver;
5
6
  import android.content.Context;
@@ -24,14 +25,19 @@ import androidx.annotation.Nullable;
24
25
  import com.volcengine.velive.rn.pull.R;
25
26
 
26
27
  public class FloatingWindowService extends Service {
28
+ private static final int MARGIN_TOP = 40;
29
+ private static final int MARGIN_BOTTOM = 40;
30
+ private static final int MARGIN_LEFT = 20;
31
+ private static final int MARGIN_RIGHT = 20;
27
32
  private static final String TAG = FloatingWindowService.class.getSimpleName();
28
- private static final int LONGER_SIDE_MAX_LEN = 1000;
29
33
 
30
34
  private WindowManager mWindowManager;
31
35
  private WindowManager.LayoutParams mLayoutParams;
32
36
  private SurfaceView mSurfaceView;
33
37
  private View mSmallWindowView;
34
38
  private ActivityLaunchReceiver mActivityLaunchReceiver;
39
+ private FloatingOnTouchListener
40
+ mFloatingOnTouchListener; // Store the listener instance
35
41
 
36
42
  public static final String ACTION_STOP_PIP_SERVICE =
37
43
  "com.volcengine.velive.rn.pull.STOP_PIP_SERVICE";
@@ -97,37 +103,68 @@ public class FloatingWindowService extends Service {
97
103
  int screenWidth = displayMetrics.widthPixels;
98
104
  int screenHeight = displayMetrics.heightPixels;
99
105
 
100
- // Calculate the minimum screen dimension
101
- int minScreenDim = Math.min(screenWidth, screenHeight);
106
+ int drawableWidth = screenWidth - MARGIN_LEFT - MARGIN_RIGHT;
107
+ int drawableHeight = screenHeight - MARGIN_TOP - MARGIN_BOTTOM;
102
108
 
103
- // Determine the maximum length based on the smaller of 1000 and
104
- // minScreenDim
105
- int maxLen = Math.min(LONGER_SIDE_MAX_LEN, minScreenDim);
109
+ boolean isPortrait = screenHeight > screenWidth;
110
+
111
+ int maxLen;
112
+ if (isPortrait) {
113
+ // 竖屏时,宽度不能超过 drawableWidth
114
+ maxLen = drawableWidth;
115
+ } else {
116
+ // 横屏时,高度不能超过 drawableHeight
117
+ maxLen = drawableHeight;
118
+ }
106
119
 
107
- // Limit the floating window size to prevent it from being too large or too
108
- // small, control the longer side to maxLen, scale the shorter
109
- // side proportionally
110
120
  int width, height;
111
- if (aspectRatio >= 1) {
112
- height = (int)(maxLen / aspectRatio);
121
+ if (aspectRatio >= 1) { // 宽大于等于高 (横向视频或方形)
113
122
  width = maxLen;
114
- } else {
115
- width = (int)(maxLen * aspectRatio);
123
+ height = (int)(width / aspectRatio);
124
+ if (isPortrait && width > drawableWidth) {
125
+ width = drawableWidth;
126
+ height = (int)(width / aspectRatio);
127
+ }
128
+ if (!isPortrait &&
129
+ height > drawableHeight) { // 横屏下,若计算出的高度超出drawableHeight
130
+ height = drawableHeight;
131
+ width = (int)(height * aspectRatio);
132
+ }
133
+ } else { // 高大于宽 (竖向视频)
116
134
  height = maxLen;
135
+ width = (int)(height * aspectRatio);
136
+ if (!isPortrait && height > drawableHeight) {
137
+ height = drawableHeight;
138
+ width = (int)(height * aspectRatio);
139
+ }
140
+ if (isPortrait &&
141
+ width > drawableWidth) { // 竖屏下,若计算出的宽度超出drawableWidth
142
+ width = drawableWidth;
143
+ height = (int)(width / aspectRatio);
144
+ }
117
145
  }
118
- mLayoutParams.width = width;
119
- mLayoutParams.height = height;
120
146
 
121
- // Initial position of the floating window
122
- mLayoutParams.x = x;
123
- mLayoutParams.y = y;
147
+ // Ensure dimensions are positive
148
+ mLayoutParams.width = Math.max(1, width);
149
+ mLayoutParams.height = Math.max(1, height);
150
+
151
+ // Initial position of the floating window, respecting margins
152
+ mLayoutParams.x =
153
+ Math.max(MARGIN_LEFT,
154
+ Math.min(x, screenWidth - mLayoutParams.width - MARGIN_RIGHT));
155
+ mLayoutParams.y =
156
+ Math.max(MARGIN_TOP, Math.min(y, screenHeight - mLayoutParams.height -
157
+ MARGIN_BOTTOM));
124
158
 
125
159
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
126
160
  if (Settings.canDrawOverlays(this)) {
127
161
  LayoutInflater layoutInflater = LayoutInflater.from(this);
128
162
  mSmallWindowView =
129
163
  layoutInflater.inflate(R.layout.floating_window_layout, null);
130
- mSmallWindowView.setOnTouchListener(new FloatingOnTouchListener());
164
+ this.mFloatingOnTouchListener =
165
+ new FloatingOnTouchListener(); // Create and store the instance
166
+ mSmallWindowView.setOnTouchListener(
167
+ this.mFloatingOnTouchListener); // Set the stored instance
131
168
  mWindowManager.addView(mSmallWindowView, mLayoutParams);
132
169
  mSurfaceView = mSmallWindowView.findViewById(R.id.surface_view);
133
170
  mSmallWindowView.findViewById(R.id.surface_close_btn)
@@ -204,6 +241,8 @@ public class FloatingWindowService extends Service {
204
241
  }
205
242
 
206
243
  private class FloatingOnTouchListener implements View.OnTouchListener {
244
+ private boolean isDoubleClickAnimating =
245
+ false; // Flag to indicate if double-click animation is running
207
246
  private final int touchSlop =
208
247
  ViewConfiguration
209
248
  .get(FloatingWindowService.this.getApplicationContext())
@@ -212,36 +251,289 @@ public class FloatingWindowService extends Service {
212
251
  private int x, y;
213
252
  private boolean isDragging;
214
253
 
254
+ private static final int MODE_NONE = 0;
255
+ private static final int MODE_DRAG = 1;
256
+ private static final int MODE_ZOOM = 2;
257
+ private int mode = MODE_NONE;
258
+
259
+ private float oldDist = 1f;
260
+ private float initialAspectRatio;
261
+ private int initialWidth;
262
+ private int initialHeight;
263
+
264
+ // Screen metrics
265
+ private DisplayMetrics displayMetrics = new DisplayMetrics();
266
+ private int screenWidth;
267
+ private int screenHeight;
268
+ private int drawableWidth;
269
+ private int drawableHeight;
270
+ private boolean isPortraitScreen;
271
+
272
+ private long lastClickTime = 0;
273
+ private static final long DOUBLE_CLICK_TIME_DELTA = 200; // milliseconds
274
+
275
+ private final float ZOOM_SCALE_FACTOR =
276
+ 1.5f; // Factor to zoom in/out on double tap
277
+
278
+ private void updateScreenMetrics() {
279
+ mWindowManager.getDefaultDisplay().getMetrics(displayMetrics);
280
+ screenWidth = displayMetrics.widthPixels;
281
+ screenHeight = displayMetrics.heightPixels;
282
+ drawableWidth = screenWidth - MARGIN_LEFT - MARGIN_RIGHT;
283
+ drawableHeight = screenHeight - MARGIN_TOP - MARGIN_BOTTOM;
284
+ isPortraitScreen = screenHeight > screenWidth;
285
+ }
286
+
215
287
  @Override
216
288
  public boolean onTouch(View view, MotionEvent event) {
217
- switch (event.getAction()) {
289
+ // Update screen metrics at the beginning of a touch gesture,
290
+ // as orientation or screen size might have changed since last touch.
291
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
292
+ updateScreenMetrics();
293
+ }
294
+ // If currently animating from double click, consume touch events to
295
+ // prevent interference
296
+ if (isDoubleClickAnimating) {
297
+ // Allow ACTION_UP to potentially clear the flag if animation ends early
298
+ // or is cancelled but primarily, prevent new gestures from starting.
299
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
300
+ mode = MODE_NONE; // Prevent drag/zoom from starting
301
+ }
302
+ return true; // Consume the event
303
+ }
304
+ switch (event.getAction() & MotionEvent.ACTION_MASK) {
305
+ case MotionEvent.ACTION_DOWN:
306
+ downX = x = (int)event.getRawX();
307
+ downY = y = (int)event.getRawY();
308
+ mode = MODE_DRAG;
309
+ initialAspectRatio = (float)mLayoutParams.width / mLayoutParams.height;
310
+ initialWidth = mLayoutParams.width;
311
+ initialHeight = mLayoutParams.height;
312
+
313
+ // Double tap detection
314
+ long clickTime = System.currentTimeMillis();
315
+ if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA) {
316
+ handleDoubleClick(view);
317
+ }
318
+ lastClickTime = clickTime;
319
+ break;
320
+ case MotionEvent.ACTION_POINTER_DOWN:
321
+ oldDist = spacing(event);
322
+ if (oldDist > 10f) {
323
+ mode = MODE_ZOOM;
324
+ }
325
+ break;
218
326
  case MotionEvent.ACTION_UP:
327
+ case MotionEvent.ACTION_POINTER_UP:
328
+ boolean wasZooming = (mode == MODE_ZOOM);
329
+ // Capture params before mode is reset
330
+ int xBeforeSnap = mLayoutParams.x;
331
+ int widthBeforeSnap = mLayoutParams.width;
332
+
333
+ mode = MODE_NONE; // Reset mode
334
+
219
335
  if (isDragging) {
220
336
  isDragging = false;
337
+ // Perform snap animation if it was a drag or end of zoom
338
+ if (event.getPointerCount() == 1 || wasZooming) {
339
+ Log.i(TAG, "ACTION_UP/POINTER_UP: Triggering snap. xBeforeSnap=" +
340
+ xBeforeSnap + ", widthBeforeSnap=" +
341
+ widthBeforeSnap + ", wasZooming=" + wasZooming +
342
+ ", pointerCount=" + event.getPointerCount());
343
+ animateSnapToEdge(view);
344
+ }
221
345
  } else {
222
- FloatingWindowHelper.getInstance().onClickFloatingWindow(
223
- FloatingWindowService.this);
346
+ // Only trigger click if not zooming and it's a single pointer up
347
+ if (event.getPointerCount() == 1 &&
348
+ (event.getAction() & MotionEvent.ACTION_MASK) ==
349
+ MotionEvent.ACTION_UP) {
350
+ // Check if it was a drag or a tap
351
+ if (Math.abs(event.getRawX() - downX) < touchSlop &&
352
+ Math.abs(event.getRawY() - downY) < touchSlop) {
353
+ // This is a tap, not a double tap, so handle as single click if
354
+ // needed For now, double tap handles zoom, single tap is handled
355
+ // by new_window_btn
356
+ }
357
+ }
224
358
  }
225
- downX = downY = 0;
226
- break;
227
- case MotionEvent.ACTION_DOWN:
228
- downX = x = (int)event.getRawX();
229
- downY = y = (int)event.getRawY();
359
+ // downX and downY are reset at ACTION_DOWN for the primary pointer
230
360
  break;
361
+
231
362
  case MotionEvent.ACTION_MOVE:
232
- int nowX = (int)event.getRawX();
233
- int nowY = (int)event.getRawY();
234
- if (Math.abs(nowX - downX) > touchSlop ||
235
- Math.abs(nowY - downY) > touchSlop) {
236
- isDragging = true;
237
- }
238
- int movedX = nowX - x;
239
- int movedY = nowY - y;
240
- x = nowX;
241
- y = nowY;
242
- mLayoutParams.x = mLayoutParams.x + movedX;
243
- mLayoutParams.y = mLayoutParams.y + movedY;
244
- mWindowManager.updateViewLayout(view, mLayoutParams);
363
+ if (mode == MODE_DRAG && event.getPointerCount() == 1) {
364
+ int nowX = (int)event.getRawX();
365
+ int nowY = (int)event.getRawY();
366
+ if (!isDragging && (Math.abs(nowX - downX) > touchSlop ||
367
+ Math.abs(nowY - downY) > touchSlop)) {
368
+ isDragging = true;
369
+ }
370
+ if (isDragging) {
371
+ int movedX = nowX - x;
372
+ int movedY = nowY - y;
373
+ mLayoutParams.x = mLayoutParams.x + movedX;
374
+ mLayoutParams.y = mLayoutParams.y + movedY;
375
+
376
+ // 使用预先获取的屏幕高度 screenHeight
377
+ // 限制y坐标在安全区域内
378
+ mLayoutParams.y = Math.max(
379
+ MARGIN_TOP, Math.min(mLayoutParams.y, this.screenHeight -
380
+ mLayoutParams.height -
381
+ MARGIN_BOTTOM));
382
+
383
+ mWindowManager.updateViewLayout(view, mLayoutParams);
384
+ }
385
+ x = nowX;
386
+ y = nowY;
387
+ } else if (mode == MODE_ZOOM && event.getPointerCount() >= 2) {
388
+ float newDist = spacing(event);
389
+ if (newDist > 10f) {
390
+ // Calculate midpoint of the two fingers
391
+ float midX = (event.getX(0) + event.getX(1)) / 2;
392
+ float midY = (event.getY(0) + event.getY(1)) / 2;
393
+
394
+ // Convert midpoint from view coordinates to screen coordinates
395
+ float screenMidX = mLayoutParams.x + midX;
396
+ float screenMidY = mLayoutParams.y + midY;
397
+
398
+ float scale = newDist / oldDist;
399
+ int oldWidth = mLayoutParams.width;
400
+ int oldHeight = mLayoutParams.height;
401
+ int newWidth = (int)(oldWidth * scale);
402
+ int newHeight = (int)(oldHeight * scale);
403
+
404
+ // Use pre-calculated screen metrics
405
+ // Screen metrics are now updated in onTouch ACTION_DOWN, so they
406
+ // should be current here.
407
+
408
+ // Min size constraints: 1/2 of initial size, but not smaller than a
409
+ // fraction of screen respecting margins
410
+ int minAllowedWidth;
411
+ int minAllowedHeight;
412
+ if (isPortraitScreen) {
413
+ minAllowedWidth = Math.max(initialWidth / 2, drawableWidth / 2);
414
+ minAllowedHeight = (int)(minAllowedWidth / initialAspectRatio);
415
+ } else {
416
+ minAllowedHeight =
417
+ Math.max(initialHeight / 2, drawableHeight / 2);
418
+ minAllowedWidth = (int)(minAllowedHeight * initialAspectRatio);
419
+ }
420
+ // Ensure min dimensions are at least 1
421
+ minAllowedWidth = Math.max(1, minAllowedWidth);
422
+ minAllowedHeight = Math.max(1, minAllowedHeight);
423
+
424
+ // Max size constraints based on orientation and margins
425
+ int maxAllowedWidth, maxAllowedHeight;
426
+ if (isPortraitScreen) {
427
+ maxAllowedWidth = drawableWidth;
428
+ maxAllowedHeight =
429
+ (int)(maxAllowedWidth /
430
+ initialAspectRatio); // Maintain aspect ratio
431
+ if (maxAllowedHeight >
432
+ drawableHeight) { // If calculated height is too much for
433
+ // portrait
434
+ maxAllowedHeight = drawableHeight;
435
+ maxAllowedWidth = (int)(maxAllowedHeight * initialAspectRatio);
436
+ }
437
+ } else { // Landscape screen
438
+ maxAllowedHeight = drawableHeight;
439
+ maxAllowedWidth =
440
+ (int)(maxAllowedHeight *
441
+ initialAspectRatio); // Maintain aspect ratio
442
+ if (maxAllowedWidth > drawableWidth) { // If calculated width is
443
+ // too much for landscape
444
+ maxAllowedWidth = drawableWidth;
445
+ maxAllowedHeight = (int)(maxAllowedWidth / initialAspectRatio);
446
+ }
447
+ }
448
+ // maxAllowedWidth = Math.min(maxAllowedWidth, LONGER_SIDE_MAX_LEN);
449
+ // // Global max len - Removed maxAllowedHeight =
450
+ // Math.min(maxAllowedHeight, LONGER_SIDE_MAX_LEN); // Global max
451
+ // len - Removed
452
+ if (initialAspectRatio >= 1)
453
+ maxAllowedHeight = (int)(maxAllowedWidth / initialAspectRatio);
454
+ else
455
+ maxAllowedWidth = (int)(maxAllowedHeight * initialAspectRatio);
456
+
457
+ // Apply scaling
458
+ newWidth = (int)(oldWidth * scale);
459
+ newHeight = (int)(oldHeight * scale);
460
+
461
+ // Clamp to min/max size while maintaining aspect ratio
462
+ if (scale < 1) { // Shrinking
463
+ newWidth = Math.max(minAllowedWidth, newWidth);
464
+ newHeight = (int)(newWidth / initialAspectRatio);
465
+ if (newHeight < minAllowedHeight) {
466
+ newHeight = minAllowedHeight;
467
+ newWidth = (int)(newHeight * initialAspectRatio);
468
+ }
469
+ } else { // Expanding
470
+ newWidth = Math.min(maxAllowedWidth, newWidth);
471
+ newHeight = (int)(newWidth / initialAspectRatio);
472
+ if (newHeight > maxAllowedHeight) {
473
+ newHeight = maxAllowedHeight;
474
+ newWidth = (int)(newHeight * initialAspectRatio);
475
+ }
476
+ }
477
+
478
+ // Final check to ensure dimensions are within absolute min/max
479
+ // bounds
480
+ newWidth =
481
+ Math.max(minAllowedWidth, Math.min(newWidth, maxAllowedWidth));
482
+ newHeight =
483
+ (int)(newWidth / initialAspectRatio); // Maintain aspect ratio
484
+ // Ensure height is also clamped correctly after width adjustment
485
+ if (newHeight < minAllowedHeight) {
486
+ newHeight = minAllowedHeight;
487
+ newWidth = (int)(newHeight * initialAspectRatio);
488
+ }
489
+ if (newHeight > maxAllowedHeight) {
490
+ newHeight = maxAllowedHeight;
491
+ newWidth = (int)(newHeight * initialAspectRatio);
492
+ }
493
+ // Re-clamp width just in case height clamping affected it and
494
+ // pushed it out of width bounds
495
+ newWidth =
496
+ Math.max(minAllowedWidth, Math.min(newWidth, maxAllowedWidth));
497
+
498
+ // Adjust position to keep the zoom centered on the midpoint
499
+ mLayoutParams.x = (int)(screenMidX - (midX * newWidth / oldWidth));
500
+ mLayoutParams.y =
501
+ (int)(screenMidY - (midY * newHeight / oldHeight));
502
+
503
+ mLayoutParams.width = newWidth;
504
+ mLayoutParams.height = newHeight;
505
+
506
+ // Prevent window from going off-screen after repositioning
507
+ // For Y, keep margin constraints
508
+ mLayoutParams.y = Math.max(
509
+ MARGIN_TOP,
510
+ Math.min(mLayoutParams.y,
511
+ screenHeight - mLayoutParams.height - MARGIN_BOTTOM));
512
+ // For X, constrain to screen physical edges only during zoom,
513
+ // let animateSnapToEdge handle final margin snapping.
514
+ mLayoutParams.x = Math.max(
515
+ 0, // Screen physical left edge
516
+ Math.min(
517
+ mLayoutParams.x,
518
+ screenWidth -
519
+ mLayoutParams.width)); // Screen physical right edge
520
+
521
+ // 更新SurfaceView的布局参数
522
+ if (mSurfaceView != null) {
523
+ android.view.ViewGroup.LayoutParams surfaceParams =
524
+ mSurfaceView.getLayoutParams();
525
+ if (surfaceParams != null) {
526
+ surfaceParams.width = mLayoutParams.width;
527
+ surfaceParams.height = mLayoutParams.height;
528
+ mSurfaceView.setLayoutParams(surfaceParams);
529
+ }
530
+ }
531
+ mWindowManager.updateViewLayout(view, mLayoutParams);
532
+ oldDist = newDist;
533
+ }
534
+ isDragging =
535
+ true; // Zooming implies dragging state for click handling
536
+ }
245
537
  break;
246
538
 
247
539
  default:
@@ -249,5 +541,392 @@ public class FloatingWindowService extends Service {
249
541
  }
250
542
  return true;
251
543
  }
544
+
545
+ private float spacing(MotionEvent event) {
546
+ if (event.getPointerCount() < 2)
547
+ return 0f;
548
+ float x = event.getX(0) - event.getX(1);
549
+ float y = event.getY(0) - event.getY(1);
550
+ return (float)Math.sqrt(x * x + y * y);
551
+ }
552
+
553
+ private void handleDoubleClick(View view) {
554
+ Log.d(TAG, "Double tap detected");
555
+ int targetWidth, targetHeight;
556
+
557
+ // Use pre-calculated screen metrics
558
+ // updateScreenMetrics(); // Ensure metrics are fresh if not updated in
559
+ // onTouch ACTION_DOWN Screen metrics are now updated in onTouch
560
+ // ACTION_DOWN, so they should be current here.
561
+
562
+ // Minimum size: 1/2 of initial size, but not smaller than a fraction of
563
+ // screen respecting margins
564
+ int minAllowedWidth = initialWidth / 2;
565
+ int minAllowedHeight = initialHeight / 2;
566
+ if (isPortraitScreen) {
567
+ minAllowedWidth = Math.max(minAllowedWidth, drawableWidth / 2);
568
+ minAllowedHeight = (int)(minAllowedWidth / initialAspectRatio);
569
+ } else {
570
+ minAllowedHeight = Math.max(minAllowedHeight, drawableHeight / 2);
571
+ minAllowedWidth = (int)(minAllowedHeight * initialAspectRatio);
572
+ }
573
+
574
+ // Maximum size based on orientation and margins
575
+ int maxAllowedTargetWidth, maxAllowedTargetHeight;
576
+ if (isPortraitScreen) {
577
+ maxAllowedTargetWidth = drawableWidth;
578
+ maxAllowedTargetHeight =
579
+ (int)(maxAllowedTargetWidth / initialAspectRatio);
580
+ if (maxAllowedTargetHeight > drawableHeight) {
581
+ maxAllowedTargetHeight = drawableHeight;
582
+ maxAllowedTargetWidth =
583
+ (int)(maxAllowedTargetHeight * initialAspectRatio);
584
+ }
585
+ } else { // Landscape screen
586
+ maxAllowedTargetHeight = drawableHeight;
587
+ maxAllowedTargetWidth =
588
+ (int)(maxAllowedTargetHeight * initialAspectRatio);
589
+ if (maxAllowedTargetWidth > drawableWidth) {
590
+ maxAllowedTargetWidth = drawableWidth;
591
+ maxAllowedTargetHeight =
592
+ (int)(maxAllowedTargetWidth / initialAspectRatio);
593
+ }
594
+ }
595
+ // Apply global LONGER_SIDE_MAX_LEN constraint - Removed
596
+ // if (initialAspectRatio >= 1) { // Landscape or square video
597
+ // maxAllowedTargetWidth =
598
+ // Math.min(maxAllowedTargetWidth, LONGER_SIDE_MAX_LEN);
599
+ // maxAllowedTargetHeight =
600
+ // (int)(maxAllowedTargetWidth / initialAspectRatio);
601
+ // } else { // Portrait video
602
+ // maxAllowedTargetHeight =
603
+ // Math.min(maxAllowedTargetHeight, LONGER_SIDE_MAX_LEN);
604
+ // maxAllowedTargetWidth =
605
+ // (int)(maxAllowedTargetHeight * initialAspectRatio);
606
+ // }
607
+
608
+ int currentX = mLayoutParams.x;
609
+ int currentY = mLayoutParams.y;
610
+ int currentWidth = mLayoutParams.width;
611
+ int currentHeight = mLayoutParams.height;
612
+
613
+ int finalTargetX = currentX;
614
+ int finalTargetY = currentY;
615
+
616
+ // 计算当前宽度与中间值的比较,决定缩放方向
617
+ int midWidth = (minAllowedWidth + maxAllowedTargetWidth) / 2;
618
+ if (currentWidth < midWidth) {
619
+ // 当前更接近最小值,放大到最大尺寸
620
+ targetWidth = maxAllowedTargetWidth;
621
+ targetHeight = maxAllowedTargetHeight;
622
+ Log.d(TAG, "Zooming in to max: " + targetWidth + "x" + targetHeight);
623
+ } else {
624
+ // 当前更接近最大值,缩小到最小尺寸
625
+ targetWidth = minAllowedWidth;
626
+ targetHeight = minAllowedHeight;
627
+ Log.d(TAG, "Zooming out to min: " + targetWidth + "x" + targetHeight);
628
+ }
629
+
630
+ // Ensure target dimensions respect calculated min/max and screen
631
+ // boundaries with margins
632
+ targetWidth = Math.max(minAllowedWidth,
633
+ Math.min(targetWidth, maxAllowedTargetWidth));
634
+ targetHeight = (int)(targetWidth / initialAspectRatio);
635
+ if (targetHeight < minAllowedHeight) {
636
+ targetHeight = minAllowedHeight;
637
+ targetWidth = (int)(targetHeight * initialAspectRatio);
638
+ }
639
+ if (targetHeight > maxAllowedTargetHeight) {
640
+ targetHeight = maxAllowedTargetHeight;
641
+ targetWidth = (int)(targetHeight * initialAspectRatio);
642
+ }
643
+ // Final check for width after height adjustment
644
+ targetWidth = Math.max(minAllowedWidth,
645
+ Math.min(targetWidth, maxAllowedTargetWidth));
646
+
647
+ // Instantly apply new size and update layout BEFORE starting
648
+ // position/size animations This helps in reducing black bars by setting
649
+ // the target container size first.
650
+ mLayoutParams.width = targetWidth;
651
+ mLayoutParams.height = targetHeight;
652
+ if (mSmallWindowView != null &&
653
+ mSmallWindowView.getWindowToken() != null) {
654
+ mWindowManager.updateViewLayout(mSmallWindowView, mLayoutParams);
655
+ // Also update SurfaceView's layout params to match the new window size
656
+ // immediately
657
+ if (mSurfaceView != null) {
658
+ android.view.ViewGroup.LayoutParams surfaceParams =
659
+ mSurfaceView.getLayoutParams();
660
+ if (surfaceParams != null) {
661
+ surfaceParams.width = targetWidth;
662
+ surfaceParams.height = targetHeight;
663
+ mSurfaceView.setLayoutParams(surfaceParams);
664
+ mSurfaceView
665
+ .requestLayout(); // Crucial for SurfaceView to redraw correctly
666
+ }
667
+ }
668
+ }
669
+
670
+ // Determine window corner for zoom anchor, considering margins
671
+ boolean isTop =
672
+ currentY < (screenHeight - MARGIN_TOP - MARGIN_BOTTOM) / 2 -
673
+ currentHeight / 2 + MARGIN_TOP;
674
+ boolean isLeft =
675
+ currentX < (screenWidth - MARGIN_LEFT - MARGIN_RIGHT) / 2 -
676
+ currentWidth / 2 + MARGIN_LEFT;
677
+
678
+ if (isLeft && isTop) { // Top-left
679
+ finalTargetX = MARGIN_LEFT;
680
+ finalTargetY = MARGIN_TOP;
681
+ } else if (!isLeft && isTop) { // Top-right
682
+ finalTargetX = screenWidth - targetWidth - MARGIN_RIGHT;
683
+ finalTargetY = MARGIN_TOP;
684
+ } else if (isLeft && !isTop) { // Bottom-left
685
+ finalTargetX = MARGIN_LEFT;
686
+ finalTargetY = screenHeight - targetHeight - MARGIN_BOTTOM;
687
+ } else { // Bottom-right
688
+ finalTargetX = screenWidth - targetWidth - MARGIN_RIGHT;
689
+ finalTargetY = screenHeight - targetHeight - MARGIN_BOTTOM;
690
+ }
691
+
692
+ // Ensure target position is within drawable area
693
+ finalTargetX = Math.max(
694
+ MARGIN_LEFT,
695
+ Math.min(finalTargetX, screenWidth - targetWidth - MARGIN_RIGHT));
696
+ finalTargetY = Math.max(
697
+ MARGIN_TOP,
698
+ Math.min(finalTargetY, screenHeight - targetHeight - MARGIN_BOTTOM));
699
+
700
+ final int finalTargetWidth = targetWidth;
701
+ final int finalTargetHeight = targetHeight;
702
+
703
+ // Make copies for use in animator listeners
704
+ final int animFinalTargetX = finalTargetX;
705
+ final int animFinalTargetY = finalTargetY;
706
+
707
+ ValueAnimator xAnimator = ValueAnimator.ofInt(currentX, finalTargetX);
708
+ xAnimator.setDuration(200);
709
+ xAnimator.addUpdateListener(animation -> {
710
+ mLayoutParams.x = (Integer)animation.getAnimatedValue();
711
+ mWindowManager.updateViewLayout(view, mLayoutParams);
712
+ });
713
+
714
+ ValueAnimator yAnimator = ValueAnimator.ofInt(currentY, finalTargetY);
715
+ yAnimator.setDuration(200);
716
+ yAnimator.addUpdateListener(animation -> {
717
+ mLayoutParams.y = (Integer)animation.getAnimatedValue();
718
+ mWindowManager.updateViewLayout(view, mLayoutParams);
719
+ });
720
+
721
+ ValueAnimator widthAnimator =
722
+ ValueAnimator.ofInt(currentWidth, finalTargetWidth);
723
+ widthAnimator.setDuration(200);
724
+ widthAnimator.addUpdateListener(animation -> {
725
+ mLayoutParams.width = (Integer)animation.getAnimatedValue();
726
+ if (mSurfaceView != null) { // Ensure mSurfaceView is not null
727
+ android.view.ViewGroup.LayoutParams surfaceParams =
728
+ mSurfaceView.getLayoutParams();
729
+ if (surfaceParams != null) { // Ensure surfaceParams is not null
730
+ surfaceParams.width = mLayoutParams.width;
731
+ mSurfaceView.setLayoutParams(surfaceParams);
732
+ }
733
+ }
734
+ mWindowManager.updateViewLayout(view, mLayoutParams);
735
+ });
736
+
737
+ ValueAnimator heightAnimator =
738
+ ValueAnimator.ofInt(currentHeight, finalTargetHeight);
739
+ heightAnimator.setDuration(200);
740
+ heightAnimator.addUpdateListener(animation -> {
741
+ mLayoutParams.height = (Integer)animation.getAnimatedValue();
742
+ if (mSurfaceView != null) { // Ensure mSurfaceView is not null
743
+ android.view.ViewGroup.LayoutParams surfaceParams =
744
+ mSurfaceView.getLayoutParams();
745
+ if (surfaceParams != null) { // Ensure surfaceParams is not null
746
+ surfaceParams.height = mLayoutParams.height;
747
+ mSurfaceView.setLayoutParams(surfaceParams);
748
+ }
749
+ }
750
+ mWindowManager.updateViewLayout(view, mLayoutParams);
751
+ });
752
+
753
+ android.animation.AnimatorSet animatorSet =
754
+ new android.animation.AnimatorSet();
755
+ animatorSet.playTogether(xAnimator, yAnimator, widthAnimator,
756
+ heightAnimator);
757
+ // The isDoubleClickAnimating flag is now managed by
758
+ // FloatingOnTouchListener but we still need to set it within
759
+ // handleDoubleClick's AnimatorSet listeners to ensure it's active for the
760
+ // duration of this specific animation.
761
+ animatorSet.addListener(new android.animation.AnimatorListenerAdapter() {
762
+ @Override
763
+ public void onAnimationStart(android.animation.Animator animation) {
764
+ if (FloatingWindowService.this.mFloatingOnTouchListener != null) {
765
+ FloatingWindowService.this.mFloatingOnTouchListener
766
+ .isDoubleClickAnimating = true;
767
+ }
768
+ Log.d(TAG, "Double tap AnimatorSet started.");
769
+ }
770
+
771
+ @Override
772
+ public void onAnimationEnd(android.animation.Animator animation) {
773
+ if (FloatingWindowService.this.mFloatingOnTouchListener != null) {
774
+ FloatingWindowService.this.mFloatingOnTouchListener
775
+ .isDoubleClickAnimating = false;
776
+ }
777
+ // ValueAnimators update mLayoutParams continuously via their
778
+ // AnimatorUpdateListener. For safety, explicitly set final position
779
+ // values as the last update might not be exact.
780
+ mLayoutParams.x = animFinalTargetX;
781
+ mLayoutParams.y = animFinalTargetY;
782
+ // mLayoutParams.width and mLayoutParams.height should be at
783
+ // finalTargetWidth/Height due to widthAnimator and heightAnimator's
784
+ // updates.
785
+
786
+ // Perform a final update of the window layout with all parameters.
787
+ if (mSmallWindowView != null &&
788
+ mSmallWindowView.getWindowToken() != null) {
789
+ mWindowManager.updateViewLayout(mSmallWindowView, mLayoutParams);
790
+ }
791
+
792
+ // Resize SurfaceView (logic moved from postDelayed and refined)
793
+ if (mSurfaceView != null && mLayoutParams != null) {
794
+ android.view.ViewGroup.LayoutParams surfaceParams =
795
+ mSurfaceView.getLayoutParams();
796
+ if (surfaceParams != null) {
797
+ boolean changed = false;
798
+ if (surfaceParams.width != mLayoutParams.width) {
799
+ surfaceParams.width =
800
+ mLayoutParams.width; // mLayoutParams.width is at its final
801
+ // animated value
802
+ changed = true;
803
+ }
804
+ if (surfaceParams.height != mLayoutParams.height) {
805
+ surfaceParams.height =
806
+ mLayoutParams.height; // mLayoutParams.height is at its
807
+ // final animated value
808
+ changed = true;
809
+ }
810
+ if (changed) {
811
+ mSurfaceView.setLayoutParams(surfaceParams);
812
+ }
813
+ mSurfaceView
814
+ .requestLayout(); // Ensure the SurfaceView redraws correctly
815
+ Log.d(TAG,
816
+ "SurfaceView dimensions finalized in onAnimationEnd to: " +
817
+ mLayoutParams.width + "x" + mLayoutParams.height);
818
+ }
819
+ }
820
+ Log.d(TAG, "Double tap AnimatorSet ended. Final state: x=" +
821
+ mLayoutParams.x + ", y=" + mLayoutParams.y + ", w=" +
822
+ mLayoutParams.width + ", h=" + mLayoutParams.height);
823
+ }
824
+
825
+ @Override
826
+ public void onAnimationCancel(android.animation.Animator animation) {
827
+ if (FloatingWindowService.this.mFloatingOnTouchListener != null) {
828
+ FloatingWindowService.this.mFloatingOnTouchListener
829
+ .isDoubleClickAnimating = false;
830
+ }
831
+ // Animation was cancelled, so explicitly set all mLayoutParams to
832
+ // their final target values.
833
+ mLayoutParams.x = animFinalTargetX;
834
+ mLayoutParams.y = animFinalTargetY;
835
+ mLayoutParams.width = finalTargetWidth;
836
+ mLayoutParams.height = finalTargetHeight;
837
+
838
+ if (mSmallWindowView != null &&
839
+ mSmallWindowView.getWindowToken() != null) {
840
+ mWindowManager.updateViewLayout(mSmallWindowView, mLayoutParams);
841
+ }
842
+
843
+ // Resize SurfaceView to final target dimensions
844
+ if (mSurfaceView != null && mLayoutParams != null) {
845
+ android.view.ViewGroup.LayoutParams surfaceParams =
846
+ mSurfaceView.getLayoutParams();
847
+ if (surfaceParams != null) {
848
+ if (surfaceParams.width != mLayoutParams.width ||
849
+ surfaceParams.height != mLayoutParams.height) {
850
+ surfaceParams.width =
851
+ mLayoutParams.width; // Now finalTargetWidth
852
+ surfaceParams.height =
853
+ mLayoutParams.height; // Now finalTargetHeight
854
+ mSurfaceView.setLayoutParams(surfaceParams);
855
+ }
856
+ mSurfaceView
857
+ .requestLayout(); // Ensure the SurfaceView redraws correctly
858
+ }
859
+ }
860
+ Log.d(TAG,
861
+ "Double tap AnimatorSet cancelled. State set to targets: x=" +
862
+ mLayoutParams.x + ", y=" + mLayoutParams.y + ", w=" +
863
+ mLayoutParams.width + ", h=" + mLayoutParams.height);
864
+ }
865
+ });
866
+ animatorSet.start();
867
+ }
868
+
869
+ private void animateSnapToEdge(View view) {
870
+ // Use pre-calculated screen metrics
871
+ // updateScreenMetrics(); // Ensure metrics are fresh if not updated in
872
+ // onTouch ACTION_DOWN Screen metrics are now updated in onTouch
873
+ // ACTION_DOWN, so they should be current here.
874
+ final int screenWidth = this.screenWidth; // Make final for use in lambda
875
+ final int windowWidthAtAnimationStart =
876
+ mLayoutParams.width; // Capture width at start
877
+
878
+ int currentX =
879
+ mLayoutParams
880
+ .x; // This is the x at the moment animateSnapToEdge is called
881
+ int targetX;
882
+
883
+ // Determine targetX based on current position and captured width
884
+ if (currentX + windowWidthAtAnimationStart / 2 < screenWidth / 2) {
885
+ targetX = MARGIN_LEFT;
886
+ } else {
887
+ targetX = screenWidth - windowWidthAtAnimationStart - MARGIN_RIGHT;
888
+ }
889
+
890
+ Log.i(TAG, "animateSnapToEdge: currentX=" + currentX +
891
+ ", windowWidthAtAnimStart=" + windowWidthAtAnimationStart +
892
+ ", screenWidth=" + screenWidth + ", calculatedTargetX=" +
893
+ targetX + ", currentY=" + mLayoutParams.y +
894
+ ", currentHeight=" + mLayoutParams.height);
895
+
896
+ if (currentX == targetX) {
897
+ Log.i(TAG, "animateSnapToEdge: Already at targetX (" + targetX +
898
+ "). No animation needed.");
899
+ return;
900
+ }
901
+
902
+ ValueAnimator snapAnimator = ValueAnimator.ofInt(currentX, targetX);
903
+ snapAnimator.setDuration(200);
904
+ snapAnimator.addUpdateListener(animation -> {
905
+ mLayoutParams.x = (Integer)animation.getAnimatedValue();
906
+ // Boundary checks using width captured at animation start
907
+ if (mLayoutParams.x < 0) { // Physical screen boundary
908
+ mLayoutParams.x = 0;
909
+ }
910
+ // Ensure the right edge does not go beyond screen width
911
+ if (mLayoutParams.x + windowWidthAtAnimationStart >
912
+ screenWidth) { // Physical screen boundary
913
+ mLayoutParams.x = screenWidth - windowWidthAtAnimationStart;
914
+ }
915
+ try {
916
+ if (mSmallWindowView != null &&
917
+ mSmallWindowView.getWindowToken() !=
918
+ null) { // Check if view is still attached
919
+ mWindowManager.updateViewLayout(view, mLayoutParams);
920
+ }
921
+ } catch (IllegalArgumentException e) {
922
+ Log.w(TAG, "animateSnapToEdge: View not attached? " + e.getMessage());
923
+ // Cancel animator if view is gone to prevent further errors
924
+ if (animation.isRunning()) {
925
+ animation.cancel();
926
+ }
927
+ }
928
+ });
929
+ snapAnimator.start();
930
+ }
252
931
  }
253
932
  }
@@ -4565,6 +4565,7 @@ var TVLManager = function () {
4565
4565
  var _enableAudioFrameObserver_decorators;
4566
4566
  var _setEnableSuperResolution_decorators;
4567
4567
  var _setVolume_decorators;
4568
+ var _setEnableIgnoreAudioInterruption_decorators;
4568
4569
  _classThis = /** @class */ (function () {
4569
4570
  function TVLManager_1() {
4570
4571
  /** {zh}
@@ -4872,6 +4873,9 @@ var TVLManager = function () {
4872
4873
  TVLManager_1.prototype.setVolume = function (volume) {
4873
4874
  throw new Error('not implement');
4874
4875
  };
4876
+ TVLManager_1.prototype.setEnableIgnoreAudioInterruption = function (enable) {
4877
+ throw new Error('not implement');
4878
+ };
4875
4879
  return TVLManager_1;
4876
4880
  }());
4877
4881
  __setFunctionName(_classThis, "TVLManager");
@@ -4907,6 +4911,7 @@ var TVLManager = function () {
4907
4911
  _enableAudioFrameObserver_decorators = [NativeMethodSync('enableAudioFrameObserver:enableRendering:')];
4908
4912
  _setEnableSuperResolution_decorators = [NativeMethodSync('setEnableSuperResolution:')];
4909
4913
  _setVolume_decorators = [NativeMethodSync('setVolume:')];
4914
+ _setEnableIgnoreAudioInterruption_decorators = [NativeMethodSync('setEnableIgnoreAudioInterruption:')];
4910
4915
  __esDecorate(_classThis, null, _static_setLogLevel_decorators, { kind: "method", name: "setLogLevel", static: true, private: false, access: { has: function (obj) { return "setLogLevel" in obj; }, get: function (obj) { return obj.setLogLevel; } }, metadata: _metadata }, null, _staticExtraInitializers);
4911
4916
  __esDecorate(_classThis, null, _static_getVersion_decorators, { kind: "method", name: "getVersion", static: true, private: false, access: { has: function (obj) { return "getVersion" in obj; }, get: function (obj) { return obj.getVersion; } }, metadata: _metadata }, null, _staticExtraInitializers);
4912
4917
  __esDecorate(_classThis, null, _static_setHttpDNSHostIP_decorators, { kind: "method", name: "setHttpDNSHostIP", static: true, private: false, access: { has: function (obj) { return "setHttpDNSHostIP" in obj; }, get: function (obj) { return obj.setHttpDNSHostIP; } }, metadata: _metadata }, null, _staticExtraInitializers);
@@ -4933,6 +4938,7 @@ var TVLManager = function () {
4933
4938
  __esDecorate(_classThis, null, _enableAudioFrameObserver_decorators, { kind: "method", name: "enableAudioFrameObserver", static: false, private: false, access: { has: function (obj) { return "enableAudioFrameObserver" in obj; }, get: function (obj) { return obj.enableAudioFrameObserver; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4934
4939
  __esDecorate(_classThis, null, _setEnableSuperResolution_decorators, { kind: "method", name: "setEnableSuperResolution", static: false, private: false, access: { has: function (obj) { return "setEnableSuperResolution" in obj; }, get: function (obj) { return obj.setEnableSuperResolution; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4935
4940
  __esDecorate(_classThis, null, _setVolume_decorators, { kind: "method", name: "setVolume", static: false, private: false, access: { has: function (obj) { return "setVolume" in obj; }, get: function (obj) { return obj.setVolume; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4941
+ __esDecorate(_classThis, null, _setEnableIgnoreAudioInterruption_decorators, { kind: "method", name: "setEnableIgnoreAudioInterruption", static: false, private: false, access: { has: function (obj) { return "setEnableIgnoreAudioInterruption" in obj; }, get: function (obj) { return obj.setEnableIgnoreAudioInterruption; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4936
4942
  __esDecorate(null, null, _observer_decorators, { kind: "field", name: "observer", static: false, private: false, access: { has: function (obj) { return "observer" in obj; }, get: function (obj) { return obj.observer; }, set: function (obj, value) { obj.observer = value; } }, metadata: _metadata }, _observer_initializers, _observer_extraInitializers);
4937
4943
  __esDecorate(null, null, _playerView_decorators, { kind: "field", name: "playerView", static: false, private: false, access: { has: function (obj) { return "playerView" in obj; }, get: function (obj) { return obj.playerView; }, set: function (obj, value) { obj.playerView = value; } }, metadata: _metadata }, _playerView_initializers, _playerView_extraInitializers);
4938
4944
  __esDecorate(null, null, _volume_decorators, { kind: "field", name: "volume", static: false, private: false, access: { has: function (obj) { return "volume" in obj; }, get: function (obj) { return obj.volume; }, set: function (obj, value) { obj.volume = value; } }, metadata: _metadata }, _volume_initializers, _volume_extraInitializers);
@@ -6723,38 +6729,6 @@ var VeLivePlayerStatistics = function () {
6723
6729
  enumerable: false,
6724
6730
  configurable: true
6725
6731
  });
6726
- Object.defineProperty(VeLivePlayerStatistics_1.prototype, "format", {
6727
- /** {zh}
6728
- * @brief 当前播放的视频格式。
6729
- *
6730
- */
6731
- /** {en}
6732
- * @brief The video format.
6733
- *
6734
- */
6735
- get: function () {
6736
- // TODO: implement
6737
- throw new Error("not implement 'format'");
6738
- },
6739
- enumerable: false,
6740
- configurable: true
6741
- });
6742
- Object.defineProperty(VeLivePlayerStatistics_1.prototype, "protocol", {
6743
- /** {zh}
6744
- * @brief 当前播放的传输协议。
6745
- *
6746
- */
6747
- /** {en}
6748
- * @brief The transmission protocol of the live stream.
6749
- *
6750
- */
6751
- get: function () {
6752
- // TODO: implement
6753
- throw new Error("not implement 'protocol'");
6754
- },
6755
- enumerable: false,
6756
- configurable: true
6757
- });
6758
6732
  Object.defineProperty(VeLivePlayerStatistics_1.prototype, "url", {
6759
6733
  /** {zh}
6760
6734
  * @brief 当前直播的播放地址。
@@ -11384,6 +11358,13 @@ extendsClassMethod(VeLivePlayer, 'destroy', function (origin) {
11384
11358
  }); });
11385
11359
  };
11386
11360
  });
11361
+ extendsClassMethod(VeLivePlayer, 'setEnableIgnoreAudioInterruption', function () {
11362
+ return function setEnableIgnoreAudioInterruption(enable) {
11363
+ return runImpl(this, function () { }, function (engine) {
11364
+ engine.setEnableIgnoreAudioInterruption(enable);
11365
+ });
11366
+ };
11367
+ });
11387
11368
 
11388
11369
  extendsClassMethod(android_VeLivePlayerObserver, 'onVideoSizeChanged', function (original) {
11389
11370
  return function onVideoSizeChanged(player, width, height) {
@@ -11641,23 +11622,24 @@ function initAndroidPlayer(options) {
11641
11622
  }
11642
11623
  function initIOSPlayer(options) {
11643
11624
  return __awaiter(this, void 0, void 0, function () {
11644
- var viewId, option, player, config, uiView, multiObserver, manager;
11625
+ var viewId, option, iosPlayer, player, config, uiView, multiObserver, manager;
11645
11626
  return __generator(this, function (_a) {
11646
11627
  switch (_a.label) {
11647
11628
  case 0:
11648
11629
  viewId = options.viewId, option = __rest(options, ["viewId"]);
11649
- player = new VeLivePlayer({});
11630
+ iosPlayer = new TVLManager();
11631
+ player = packObject(iosPlayer, VeLivePlayer);
11650
11632
  config = new VeLivePlayerConfiguration();
11651
11633
  Object.assign(config, defaultConfig, option);
11652
11634
  player.setConfig(config);
11653
11635
  uiView = NativeView.getView(viewId, NativeUIView);
11654
- return [4 /*yield*/, uiView.insertSubview(player.ios_playerView, 0)];
11636
+ return [4 /*yield*/, uiView.insertSubview(iosPlayer.playerView, 0)];
11655
11637
  case 1:
11656
11638
  _a.sent();
11657
11639
  multiObserver = VeLivePlayerMultiObserver.getInstance();
11658
- multiObserver.setupPlayer(unpackObject(player));
11640
+ multiObserver.setupPlayer(iosPlayer);
11659
11641
  manager = VeLivePictureInPictureManager.getInstance();
11660
- manager.setupPlayer(unpackObject(player));
11642
+ manager.setupPlayer(iosPlayer);
11661
11643
  return [2 /*return*/, player];
11662
11644
  }
11663
11645
  });
@@ -4563,6 +4563,7 @@ var TVLManager = function () {
4563
4563
  var _enableAudioFrameObserver_decorators;
4564
4564
  var _setEnableSuperResolution_decorators;
4565
4565
  var _setVolume_decorators;
4566
+ var _setEnableIgnoreAudioInterruption_decorators;
4566
4567
  _classThis = /** @class */ (function () {
4567
4568
  function TVLManager_1() {
4568
4569
  /** {zh}
@@ -4870,6 +4871,9 @@ var TVLManager = function () {
4870
4871
  TVLManager_1.prototype.setVolume = function (volume) {
4871
4872
  throw new Error('not implement');
4872
4873
  };
4874
+ TVLManager_1.prototype.setEnableIgnoreAudioInterruption = function (enable) {
4875
+ throw new Error('not implement');
4876
+ };
4873
4877
  return TVLManager_1;
4874
4878
  }());
4875
4879
  __setFunctionName(_classThis, "TVLManager");
@@ -4905,6 +4909,7 @@ var TVLManager = function () {
4905
4909
  _enableAudioFrameObserver_decorators = [NativeMethodSync('enableAudioFrameObserver:enableRendering:')];
4906
4910
  _setEnableSuperResolution_decorators = [NativeMethodSync('setEnableSuperResolution:')];
4907
4911
  _setVolume_decorators = [NativeMethodSync('setVolume:')];
4912
+ _setEnableIgnoreAudioInterruption_decorators = [NativeMethodSync('setEnableIgnoreAudioInterruption:')];
4908
4913
  __esDecorate(_classThis, null, _static_setLogLevel_decorators, { kind: "method", name: "setLogLevel", static: true, private: false, access: { has: function (obj) { return "setLogLevel" in obj; }, get: function (obj) { return obj.setLogLevel; } }, metadata: _metadata }, null, _staticExtraInitializers);
4909
4914
  __esDecorate(_classThis, null, _static_getVersion_decorators, { kind: "method", name: "getVersion", static: true, private: false, access: { has: function (obj) { return "getVersion" in obj; }, get: function (obj) { return obj.getVersion; } }, metadata: _metadata }, null, _staticExtraInitializers);
4910
4915
  __esDecorate(_classThis, null, _static_setHttpDNSHostIP_decorators, { kind: "method", name: "setHttpDNSHostIP", static: true, private: false, access: { has: function (obj) { return "setHttpDNSHostIP" in obj; }, get: function (obj) { return obj.setHttpDNSHostIP; } }, metadata: _metadata }, null, _staticExtraInitializers);
@@ -4931,6 +4936,7 @@ var TVLManager = function () {
4931
4936
  __esDecorate(_classThis, null, _enableAudioFrameObserver_decorators, { kind: "method", name: "enableAudioFrameObserver", static: false, private: false, access: { has: function (obj) { return "enableAudioFrameObserver" in obj; }, get: function (obj) { return obj.enableAudioFrameObserver; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4932
4937
  __esDecorate(_classThis, null, _setEnableSuperResolution_decorators, { kind: "method", name: "setEnableSuperResolution", static: false, private: false, access: { has: function (obj) { return "setEnableSuperResolution" in obj; }, get: function (obj) { return obj.setEnableSuperResolution; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4933
4938
  __esDecorate(_classThis, null, _setVolume_decorators, { kind: "method", name: "setVolume", static: false, private: false, access: { has: function (obj) { return "setVolume" in obj; }, get: function (obj) { return obj.setVolume; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4939
+ __esDecorate(_classThis, null, _setEnableIgnoreAudioInterruption_decorators, { kind: "method", name: "setEnableIgnoreAudioInterruption", static: false, private: false, access: { has: function (obj) { return "setEnableIgnoreAudioInterruption" in obj; }, get: function (obj) { return obj.setEnableIgnoreAudioInterruption; } }, metadata: _metadata }, null, _instanceExtraInitializers);
4934
4940
  __esDecorate(null, null, _observer_decorators, { kind: "field", name: "observer", static: false, private: false, access: { has: function (obj) { return "observer" in obj; }, get: function (obj) { return obj.observer; }, set: function (obj, value) { obj.observer = value; } }, metadata: _metadata }, _observer_initializers, _observer_extraInitializers);
4935
4941
  __esDecorate(null, null, _playerView_decorators, { kind: "field", name: "playerView", static: false, private: false, access: { has: function (obj) { return "playerView" in obj; }, get: function (obj) { return obj.playerView; }, set: function (obj, value) { obj.playerView = value; } }, metadata: _metadata }, _playerView_initializers, _playerView_extraInitializers);
4936
4942
  __esDecorate(null, null, _volume_decorators, { kind: "field", name: "volume", static: false, private: false, access: { has: function (obj) { return "volume" in obj; }, get: function (obj) { return obj.volume; }, set: function (obj, value) { obj.volume = value; } }, metadata: _metadata }, _volume_initializers, _volume_extraInitializers);
@@ -6721,38 +6727,6 @@ var VeLivePlayerStatistics = function () {
6721
6727
  enumerable: false,
6722
6728
  configurable: true
6723
6729
  });
6724
- Object.defineProperty(VeLivePlayerStatistics_1.prototype, "format", {
6725
- /** {zh}
6726
- * @brief 当前播放的视频格式。
6727
- *
6728
- */
6729
- /** {en}
6730
- * @brief The video format.
6731
- *
6732
- */
6733
- get: function () {
6734
- // TODO: implement
6735
- throw new Error("not implement 'format'");
6736
- },
6737
- enumerable: false,
6738
- configurable: true
6739
- });
6740
- Object.defineProperty(VeLivePlayerStatistics_1.prototype, "protocol", {
6741
- /** {zh}
6742
- * @brief 当前播放的传输协议。
6743
- *
6744
- */
6745
- /** {en}
6746
- * @brief The transmission protocol of the live stream.
6747
- *
6748
- */
6749
- get: function () {
6750
- // TODO: implement
6751
- throw new Error("not implement 'protocol'");
6752
- },
6753
- enumerable: false,
6754
- configurable: true
6755
- });
6756
6730
  Object.defineProperty(VeLivePlayerStatistics_1.prototype, "url", {
6757
6731
  /** {zh}
6758
6732
  * @brief 当前直播的播放地址。
@@ -11382,6 +11356,13 @@ extendsClassMethod(VeLivePlayer, 'destroy', function (origin) {
11382
11356
  }); });
11383
11357
  };
11384
11358
  });
11359
+ extendsClassMethod(VeLivePlayer, 'setEnableIgnoreAudioInterruption', function () {
11360
+ return function setEnableIgnoreAudioInterruption(enable) {
11361
+ return runImpl(this, function () { }, function (engine) {
11362
+ engine.setEnableIgnoreAudioInterruption(enable);
11363
+ });
11364
+ };
11365
+ });
11385
11366
 
11386
11367
  extendsClassMethod(android_VeLivePlayerObserver, 'onVideoSizeChanged', function (original) {
11387
11368
  return function onVideoSizeChanged(player, width, height) {
@@ -11639,23 +11620,24 @@ function initAndroidPlayer(options) {
11639
11620
  }
11640
11621
  function initIOSPlayer(options) {
11641
11622
  return __awaiter(this, void 0, void 0, function () {
11642
- var viewId, option, player, config, uiView, multiObserver, manager;
11623
+ var viewId, option, iosPlayer, player, config, uiView, multiObserver, manager;
11643
11624
  return __generator(this, function (_a) {
11644
11625
  switch (_a.label) {
11645
11626
  case 0:
11646
11627
  viewId = options.viewId, option = __rest(options, ["viewId"]);
11647
- player = new VeLivePlayer({});
11628
+ iosPlayer = new TVLManager();
11629
+ player = packObject(iosPlayer, VeLivePlayer);
11648
11630
  config = new VeLivePlayerConfiguration();
11649
11631
  Object.assign(config, defaultConfig, option);
11650
11632
  player.setConfig(config);
11651
11633
  uiView = NativeView.getView(viewId, NativeUIView);
11652
- return [4 /*yield*/, uiView.insertSubview(player.ios_playerView, 0)];
11634
+ return [4 /*yield*/, uiView.insertSubview(iosPlayer.playerView, 0)];
11653
11635
  case 1:
11654
11636
  _a.sent();
11655
11637
  multiObserver = VeLivePlayerMultiObserver.getInstance();
11656
- multiObserver.setupPlayer(unpackObject(player));
11638
+ multiObserver.setupPlayer(iosPlayer);
11657
11639
  manager = VeLivePictureInPictureManager.getInstance();
11658
- manager.setupPlayer(unpackObject(player));
11640
+ manager.setupPlayer(iosPlayer);
11659
11641
  return [2 /*return*/, player];
11660
11642
  }
11661
11643
  });
@@ -62,6 +62,7 @@ export declare class TVLManager {
62
62
 
63
63
  setEnableSuperResolution(enable: BOOL): void;
64
64
  setVolume(volume: float): void;
65
+ setEnableIgnoreAudioInterruption(enable: BOOL): void;
65
66
  }
66
67
  export declare enum VeLivePlayerType {
67
68
 
@@ -111,18 +111,6 @@ export declare class VeLivePlayerStatistics {
111
111
  */
112
112
  get isHardwareDecode(): boolean;
113
113
 
114
- /** {en}
115
- * @brief The video format.
116
- *
117
- */
118
- get format(): void;
119
-
120
- /** {en}
121
- * @brief The transmission protocol of the live stream.
122
- *
123
- */
124
- get protocol(): void;
125
-
126
114
  /** {en}
127
115
  * @brief The current pull stream address.
128
116
  *
@@ -83,6 +83,19 @@ declare module '../codegen/pack/api' {
83
83
  * @order 6
84
84
  */
85
85
  disablePictureInPicture(): Promise<void>;
86
+ /**
87
+ * {zh}
88
+ * @brief 设置是否忽略音频中断
89
+ * @param enable 是否忽略音频中断
90
+ * @order 7
91
+ */
92
+ /**
93
+ * {en}
94
+ * @brief Set whether to ignore audio interruption
95
+ * @param enable Whether to ignore audio interruption
96
+ * @order 7
97
+ */
98
+ setEnableIgnoreAudioInterruption(enable: boolean): void;
86
99
  }
87
100
  }
88
101
  export { VeLivePlayer };
@@ -1 +1,17 @@
1
+ declare module '../codegen/pack/keytype' {
2
+ interface VeLivePlayerStatistics {
3
+
4
+ /** {en}
5
+ * @brief The video format.
6
+ *
7
+ */
8
+ format: VeLivePlayerFormat;
9
+
10
+ /** {en}
11
+ * @brief The transmission protocol of the live stream.
12
+ *
13
+ */
14
+ protocol: VeLivePlayerProtocol;
15
+ }
16
+ }
1
17
  export { VeLivePlayerAudioBufferType, VeLivePlayerAudioFrame, VeLivePlayerConfiguration, VeLivePlayerFillMode, VeLivePlayerFormat, VeLivePlayerLogLevel, VeLivePlayerMirror, VeLivePlayerPixelFormat, VeLivePlayerProtocol, VeLivePlayerResolution, VeLivePlayerResolutionSwitchReason, VeLivePlayerRotation, VeLivePlayerStatistics, VeLivePlayerStatus, VeLivePlayerStream, VeLivePlayerStreamData, VeLivePlayerStreamType, VeLivePlayerVideoBufferType, VeLivePlayerVideoFrame, } from '../codegen/pack/keytype';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byteplus/react-native-live-pull",
3
- "version": "1.1.2-rc.1",
3
+ "version": "1.1.3-rc.0",
4
4
  "peerDependencies": {
5
5
  "react": "*",
6
6
  "react-native": "*"