react-native-tpstreams 1.1.0-debug.2 → 1.1.0-debug.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.
- package/ios/TPStreamsRNPlayerView.swift +264 -10
- package/package.json +1 -1
|
@@ -28,6 +28,14 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
28
28
|
private var pendingOfflineCredentialsCompletion: ((String?, Double) -> Void)?
|
|
29
29
|
private var _offlineLicenseExpireTime: Double = TPStreamsRNPlayerView.maxOfflineLicenseDuration
|
|
30
30
|
|
|
31
|
+
// Add a property to track when play() was called
|
|
32
|
+
private var playCallTime: CFAbsoluteTime?
|
|
33
|
+
private var playerReadyTime: CFAbsoluteTime?
|
|
34
|
+
private var playbackStartTime: CFAbsoluteTime?
|
|
35
|
+
|
|
36
|
+
// Add a property to track when setup started (for relative timing)
|
|
37
|
+
private var setupStartTime: CFAbsoluteTime?
|
|
38
|
+
|
|
31
39
|
@objc var videoId: NSString = ""
|
|
32
40
|
@objc var accessToken: NSString = ""
|
|
33
41
|
@objc var shouldAutoPlay: Bool = true
|
|
@@ -57,11 +65,17 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
57
65
|
override init(frame: CGRect) {
|
|
58
66
|
super.init(frame: frame)
|
|
59
67
|
backgroundColor = .black
|
|
68
|
+
let deviceModel = UIDevice.current.model
|
|
69
|
+
let systemVersion = UIDevice.current.systemVersion
|
|
70
|
+
print("⏱️ [TPStreams] TPStreamsRNPlayerView init() - Device: \(deviceModel), iOS: \(systemVersion)")
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
required init?(coder: NSCoder) {
|
|
63
74
|
super.init(coder: coder)
|
|
64
75
|
backgroundColor = .black
|
|
76
|
+
let deviceModel = UIDevice.current.model
|
|
77
|
+
let systemVersion = UIDevice.current.systemVersion
|
|
78
|
+
print("⏱️ [TPStreams] TPStreamsRNPlayerView init(coder:) - Device: \(deviceModel), iOS: \(systemVersion)")
|
|
65
79
|
}
|
|
66
80
|
|
|
67
81
|
override func layoutSubviews() {
|
|
@@ -71,38 +85,93 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
71
85
|
|
|
72
86
|
override func didSetProps(_ changedProps: [String]!) {
|
|
73
87
|
super.didSetProps(changedProps)
|
|
88
|
+
let propsTime = CFAbsoluteTimeGetCurrent()
|
|
89
|
+
print("⏱️ [TPStreams] didSetProps() called with props: \(changedProps ?? [])")
|
|
74
90
|
schedulePlayerSetup()
|
|
91
|
+
let propsDuration = CFAbsoluteTimeGetCurrent() - propsTime
|
|
92
|
+
print("⏱️ [TPStreams] didSetProps() took: \(String(format: "%.3f", propsDuration * 1000))ms")
|
|
75
93
|
}
|
|
76
94
|
|
|
77
95
|
private func schedulePlayerSetup() {
|
|
78
|
-
guard !setupScheduled else {
|
|
96
|
+
guard !setupScheduled else {
|
|
97
|
+
print("⏱️ [TPStreams] setupPlayer() already scheduled, skipping")
|
|
98
|
+
return
|
|
99
|
+
}
|
|
79
100
|
|
|
101
|
+
let scheduleTime = CFAbsoluteTimeGetCurrent()
|
|
80
102
|
setupScheduled = true
|
|
103
|
+
print("⏱️ [TPStreams] schedulePlayerSetup() - scheduling async setup")
|
|
81
104
|
DispatchQueue.main.async { [weak self] in
|
|
105
|
+
let asyncDelay = CFAbsoluteTimeGetCurrent() - scheduleTime
|
|
106
|
+
print("⏱️ [TPStreams] schedulePlayerSetup() - async dispatch delay: \(String(format: "%.3f", asyncDelay * 1000))ms")
|
|
82
107
|
self?.setupPlayer()
|
|
83
108
|
}
|
|
84
109
|
}
|
|
85
110
|
|
|
86
111
|
private func setupPlayer() {
|
|
112
|
+
let setupStartTime = CFAbsoluteTimeGetCurrent()
|
|
113
|
+
self.setupStartTime = setupStartTime // Store for relative timing
|
|
114
|
+
print("⏱️ [TPStreams] ========== setupPlayer() STARTED ==========")
|
|
115
|
+
print("⏱️ [TPStreams] videoId: \(videoId), accessToken length: \(accessToken.length)")
|
|
116
|
+
|
|
117
|
+
// Cleanup
|
|
118
|
+
let cleanupStartTime = CFAbsoluteTimeGetCurrent()
|
|
87
119
|
cleanupPlayer()
|
|
120
|
+
let cleanupDuration = CFAbsoluteTimeGetCurrent() - cleanupStartTime
|
|
121
|
+
print("⏱️ [TPStreams] cleanupPlayer() took: \(String(format: "%.3f", cleanupDuration * 1000))ms")
|
|
122
|
+
|
|
123
|
+
// Download check
|
|
124
|
+
let downloadCheckStartTime = CFAbsoluteTimeGetCurrent()
|
|
125
|
+
let isDownloaded = TPStreamsDownloadManager.shared.isAssetDownloaded(assetID: videoId as String)
|
|
126
|
+
let downloadCheckDuration = CFAbsoluteTimeGetCurrent() - downloadCheckStartTime
|
|
127
|
+
print("⏱️ [TPStreams] Download check took: \(String(format: "%.3f", downloadCheckDuration * 1000))ms (isDownloaded: \(isDownloaded))")
|
|
88
128
|
|
|
89
|
-
|
|
129
|
+
// Player creation
|
|
130
|
+
let playerCreateStartTime = CFAbsoluteTimeGetCurrent()
|
|
131
|
+
player = isDownloaded
|
|
90
132
|
? createOfflinePlayer()
|
|
91
133
|
: createOnlinePlayer()
|
|
134
|
+
let playerCreateDuration = CFAbsoluteTimeGetCurrent() - playerCreateStartTime
|
|
135
|
+
print("⏱️ [TPStreams] Player creation took: \(String(format: "%.3f", playerCreateDuration * 1000))ms")
|
|
92
136
|
|
|
93
137
|
guard player != nil else {
|
|
94
|
-
print("Failed to create player - invalid videoId or accessToken")
|
|
138
|
+
print("❌ [TPStreams] Failed to create player - invalid videoId or accessToken")
|
|
95
139
|
setupScheduled = false
|
|
96
140
|
return
|
|
97
141
|
}
|
|
142
|
+
|
|
143
|
+
// Token delegate setup
|
|
144
|
+
let tokenDelegateStartTime = CFAbsoluteTimeGetCurrent()
|
|
98
145
|
setupTokenDelegate()
|
|
146
|
+
let tokenDelegateDuration = CFAbsoluteTimeGetCurrent() - tokenDelegateStartTime
|
|
147
|
+
print("⏱️ [TPStreams] setupTokenDelegate() took: \(String(format: "%.3f", tokenDelegateDuration * 1000))ms")
|
|
148
|
+
|
|
149
|
+
// View configuration
|
|
150
|
+
let configStartTime = CFAbsoluteTimeGetCurrent()
|
|
99
151
|
configurePlayerView()
|
|
152
|
+
let configDuration = CFAbsoluteTimeGetCurrent() - configStartTime
|
|
153
|
+
print("⏱️ [TPStreams] configurePlayerView() took: \(String(format: "%.3f", configDuration * 1000))ms")
|
|
154
|
+
|
|
155
|
+
// Observer setup
|
|
156
|
+
let observerStartTime = CFAbsoluteTimeGetCurrent()
|
|
100
157
|
observePlayerChanges()
|
|
158
|
+
let observerDuration = CFAbsoluteTimeGetCurrent() - observerStartTime
|
|
159
|
+
print("⏱️ [TPStreams] observePlayerChanges() took: \(String(format: "%.3f", observerDuration * 1000))ms")
|
|
160
|
+
|
|
101
161
|
setupScheduled = false
|
|
162
|
+
|
|
163
|
+
let totalDuration = CFAbsoluteTimeGetCurrent() - setupStartTime
|
|
164
|
+
print("⏱️ [TPStreams] ========== setupPlayer() COMPLETED in \(String(format: "%.3f", totalDuration * 1000))ms ==========")
|
|
102
165
|
}
|
|
103
166
|
|
|
104
167
|
private func cleanupPlayer() {
|
|
168
|
+
let cleanupStartTime = CFAbsoluteTimeGetCurrent()
|
|
169
|
+
|
|
170
|
+
let removeObserversStartTime = CFAbsoluteTimeGetCurrent()
|
|
105
171
|
removeObservers()
|
|
172
|
+
let removeObserversDuration = CFAbsoluteTimeGetCurrent() - removeObserversStartTime
|
|
173
|
+
print("⏱️ [TPStreams] removeObservers() took: \(String(format: "%.3f", removeObserversDuration * 1000))ms")
|
|
174
|
+
|
|
106
175
|
player?.pause()
|
|
107
176
|
|
|
108
177
|
playerViewController?.view.removeFromSuperview()
|
|
@@ -111,6 +180,11 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
111
180
|
|
|
112
181
|
player?.replaceCurrentItem(with: nil)
|
|
113
182
|
player = nil
|
|
183
|
+
|
|
184
|
+
let totalCleanupDuration = CFAbsoluteTimeGetCurrent() - cleanupStartTime
|
|
185
|
+
if totalCleanupDuration > 0.001 { // Only log if cleanup took meaningful time
|
|
186
|
+
print("⏱️ [TPStreams] cleanupPlayer() total: \(String(format: "%.3f", totalCleanupDuration * 1000))ms")
|
|
187
|
+
}
|
|
114
188
|
}
|
|
115
189
|
|
|
116
190
|
private func removeObservers() {
|
|
@@ -125,17 +199,37 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
125
199
|
}
|
|
126
200
|
|
|
127
201
|
private func createOfflinePlayer() -> TPAVPlayer? {
|
|
128
|
-
|
|
129
|
-
|
|
202
|
+
let startTime = CFAbsoluteTimeGetCurrent()
|
|
203
|
+
guard videoId.length > 0 else {
|
|
204
|
+
print("❌ [TPStreams] createOfflinePlayer() - invalid videoId")
|
|
205
|
+
return nil
|
|
206
|
+
}
|
|
207
|
+
print("⏱️ [TPStreams] Creating offline player for videoId: \(videoId)")
|
|
208
|
+
let player = TPAVPlayer(offlineAssetId: videoId as String) { [weak self] error in
|
|
209
|
+
let errorTime = CFAbsoluteTimeGetCurrent()
|
|
210
|
+
print("⏱️ [TPStreams] Offline player error callback triggered at: \(String(format: "%.3f", errorTime * 1000))ms")
|
|
130
211
|
self?.handlePlayerError(error, context: "Offline setup")
|
|
131
212
|
}
|
|
213
|
+
let duration = CFAbsoluteTimeGetCurrent() - startTime
|
|
214
|
+
print("⏱️ [TPStreams] TPAVPlayer(offline) init took: \(String(format: "%.3f", duration * 1000))ms")
|
|
215
|
+
return player
|
|
132
216
|
}
|
|
133
217
|
|
|
134
218
|
private func createOnlinePlayer() -> TPAVPlayer? {
|
|
135
|
-
|
|
136
|
-
|
|
219
|
+
let startTime = CFAbsoluteTimeGetCurrent()
|
|
220
|
+
guard videoId.length > 0, accessToken.length > 0 else {
|
|
221
|
+
print("❌ [TPStreams] createOnlinePlayer() - invalid videoId or accessToken")
|
|
222
|
+
return nil
|
|
223
|
+
}
|
|
224
|
+
print("⏱️ [TPStreams] Creating online player for videoId: \(videoId)")
|
|
225
|
+
let player = TPAVPlayer(assetID: videoId as String, accessToken: accessToken as String) { [weak self] error in
|
|
226
|
+
let errorTime = CFAbsoluteTimeGetCurrent()
|
|
227
|
+
// print("⏱️ [TPStreams] Online player error callback triggered at: \(String(format: "%.3f", errorTime * 1000))ms")
|
|
137
228
|
self?.handlePlayerError(error, context: "Online setup")
|
|
138
229
|
}
|
|
230
|
+
let duration = CFAbsoluteTimeGetCurrent() - startTime
|
|
231
|
+
print("⏱️ [TPStreams] TPAVPlayer(online) init took: \(String(format: "%.3f", duration * 1000))ms")
|
|
232
|
+
return player
|
|
139
233
|
}
|
|
140
234
|
|
|
141
235
|
private func handlePlayerError(_ error: Error?, context: String) {
|
|
@@ -150,7 +244,14 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
150
244
|
}
|
|
151
245
|
|
|
152
246
|
private func configurePlayerView() {
|
|
153
|
-
|
|
247
|
+
let configStartTime = CFAbsoluteTimeGetCurrent()
|
|
248
|
+
guard let player = player else {
|
|
249
|
+
print("❌ [TPStreams] configurePlayerView() - player is nil")
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// License renewal setup
|
|
254
|
+
let licenseSetupStartTime = CFAbsoluteTimeGetCurrent()
|
|
154
255
|
player.onRequestOfflineLicenseRenewal = { [weak self] assetId, completion in
|
|
155
256
|
guard let self = self else {
|
|
156
257
|
completion(nil, 0)
|
|
@@ -160,53 +261,132 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
160
261
|
self.pendingOfflineCredentialsCompletion = completion
|
|
161
262
|
self.onAccessTokenExpired?(["videoId": assetId])
|
|
162
263
|
}
|
|
264
|
+
let licenseSetupDuration = CFAbsoluteTimeGetCurrent() - licenseSetupStartTime
|
|
265
|
+
print("⏱️ [TPStreams] License renewal setup took: \(String(format: "%.3f", licenseSetupDuration * 1000))ms")
|
|
163
266
|
|
|
267
|
+
// Config builder
|
|
268
|
+
let configBuilderStartTime = CFAbsoluteTimeGetCurrent()
|
|
164
269
|
let configBuilder = createPlayerConfigBuilder()
|
|
270
|
+
let configBuilderDuration = CFAbsoluteTimeGetCurrent() - configBuilderStartTime
|
|
271
|
+
print("⏱️ [TPStreams] createPlayerConfigBuilder() took: \(String(format: "%.3f", configBuilderDuration * 1000))ms")
|
|
272
|
+
|
|
273
|
+
// View controller creation
|
|
274
|
+
let vcCreateStartTime = CFAbsoluteTimeGetCurrent()
|
|
165
275
|
let playerVC = TPStreamPlayerViewController()
|
|
166
276
|
playerVC.player = player
|
|
167
277
|
playerVC.config = configBuilder.build()
|
|
278
|
+
let vcCreateDuration = CFAbsoluteTimeGetCurrent() - vcCreateStartTime
|
|
279
|
+
print("⏱️ [TPStreams] TPStreamPlayerViewController creation took: \(String(format: "%.3f", vcCreateDuration * 1000))ms")
|
|
168
280
|
|
|
281
|
+
// Attach view controller
|
|
282
|
+
let attachStartTime = CFAbsoluteTimeGetCurrent()
|
|
169
283
|
attachPlayerViewController(playerVC)
|
|
284
|
+
let attachDuration = CFAbsoluteTimeGetCurrent() - attachStartTime
|
|
285
|
+
print("⏱️ [TPStreams] attachPlayerViewController() took: \(String(format: "%.3f", attachDuration * 1000))ms")
|
|
286
|
+
|
|
287
|
+
if shouldAutoPlay {
|
|
288
|
+
let playStartTime = CFAbsoluteTimeGetCurrent()
|
|
289
|
+
playCallTime = playStartTime
|
|
290
|
+
print("⏱️ [TPStreams] 🎬 player.play() CALLED at: \(String(format: "%.3f", playStartTime * 1000))ms")
|
|
291
|
+
player.play()
|
|
292
|
+
let playDuration = CFAbsoluteTimeGetCurrent() - playStartTime
|
|
293
|
+
print("⏱️ [TPStreams] player.play() took: \(String(format: "%.3f", playDuration * 1000))ms")
|
|
294
|
+
}
|
|
170
295
|
|
|
171
|
-
if shouldAutoPlay { player.play() }
|
|
172
296
|
playerViewController = playerVC
|
|
297
|
+
|
|
298
|
+
let totalConfigDuration = CFAbsoluteTimeGetCurrent() - configStartTime
|
|
299
|
+
print("⏱️ [TPStreams] configurePlayerView() total: \(String(format: "%.3f", totalConfigDuration * 1000))ms")
|
|
173
300
|
}
|
|
174
301
|
|
|
175
302
|
private func createPlayerConfigBuilder() -> TPStreamPlayerConfigurationBuilder {
|
|
303
|
+
let builderStartTime = CFAbsoluteTimeGetCurrent()
|
|
304
|
+
|
|
305
|
+
let parseStartTime = CFAbsoluteTimeGetCurrent()
|
|
176
306
|
let metadataDict = parseMetadataJSON(from: downloadMetadata)
|
|
307
|
+
let parseDuration = CFAbsoluteTimeGetCurrent() - parseStartTime
|
|
308
|
+
print("⏱️ [TPStreams] parseMetadataJSON() took: \(String(format: "%.3f", parseDuration * 1000))ms")
|
|
309
|
+
|
|
310
|
+
let builderCreateStartTime = CFAbsoluteTimeGetCurrent()
|
|
177
311
|
let configBuilder = TPStreamPlayerConfigurationBuilder()
|
|
178
312
|
.setPreferredForwardDuration(15)
|
|
179
313
|
.setPreferredRewindDuration(5)
|
|
180
314
|
.setprogressBarThumbColor(.systemBlue)
|
|
181
315
|
.setwatchedProgressTrackColor(.systemBlue)
|
|
182
316
|
.setDownloadMetadata(metadataDict)
|
|
317
|
+
let builderCreateDuration = CFAbsoluteTimeGetCurrent() - builderCreateStartTime
|
|
318
|
+
print("⏱️ [TPStreams] ConfigBuilder creation took: \(String(format: "%.3f", builderCreateDuration * 1000))ms")
|
|
183
319
|
|
|
320
|
+
let licenseStartTime = CFAbsoluteTimeGetCurrent()
|
|
184
321
|
configBuilder.setLicenseDurationSeconds(offlineLicenseExpireTime)
|
|
322
|
+
let licenseDuration = CFAbsoluteTimeGetCurrent() - licenseStartTime
|
|
323
|
+
print("⏱️ [TPStreams] setLicenseDurationSeconds() took: \(String(format: "%.3f", licenseDuration * 1000))ms")
|
|
185
324
|
|
|
186
325
|
if enableDownload {
|
|
326
|
+
let downloadOptionStartTime = CFAbsoluteTimeGetCurrent()
|
|
187
327
|
configBuilder.showDownloadOption()
|
|
328
|
+
let downloadOptionDuration = CFAbsoluteTimeGetCurrent() - downloadOptionStartTime
|
|
329
|
+
print("⏱️ [TPStreams] showDownloadOption() took: \(String(format: "%.3f", downloadOptionDuration * 1000))ms")
|
|
188
330
|
}
|
|
189
331
|
|
|
332
|
+
let totalBuilderDuration = CFAbsoluteTimeGetCurrent() - builderStartTime
|
|
333
|
+
print("⏱️ [TPStreams] createPlayerConfigBuilder() total: \(String(format: "%.3f", totalBuilderDuration * 1000))ms")
|
|
334
|
+
|
|
190
335
|
return configBuilder
|
|
191
336
|
}
|
|
192
337
|
|
|
193
338
|
private func attachPlayerViewController(_ playerVC: TPStreamPlayerViewController) {
|
|
194
|
-
|
|
339
|
+
let attachStartTime = CFAbsoluteTimeGetCurrent()
|
|
340
|
+
guard let parentVC = reactViewController() else {
|
|
341
|
+
print("❌ [TPStreams] attachPlayerViewController() - reactViewController() is nil")
|
|
342
|
+
return
|
|
343
|
+
}
|
|
195
344
|
|
|
345
|
+
let addChildStartTime = CFAbsoluteTimeGetCurrent()
|
|
196
346
|
parentVC.addChild(playerVC)
|
|
347
|
+
let addChildDuration = CFAbsoluteTimeGetCurrent() - addChildStartTime
|
|
348
|
+
print("⏱️ [TPStreams] addChild() took: \(String(format: "%.3f", addChildDuration * 1000))ms")
|
|
349
|
+
|
|
197
350
|
addSubview(playerVC.view)
|
|
198
351
|
playerVC.view.frame = bounds
|
|
199
352
|
playerVC.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
200
353
|
playerVC.view.isHidden = false
|
|
201
354
|
bringSubviewToFront(playerVC.view)
|
|
355
|
+
|
|
356
|
+
let didMoveStartTime = CFAbsoluteTimeGetCurrent()
|
|
202
357
|
playerVC.didMove(toParent: parentVC)
|
|
358
|
+
let didMoveDuration = CFAbsoluteTimeGetCurrent() - didMoveStartTime
|
|
359
|
+
print("⏱️ [TPStreams] didMove(toParent:) took: \(String(format: "%.3f", didMoveDuration * 1000))ms")
|
|
360
|
+
|
|
361
|
+
let totalAttachDuration = CFAbsoluteTimeGetCurrent() - attachStartTime
|
|
362
|
+
print("⏱️ [TPStreams] attachPlayerViewController() total: \(String(format: "%.3f", totalAttachDuration * 1000))ms")
|
|
203
363
|
}
|
|
204
364
|
|
|
205
365
|
private func observePlayerChanges() {
|
|
366
|
+
let observerStartTime = CFAbsoluteTimeGetCurrent()
|
|
367
|
+
|
|
368
|
+
let seekObserverStartTime = CFAbsoluteTimeGetCurrent()
|
|
206
369
|
setupSeekObserver()
|
|
370
|
+
let seekObserverDuration = CFAbsoluteTimeGetCurrent() - seekObserverStartTime
|
|
371
|
+
print("⏱️ [TPStreams] setupSeekObserver() took: \(String(format: "%.3f", seekObserverDuration * 1000))ms")
|
|
372
|
+
|
|
373
|
+
let playerStateObserverStartTime = CFAbsoluteTimeGetCurrent()
|
|
207
374
|
setupPlayerStateObserver()
|
|
375
|
+
let playerStateObserverDuration = CFAbsoluteTimeGetCurrent() - playerStateObserverStartTime
|
|
376
|
+
print("⏱️ [TPStreams] setupPlayerStateObserver() took: \(String(format: "%.3f", playerStateObserverDuration * 1000))ms")
|
|
377
|
+
|
|
378
|
+
let playbackSpeedObserverStartTime = CFAbsoluteTimeGetCurrent()
|
|
208
379
|
setupPlaybackSpeedObserver()
|
|
380
|
+
let playbackSpeedObserverDuration = CFAbsoluteTimeGetCurrent() - playbackSpeedObserverStartTime
|
|
381
|
+
print("⏱️ [TPStreams] setupPlaybackSpeedObserver() took: \(String(format: "%.3f", playbackSpeedObserverDuration * 1000))ms")
|
|
382
|
+
|
|
383
|
+
let playingStateObserverStartTime = CFAbsoluteTimeGetCurrent()
|
|
209
384
|
setupPlayingStateObserver()
|
|
385
|
+
let playingStateObserverDuration = CFAbsoluteTimeGetCurrent() - playingStateObserverStartTime
|
|
386
|
+
print("⏱️ [TPStreams] setupPlayingStateObserver() took: \(String(format: "%.3f", playingStateObserverDuration * 1000))ms")
|
|
387
|
+
|
|
388
|
+
let totalObserverDuration = CFAbsoluteTimeGetCurrent() - observerStartTime
|
|
389
|
+
print("⏱️ [TPStreams] observePlayerChanges() total: \(String(format: "%.3f", totalObserverDuration * 1000))ms")
|
|
210
390
|
}
|
|
211
391
|
|
|
212
392
|
private func setupSeekObserver() {
|
|
@@ -245,6 +425,37 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
245
425
|
guard let player = player else { return }
|
|
246
426
|
|
|
247
427
|
playerStateObserver = player.observe(\.status, options: [.new, .initial]) { [weak self] player, _ in
|
|
428
|
+
let statusTime = CFAbsoluteTimeGetCurrent()
|
|
429
|
+
let statusString: String
|
|
430
|
+
switch player.status {
|
|
431
|
+
case .unknown:
|
|
432
|
+
statusString = "unknown"
|
|
433
|
+
case .readyToPlay:
|
|
434
|
+
statusString = "readyToPlay"
|
|
435
|
+
if self?.playerReadyTime == nil {
|
|
436
|
+
self?.playerReadyTime = statusTime
|
|
437
|
+
if let playCallTime = self?.playCallTime {
|
|
438
|
+
let timeToReady = statusTime - playCallTime
|
|
439
|
+
print("⏱️ [TPStreams] ✅ Player READY TO PLAY - Time from play() call: \(String(format: "%.3f", timeToReady * 1000))ms")
|
|
440
|
+
} else {
|
|
441
|
+
print("⏱️ [TPStreams] ✅ Player READY TO PLAY")
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
case .failed:
|
|
445
|
+
statusString = "failed"
|
|
446
|
+
print("❌ [TPStreams] Player status: FAILED")
|
|
447
|
+
@unknown default:
|
|
448
|
+
statusString = "unknown"
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Show relative time from setup start instead of absolute timestamp
|
|
452
|
+
if let setupStart = self?.setupStartTime {
|
|
453
|
+
let relativeTime = statusTime - setupStart
|
|
454
|
+
print("⏱️ [TPStreams] Player status changed to: \(statusString) at +\(String(format: "%.3f", relativeTime * 1000))ms from setup start")
|
|
455
|
+
} else {
|
|
456
|
+
print("⏱️ [TPStreams] Player status changed to: \(statusString)")
|
|
457
|
+
}
|
|
458
|
+
|
|
248
459
|
DispatchQueue.main.async {
|
|
249
460
|
let state = self?.mapPlayerStateToAndroid(player.status) ?? PlaybackState.idle.rawValue
|
|
250
461
|
self?.onPlayerStateChanged?(["playbackState": state])
|
|
@@ -252,6 +463,46 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
252
463
|
}
|
|
253
464
|
|
|
254
465
|
timeControlStatusObserver = player.observe(\.timeControlStatus, options: [.new, .initial]) { [weak self] player, _ in
|
|
466
|
+
let controlStatusTime = CFAbsoluteTimeGetCurrent()
|
|
467
|
+
let statusString: String
|
|
468
|
+
switch player.timeControlStatus {
|
|
469
|
+
case .paused:
|
|
470
|
+
statusString = "paused"
|
|
471
|
+
case .waitingToPlayAtSpecifiedRate:
|
|
472
|
+
statusString = "waitingToPlayAtSpecifiedRate"
|
|
473
|
+
if let setupStart = self?.setupStartTime {
|
|
474
|
+
let relativeTime = controlStatusTime - setupStart
|
|
475
|
+
print("⏱️ [TPStreams] ⏳ Player WAITING TO PLAY (buffering) at +\(String(format: "%.3f", relativeTime * 1000))ms from setup start")
|
|
476
|
+
} else {
|
|
477
|
+
print("⏱️ [TPStreams] ⏳ Player WAITING TO PLAY (buffering)")
|
|
478
|
+
}
|
|
479
|
+
case .playing:
|
|
480
|
+
statusString = "playing"
|
|
481
|
+
if self?.playbackStartTime == nil {
|
|
482
|
+
self?.playbackStartTime = controlStatusTime
|
|
483
|
+
if let playCallTime = self?.playCallTime {
|
|
484
|
+
let timeToPlay = controlStatusTime - playCallTime
|
|
485
|
+
print("⏱️ [TPStreams] 🎥 PLAYBACK STARTED! Time from play() call: \(String(format: "%.3f", timeToPlay * 1000))ms")
|
|
486
|
+
if let readyTime = self?.playerReadyTime {
|
|
487
|
+
let bufferingTime = controlStatusTime - readyTime
|
|
488
|
+
print("⏱️ [TPStreams] 📊 Buffering time (readyToPlay → playing): \(String(format: "%.3f", bufferingTime * 1000))ms")
|
|
489
|
+
}
|
|
490
|
+
} else {
|
|
491
|
+
print("⏱️ [TPStreams] 🎥 PLAYBACK STARTED!")
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
@unknown default:
|
|
495
|
+
statusString = "unknown"
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Show relative time from setup start
|
|
499
|
+
if let setupStart = self?.setupStartTime {
|
|
500
|
+
let relativeTime = controlStatusTime - setupStart
|
|
501
|
+
print("⏱️ [TPStreams] TimeControlStatus changed to: \(statusString) at +\(String(format: "%.3f", relativeTime * 1000))ms from setup start")
|
|
502
|
+
} else {
|
|
503
|
+
print("⏱️ [TPStreams] TimeControlStatus changed to: \(statusString)")
|
|
504
|
+
}
|
|
505
|
+
|
|
255
506
|
DispatchQueue.main.async {
|
|
256
507
|
let state = self?.mapPlayerStateToAndroid(player.status, timeControlStatus: player.timeControlStatus) ?? PlaybackState.idle.rawValue
|
|
257
508
|
self?.onPlayerStateChanged?(["playbackState": state])
|
|
@@ -284,7 +535,10 @@ class TPStreamsRNPlayerView: UIView {
|
|
|
284
535
|
}
|
|
285
536
|
|
|
286
537
|
private func setupTokenDelegate() {
|
|
538
|
+
let delegateStartTime = CFAbsoluteTimeGetCurrent()
|
|
287
539
|
TPStreamsDownloadModule.shared?.setAccessTokenDelegate(self)
|
|
540
|
+
let delegateDuration = CFAbsoluteTimeGetCurrent() - delegateStartTime
|
|
541
|
+
print("⏱️ [TPStreams] setupTokenDelegate() took: \(String(format: "%.3f", delegateDuration * 1000))ms")
|
|
288
542
|
}
|
|
289
543
|
|
|
290
544
|
private static func sanitizeLicenseDuration(_ value: Double) -> Double {
|