@@ -124,6 +124,7 @@ struct YoutubePlayerView: UIViewRepresentable {
124124 let shouldForceSeekJS = isRangeChanged ? " true " : " false "
125125 let playbackControlJS = isPlaying
126126 ? """
127+ window.kpAutoplayAudioRestoreAttempted = false;
127128 if (window.kpApplyDesiredRange) {
128129 window.kpApplyDesiredRange( \( shouldForceSeekJS) );
129130 if (window.kpScheduleAutoplayRetry) {
@@ -140,6 +141,11 @@ struct YoutubePlayerView: UIViewRepresentable {
140141 if (window.kpStopAutoplayRetry) {
141142 window.kpStopAutoplayRetry();
142143 }
144+ window.kpAutoplayMutedFallbackActive = false;
145+ window.kpAutoplayAudioRestoreAttempted = false;
146+ if (window.kpPlayer.unMute) {
147+ window.kpPlayer.unMute();
148+ }
143149 if ( \( shouldForceSeekJS) ) {
144150 window.kpPlayer.seekTo(window.kpDesiredStart, true);
145151 }
@@ -185,7 +191,6 @@ struct YoutubePlayerView: UIViewRepresentable {
185191 navigationAction. navigationType == . linkActivated
186192 || navigationAction. navigationType == . formSubmitted
187193 || navigationAction. navigationType == . formResubmitted
188- || navigationAction. targetFrame == nil
189194
190195 guard isUserNavigation else {
191196 decisionHandler ( . allow)
@@ -267,6 +272,9 @@ struct YoutubePlayerView: UIViewRepresentable {
267272 window.kpAutoplayRetryCount = 0;
268273 window.kpAutoplayMaxRetryCount = 14;
269274 window.kpAutoplayRetryDelayMs = 220;
275+ window.kpAutoplayMuteFallbackAfterCount = 3;
276+ window.kpAutoplayMutedFallbackActive = false;
277+ window.kpAutoplayAudioRestoreAttempted = false;
270278
271279 window.kpStopAutoplayRetry = function() {
272280 if (window.kpAutoplayRetryTimer) {
@@ -308,6 +316,9 @@ struct YoutubePlayerView: UIViewRepresentable {
308316 window.kpPlayer.seekTo(targetStart, true);
309317 }
310318
319+ if (window.kpAutoplayMutedFallbackActive && window.kpPlayer.mute) {
320+ window.kpPlayer.mute();
321+ }
311322 window.kpPlayer.playVideo();
312323 };
313324
@@ -337,6 +348,13 @@ struct YoutubePlayerView: UIViewRepresentable {
337348 }
338349
339350 window.kpAutoplayRetryCount += 1;
351+ if (
352+ !window.kpAutoplayMutedFallbackActive
353+ && window.kpAutoplayRetryCount >= window.kpAutoplayMuteFallbackAfterCount
354+ ) {
355+ window.kpAutoplayMutedFallbackActive = true;
356+ window.kpAutoplayAudioRestoreAttempted = false;
357+ }
340358 window.kpScheduleAutoplayRetry(false);
341359 }, window.kpAutoplayRetryDelayMs);
342360 };
@@ -398,11 +416,16 @@ struct YoutubePlayerView: UIViewRepresentable {
398416 events: {
399417 onReady: function() {
400418 window.kpPlayerReady = true;
419+ window.kpAutoplayMutedFallbackActive = false;
420+ window.kpAutoplayAudioRestoreAttempted = false;
401421 if (window.kpShouldAutoplay) {
402422 window.kpApplyDesiredRange(true);
403423 window.kpStartRangeLoop();
404424 window.kpScheduleAutoplayRetry(true);
405425 } else {
426+ if (window.kpPlayer.unMute) {
427+ window.kpPlayer.unMute();
428+ }
406429 window.kpPlayer.seekTo(window.kpDesiredStart, true);
407430 window.kpPlayer.pauseVideo();
408431 }
@@ -415,6 +438,38 @@ struct YoutubePlayerView: UIViewRepresentable {
415438
416439 if (state === 1 || state === 3) {
417440 window.kpStopAutoplayRetry();
441+ if (
442+ window.kpAutoplayMutedFallbackActive
443+ && !window.kpAutoplayAudioRestoreAttempted
444+ ) {
445+ window.kpAutoplayAudioRestoreAttempted = true;
446+ setTimeout(function() {
447+ if (
448+ !window.kpShouldAutoplay
449+ || !window.kpPlayer
450+ || !window.kpPlayer.unMute
451+ ) {
452+ return;
453+ }
454+
455+ window.kpPlayer.unMute();
456+
457+ var stateAfterUnmute = Number(
458+ window.kpPlayer.getPlayerState
459+ ? window.kpPlayer.getPlayerState()
460+ : -1
461+ );
462+ if (stateAfterUnmute === 1 || stateAfterUnmute === 3) {
463+ window.kpAutoplayMutedFallbackActive = false;
464+ return;
465+ }
466+
467+ if (window.kpPlayer.mute) {
468+ window.kpPlayer.mute();
469+ }
470+ window.kpPlayer.playVideo();
471+ }, 160);
472+ }
418473 return;
419474 }
420475
0 commit comments