react-native-unified-player 0.6.1 → 0.6.3
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.
|
@@ -57,6 +57,7 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
57
57
|
private var thumbnailUrl: String? = null
|
|
58
58
|
private var autoplay: Boolean = true
|
|
59
59
|
private var loop: Boolean = false
|
|
60
|
+
private var speed: Float = 1.0f // Default playback speed
|
|
60
61
|
private var textureView: android.view.TextureView
|
|
61
62
|
private var thumbnailImageView: ImageView? = null
|
|
62
63
|
internal var player: ExoPlayer? = null
|
|
@@ -157,6 +158,11 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
157
158
|
sendEvent(EVENT_COMPLETE, Arguments.createMap())
|
|
158
159
|
} else {
|
|
159
160
|
Log.d(TAG, "Looping enabled, not sending completion event")
|
|
161
|
+
// Ensure playback speed is preserved after loop
|
|
162
|
+
if (speed != 1.0f && player != null) {
|
|
163
|
+
player?.setPlaybackSpeed(speed)
|
|
164
|
+
Log.d(TAG, "Restored playback speed: $speed after loop")
|
|
165
|
+
}
|
|
160
166
|
}
|
|
161
167
|
}
|
|
162
168
|
Player.STATE_BUFFERING -> {
|
|
@@ -175,6 +181,11 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
175
181
|
Log.d(TAG, "ExoPlayer is now playing")
|
|
176
182
|
// Hide thumbnail when video starts playing
|
|
177
183
|
thumbnailImageView?.visibility = View.GONE
|
|
184
|
+
// Ensure playback speed is preserved when playback resumes (e.g., after loop)
|
|
185
|
+
if (speed != 1.0f) {
|
|
186
|
+
player?.setPlaybackSpeed(speed)
|
|
187
|
+
Log.d(TAG, "Restored playback speed: $speed when playback resumed")
|
|
188
|
+
}
|
|
178
189
|
sendEvent(EVENT_RESUMED, Arguments.createMap())
|
|
179
190
|
sendEvent(EVENT_PLAYING, Arguments.createMap())
|
|
180
191
|
} else {
|
|
@@ -248,8 +259,12 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
248
259
|
player?.prepare()
|
|
249
260
|
player?.playWhenReady = autoplay && !isPaused
|
|
250
261
|
player?.repeatMode = if (loop) Player.REPEAT_MODE_ONE else Player.REPEAT_MODE_OFF
|
|
262
|
+
// Apply playback speed if set
|
|
263
|
+
if (speed != 1.0f) {
|
|
264
|
+
player?.setPlaybackSpeed(speed)
|
|
265
|
+
}
|
|
251
266
|
|
|
252
|
-
Log.d(TAG, "ExoPlayer configured with URL: $url, autoplay: $autoplay, loop: $loop, isPaused: $isPaused")
|
|
267
|
+
Log.d(TAG, "ExoPlayer configured with URL: $url, autoplay: $autoplay, loop: $loop, isPaused: $isPaused, speed: $speed")
|
|
253
268
|
sendEvent(EVENT_LOAD_START, Arguments.createMap())
|
|
254
269
|
|
|
255
270
|
} catch (e: Exception) {
|
|
@@ -436,6 +451,10 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
436
451
|
fun play() {
|
|
437
452
|
Log.d(TAG, "Play method called")
|
|
438
453
|
player?.playWhenReady = true
|
|
454
|
+
// Ensure playback speed is applied when playing
|
|
455
|
+
if (speed != 1.0f) {
|
|
456
|
+
player?.setPlaybackSpeed(speed)
|
|
457
|
+
}
|
|
439
458
|
}
|
|
440
459
|
|
|
441
460
|
fun pause() {
|
|
@@ -455,8 +474,9 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
455
474
|
} ?: Log.e(TAG, "Cannot seek: player is null")
|
|
456
475
|
}
|
|
457
476
|
|
|
458
|
-
fun setSpeed(
|
|
459
|
-
Log.d(TAG, "SetSpeed method called with speed: $
|
|
477
|
+
fun setSpeed(speedValue: Float) {
|
|
478
|
+
Log.d(TAG, "SetSpeed method called with speed: $speedValue")
|
|
479
|
+
speed = speedValue // Store the speed value
|
|
460
480
|
player?.let {
|
|
461
481
|
it.setPlaybackSpeed(speed)
|
|
462
482
|
Log.d(TAG, "Playback speed set to: $speed")
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
_autoplay = YES;
|
|
63
63
|
_loop = NO;
|
|
64
64
|
_isFullscreen = NO;
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
// Add notification observers
|
|
67
67
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
68
68
|
selector:@selector(appDidEnterBackground:)
|
|
69
69
|
name:UIApplicationDidEnterBackgroundNotification
|
|
70
70
|
object:nil];
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
73
73
|
selector:@selector(appDidBecomeActive:)
|
|
74
74
|
name:UIApplicationDidBecomeActiveNotification
|
|
@@ -121,8 +121,8 @@
|
|
|
121
121
|
- (void)sendProgressEvent:(float)currentTime duration:(float)duration {
|
|
122
122
|
if (self.onProgress) {
|
|
123
123
|
self.onProgress(@{
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
@"currentTime": @(currentTime),
|
|
125
|
+
@"duration": @(duration)
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
}
|
|
@@ -394,15 +394,20 @@
|
|
|
394
394
|
|
|
395
395
|
- (void)play {
|
|
396
396
|
if (_playerItem && _playerItem.status == AVPlayerItemStatusReadyToPlay) {
|
|
397
|
-
// Apply speed if set
|
|
398
|
-
if (_speed > 0 && _speed != 1.0f) {
|
|
399
|
-
float validSpeed = MAX(0.25f, MIN(4.0f, _speed));
|
|
400
|
-
_player.rate = validSpeed;
|
|
401
|
-
} else {
|
|
402
|
-
_player.rate = 1.0f;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
397
|
[_player play];
|
|
398
|
+
|
|
399
|
+
// Apply speed AFTER play() is called to ensure it's not reset
|
|
400
|
+
// Use a small delay to ensure play() has started
|
|
401
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
402
|
+
if (self->_speed > 0 && self->_speed != 1.0f) {
|
|
403
|
+
float validSpeed = MAX(0.25f, MIN(4.0f, self->_speed));
|
|
404
|
+
self->_player.rate = validSpeed;
|
|
405
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] Applied speed: %f after play", validSpeed);
|
|
406
|
+
} else {
|
|
407
|
+
self->_player.rate = 1.0f;
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
|
|
406
411
|
[self sendEvent:@"onPlaying" body:@{}];
|
|
407
412
|
RCTLogInfo(@"[UnifiedPlayerViewManager] play called");
|
|
408
413
|
} else {
|
|
@@ -490,13 +495,33 @@
|
|
|
490
495
|
#pragma mark - Notifications
|
|
491
496
|
|
|
492
497
|
- (void)playerItemDidReachEnd:(NSNotification *)notification {
|
|
493
|
-
RCTLogInfo(@"[UnifiedPlayerViewManager] Video ended, loop:
|
|
494
|
-
|
|
498
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] Video ended, loop: %@, speed: %f", _loop ? @"YES" : @"NO", _speed);
|
|
499
|
+
|
|
495
500
|
if (_loop) {
|
|
501
|
+
// Store current speed before seeking
|
|
502
|
+
float savedSpeed = _speed;
|
|
503
|
+
|
|
496
504
|
// Seek to beginning and play again
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
505
|
+
[_player seekToTime:kCMTimeZero completionHandler:^(BOOL finished) {
|
|
506
|
+
if (finished) {
|
|
507
|
+
[self->_player play];
|
|
508
|
+
// Restore playback speed AFTER play() is called
|
|
509
|
+
// Use multiple attempts to ensure speed is set
|
|
510
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
511
|
+
if (savedSpeed > 0 && savedSpeed != 1.0f) {
|
|
512
|
+
float validSpeed = MAX(0.25f, MIN(4.0f, savedSpeed));
|
|
513
|
+
self->_player.rate = validSpeed;
|
|
514
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] Restored speed: %f for loop (attempt 1)", validSpeed);
|
|
515
|
+
|
|
516
|
+
// Double-check after a bit more time
|
|
517
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
518
|
+
if (self->_player.rate != validSpeed && self->_player.rate > 0) {
|
|
519
|
+
self->_player.rate = validSpeed;
|
|
520
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] Restored speed: %f for loop (attempt 2)", validSpeed);
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
});
|
|
500
525
|
RCTLogInfo(@"[UnifiedPlayerViewManager] Looped video - restarted from beginning");
|
|
501
526
|
}
|
|
502
527
|
}];
|
|
@@ -562,7 +587,7 @@
|
|
|
562
587
|
// Generate the image
|
|
563
588
|
[imageGenerator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:currentTime]]
|
|
564
589
|
completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
|
|
565
|
-
|
|
590
|
+
if (error) {
|
|
566
591
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
567
592
|
completion(nil, error);
|
|
568
593
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-unified-player",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Unified Player",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
@@ -107,7 +107,11 @@
|
|
|
107
107
|
"git": {
|
|
108
108
|
"commitMessage": "chore: release ${version}",
|
|
109
109
|
"tagName": "v${version}",
|
|
110
|
-
"requireCleanWorkingDir": false
|
|
110
|
+
"requireCleanWorkingDir": false,
|
|
111
|
+
"push": true,
|
|
112
|
+
"pushArgs": [
|
|
113
|
+
"--force-with-lease"
|
|
114
|
+
]
|
|
111
115
|
},
|
|
112
116
|
"npm": {
|
|
113
117
|
"publish": true,
|