         
         let playbackFactory = PlaybackFactory(loader: loader, options: playbackOptions)
         
-        playback?.removeFromSuperview()
-        playback = playbackFactory.createPlayback()
+        setPlayback(playbackFactory.createPlayback())
+        
         renderPlayback()
         trigger(ContainerEvent.sourceChanged)
+    }
+    
+    fileprivate func setPlayback(_ playback: Playback) {
+        if self.playback != playback {
+            trigger(InternalEvent.willChangePlayback.rawValue)
+            
+            self.playback?.removeFromSuperview()
+            self.playback = playback
+            
+            trigger(InternalEvent.didChangePlayback.rawValue)
+            stopListening()
+            bindEventListeners()
+        }
     }
     
     open override func render() {
         plugins.forEach(renderPlugin)
         renderPlayback()
     }
-
+    
     fileprivate func renderPlayback() {
         guard let playback = playback else {
             return
         }
-
+        
         addSubviewMatchingConstraints(playback)
         playback.render()
         sendSubview(toBack: playback)

    open internal(set) var ready = false
    open internal(set) var plugins: [UIContainerPlugin] = []
    open internal(set) var options: Options

    fileprivate var buffering = false
    fileprivate var loader: Loader

    
    open var isPlaying: Bool {
        return playback?.isPlaying ?? false

            .bufferUpdate         : { [weak self] (info: EventUserInfo) in self?.forward(.progress, userInfo:info)} as EventCallback,
            .positionUpdate       : { [weak self] (info: EventUserInfo) in self?.forward(.timeUpdated, userInfo:info)} as EventCallback,
            .didUpdateSubtitleSource : { [weak self] (info: EventUserInfo) in self?.forward(.subtitleSourcesUpdated, userInfo:info)} as EventCallback,
            .didUpdateAudioSource : { [weak self] (info: EventUserInfo) in self?.forward(.audioSourcesUpdated, userInfo:info)} as EventCallback
        ]
    }
    
    fileprivate func onPlay() {
        if buffering {
            buffering = false
            trigger(.bufferFull)
        }
        
        options[kStartAt] = 0.0
        trigger(.play)
    }
    
    fileprivate func setReady() {
        ready = true
        trigger(ContainerEvent.ready)
    }
    
    fileprivate func trigger(_ event: ContainerEvent) {
        trigger(event.rawValue)
    }
