diff --git a/Sources/MUXSDKStats/MUXSDKPlayerBinding.m b/Sources/MUXSDKStats/MUXSDKPlayerBinding.m index 870e0354..cfd9a88e 100644 --- a/Sources/MUXSDKStats/MUXSDKPlayerBinding.m +++ b/Sources/MUXSDKStats/MUXSDKPlayerBinding.m @@ -256,22 +256,45 @@ - (void)handleDidPlayToEndTimeNotification:(NSNotification *)notification { # pragma mark AVPlayerItemAccessLog - (void)handleAVPlayerAccess:(NSNotification *)notif { - dispatch_async(dispatch_get_main_queue(), ^{ - BOOL isNotificationRelevant = [self isNotificationAboutCurrentPlayerItem:notif]; - if (isNotificationRelevant) { - AVPlayerItemAccessLog *accessLog = [((AVPlayerItem *)notif.object) accessLog]; - if (self.shouldTrackRenditionChanges) { - [self handleRenditionChangeInAccessLog:accessLog]; - } - if (self.shouldTrackBandwidthMetrics) { - [self calculateBandwidthMetricFromAccessLog:accessLog]; + __weak MUXSDKPlayerBinding *weakSelf = self; + + if (!NSThread.isMainThread) { + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf handleAVPlayerAccess:notif]; + }); + return; + } + + BOOL isNotificationRelevant = [self isNotificationAboutCurrentPlayerItem:notif]; + if (!isNotificationRelevant) { + return; + } + + // -[AVPlayerItem accessLog] can block so access it off the main thread: + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + AVPlayerItemAccessLog *accessLog = [(AVPlayerItem *)notif.object accessLog]; + + dispatch_async(dispatch_get_main_queue(), ^{ + BOOL isNotificationStillRelevant = [weakSelf isNotificationAboutCurrentPlayerItem:notif]; + if (!isNotificationStillRelevant) { + return; } - [self updateViewingLivestream:accessLog]; - [self updateFrameDropsFromAccessLog:accessLog]; - } + [weakSelf handleAVPlayerItemAccessLog:accessLog]; + }); }); } +- (void)handleAVPlayerItemAccessLog:(AVPlayerItemAccessLog *)accessLog { + if (self.shouldTrackRenditionChanges) { + [self handleRenditionChangeInAccessLog:accessLog]; + } + if (self.shouldTrackBandwidthMetrics) { + [self calculateBandwidthMetricFromAccessLog:accessLog]; + } + [self updateViewingLivestream:accessLog]; + [self updateFrameDropsFromAccessLog:accessLog]; +} + - (void)updateFrameDropsFromAccessLog:(AVPlayerItemAccessLog *)accessLog { AVPlayerItemAccessLogEvent *event = accessLog.events.lastObject; NSInteger loggedFrameDrops = event.numberOfDroppedVideoFrames;