Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 1213775

Browse files
Huaba93jfversluis
andauthored
Ensured that observers are added only once (#928)
* Ensured that observers are added only once * renamed item to playerItem according to @pictos suggestion Co-authored-by: Gerald Versluis <[email protected]>
1 parent b3df22a commit 1213775

File tree

1 file changed

+58
-19
lines changed

1 file changed

+58
-19
lines changed

src/CommunityToolkit/Xamarin.CommunityToolkit/Views/MediaElement/iOS/MediaElementRenderer.ios.cs

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ public class MediaElementRenderer : ViewRenderer<ToolKitMediaElement, UIView>
2626
protected IDisposable rateObserver;
2727
protected IDisposable volumeObserver;
2828
bool idleTimerDisabled = false;
29+
AVPlayerItem playerItem;
2930

30-
public MediaElementRenderer() =>
31-
playedToEndObserver = NSNotificationCenter.DefaultCenter.AddObserver(AVPlayerItem.DidPlayToEndTimeNotification, PlayedToEnd);
31+
public MediaElementRenderer() => AddPlayedToEndObserver();
3232

3333
protected virtual void SetKeepScreenOn(bool value)
3434
{
@@ -81,18 +81,16 @@ protected virtual void UpdateSource()
8181
asset = AVAsset.FromUrl(NSUrl.FromFilename(fileSource.File));
8282
}
8383

84-
var item = new AVPlayerItem(asset);
85-
DisposeObservers(ref statusObserver);
86-
87-
statusObserver = item.AddObserver("status", NSKeyValueObservingOptions.New, ObserveStatus);
84+
playerItem = new AVPlayerItem(asset);
85+
AddStatusObserver();
8886

8987
if (avPlayerViewController.Player != null)
90-
avPlayerViewController.Player.ReplaceCurrentItemWithPlayerItem(item);
88+
avPlayerViewController.Player.ReplaceCurrentItemWithPlayerItem(playerItem);
9189
else
9290
{
93-
avPlayerViewController.Player = new AVPlayer(item);
94-
rateObserver = avPlayerViewController.Player.AddObserver("rate", NSKeyValueObservingOptions.New, ObserveRate);
95-
volumeObserver = avPlayerViewController.Player.AddObserver("volume", NSKeyValueObservingOptions.New, ObserveVolume);
91+
avPlayerViewController.Player = new AVPlayer(playerItem);
92+
AddRateObserver();
93+
AddVolumeObserver();
9694
}
9795

9896
UpdateVolume();
@@ -104,7 +102,7 @@ protected virtual void UpdateSource()
104102
{
105103
avPlayerViewController.Player?.Pause();
106104
avPlayerViewController.Player?.ReplaceCurrentItemWithPlayerItem(null);
107-
DisposeObservers(ref statusObserver);
105+
DestroyStatusObserver();
108106
Controller.CurrentState = MediaElementState.Stopped;
109107
}
110108
}
@@ -380,13 +378,10 @@ protected override void OnElementChanged(ElementChangedEventArgs<MediaElement> e
380378
AVAudioSession.SharedInstance().SetActive(false);
381379
}
382380

383-
if (playedToEndObserver != null)
384-
NSNotificationCenter.DefaultCenter.RemoveObserver(playedToEndObserver);
385-
386-
DisposeObservers(ref playedToEndObserver);
387-
DisposeObservers(ref rateObserver);
388-
DisposeObservers(ref volumeObserver);
389-
DisposeObservers(ref statusObserver);
381+
DestroyPlayedToEndObserver();
382+
DestroyRateObserver();
383+
DestroyVolumeObserver();
384+
DestroyStatusObserver();
390385
}
391386

392387
if (e.NewElement != null)
@@ -404,7 +399,7 @@ protected override void OnElementChanged(ElementChangedEventArgs<MediaElement> e
404399
if (Element.KeepScreenOn)
405400
SetKeepScreenOn(true);
406401

407-
playedToEndObserver = NSNotificationCenter.DefaultCenter.AddObserver(AVPlayerItem.DidPlayToEndTimeNotification, PlayedToEnd);
402+
AddPlayedToEndObserver();
408403

409404
UpdateBackgroundColor();
410405
UpdateSource();
@@ -424,5 +419,49 @@ protected void DisposeObservers(ref NSObject disposable)
424419
disposable?.Dispose();
425420
disposable = null;
426421
}
422+
423+
void AddVolumeObserver()
424+
{
425+
DestroyVolumeObserver();
426+
volumeObserver = avPlayerViewController.Player?.AddObserver("volume", NSKeyValueObservingOptions.New,
427+
ObserveVolume);
428+
}
429+
430+
void AddRateObserver()
431+
{
432+
DestroyRateObserver();
433+
rateObserver = avPlayerViewController.Player?.AddObserver("rate", NSKeyValueObservingOptions.New,
434+
ObserveRate);
435+
}
436+
437+
void AddStatusObserver()
438+
{
439+
DestroyStatusObserver();
440+
statusObserver = playerItem.AddObserver("status", NSKeyValueObservingOptions.New, ObserveStatus);
441+
}
442+
443+
void AddPlayedToEndObserver()
444+
{
445+
DestroyPlayedToEndObserver();
446+
playedToEndObserver =
447+
NSNotificationCenter.DefaultCenter.AddObserver(AVPlayerItem.DidPlayToEndTimeNotification, PlayedToEnd);
448+
}
449+
450+
void DestroyVolumeObserver() => DisposeObservers(ref volumeObserver);
451+
452+
void DestroyRateObserver() => DisposeObservers(ref rateObserver);
453+
454+
void DestroyStatusObserver() => DisposeObservers(ref statusObserver);
455+
456+
void DestroyPlayedToEndObserver()
457+
{
458+
if (playedToEndObserver == null)
459+
{
460+
return;
461+
}
462+
463+
NSNotificationCenter.DefaultCenter.RemoveObserver(playedToEndObserver);
464+
DisposeObservers(ref playedToEndObserver);
465+
}
427466
}
428467
}

0 commit comments

Comments
 (0)