Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / AVElementHelper.cs / 1 / AVElementHelper.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: avelementhelper.cs // // Description: Contains the AVElementHelper class. // // History: // 05/04/2004 : [....] - Added // //--------------------------------------------------------------------------- using MS.Internal; using MS.Utility; using System.Diagnostics; using System.Windows.Threading; using System; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.Animation; using System.Security; using System.Security.Permissions; namespace System.Windows.Controls { #region SettableState ////// Settable State, keeps track of what state was set and whether it has /// been set recently. /// internal struct SettableState{ internal T _value; internal bool _isSet; internal bool _wasSet; internal SettableState( T value ) { _value = value; _isSet = _wasSet = false; } } #endregion #region AVElementHelper /// /// AVElementHelper /// internal class AVElementHelper { #region Constructor ////// Constructor, point to the corresponding MediaElement. /// internal AVElementHelper(MediaElement element) { Debug.Assert((element != null), "Element is null"); _element = element; _position = new SettableState(new TimeSpan(0)); // // We always start off in a closed state. // _mediaState = new SettableState (MediaState.Close); _source = new SettableState (null); _clock = new SettableState (null); _speedRatio = new SettableState (1.0); _volume = new SettableState (0.5); _isMuted = new SettableState (false); _balance = new SettableState (0.0); _isScrubbingEnabled = new SettableState (false); _mediaPlayer = new MediaPlayer(); HookEvents(); } #endregion #region Internal and Private Properties / Methods /// /// Returns the helper class given a dependency object /// internal static AVElementHelper GetHelper(DependencyObject d) { MediaElement mediaElement = d as MediaElement; if (mediaElement != null) { return mediaElement.Helper; } else { throw new ArgumentException(SR.Get(SRID.AudioVideo_InvalidDependencyObject)); } } ////// MediaPlayer associated with the element. /// internal MediaPlayer Player { get { return _mediaPlayer; } } ////// Base Uri to use when resolving relative Uri's /// internal Uri BaseUri { get { return _baseUri; } set { // ignore pack URIs for now (see work items 45396 and 41636) if (value.Scheme != System.IO.Packaging.PackUriHelper.UriSchemePack) { _baseUri = value; } else { _baseUri = null; } } } ////// Allows the behavior the Media Element should have when it is unloaded /// to be expressed. This is a method because it can have side-effects /// (Media could start playing or pause or perform a number of other /// actions). /// internal void SetUnloadedBehavior( MediaState unloadedBehavior ) { _unloadedBehavior = unloadedBehavior; HandleStateChange(); } ////// Changes the loaded behavior. This is a method because it can cause /// side effects on other properties. (It could cause me to start or /// stop playing, for example). /// internal void SetLoadedBehavior( MediaState loadedBehavior ) { _loadedBehavior = loadedBehavior; HandleStateChange(); } ////// Returns the current position of the media. /// internal TimeSpan Position { get { // // If we have been closed, position is just a cached value, // return it. // if (_currentState == MediaState.Close) { return _position._value; } else { return _mediaPlayer.Position; } } } ////// Sets the current position of the media. This is a method /// and not a property because it has side effects. /// internal void SetPosition( TimeSpan position ) { _position._isSet = true; _position._value = position; // // If the media isn't closed, then we can actually send // this down to the unmanaged state engine. It gets // snippy if you try to change the position when it // is closed. // HandleStateChange(); } internal MediaClock Clock { get { return _clock._value; } } internal void SetClock( MediaClock clock ) { _clock._value = clock; // // We don't use _wasSet for clocks because our behavior changes dramatically // whether _value is null or not. // _clock._isSet = true; HandleStateChange(); } internal double SpeedRatio { get { return _speedRatio._value; } } internal void SetSpeedRatio( double speedRatio ) { _speedRatio._wasSet = _speedRatio._isSet = true; _speedRatio._value = speedRatio; HandleStateChange(); } internal void SetState( MediaState mediaState ) { // // If the caller hasn't requested any loaded or unloaded behavior to be manual // then calls to Play/Pause/Stop etc. will never take effect. // if (_loadedBehavior != MediaState.Manual && _unloadedBehavior != MediaState.Manual) { throw new NotSupportedException(SR.Get(SRID.AudioVideo_CannotControlMedia)); } _mediaState._value = mediaState; _mediaState._isSet = true; HandleStateChange(); } internal void SetVolume( double volume ) { _volume._wasSet = _volume._isSet = true; _volume._value = volume; HandleStateChange(); } internal void SetBalance( double balance ) { _balance._wasSet = _balance._isSet = true; _balance._value = balance; HandleStateChange(); } internal void SetIsMuted( bool isMuted ) { _isMuted._wasSet = _isMuted._isSet = true; _isMuted._value = isMuted; HandleStateChange(); } internal void SetScrubbingEnabled( bool isScrubbingEnabled ) { _isScrubbingEnabled._wasSet = _isScrubbingEnabled._isSet = true; _isScrubbingEnabled._value = isScrubbingEnabled; HandleStateChange(); } ////// Hook Events when clock is created/changed /// private void HookEvents() { // register the new clock events _mediaPlayer.MediaOpened += new EventHandler(OnMediaOpened); _mediaPlayer.MediaFailed += new EventHandler(OnMediaFailed); _mediaPlayer.BufferingStarted += new EventHandler(OnBufferingStarted); _mediaPlayer.BufferingEnded += new EventHandler(OnBufferingEnded); _mediaPlayer.MediaEnded += new EventHandler(OnMediaEnded); _mediaPlayer.ScriptCommand += new EventHandler (OnScriptCommand); _element.Loaded += new RoutedEventHandler(this.OnLoaded); _element.Unloaded += new RoutedEventHandler(this.OnUnloaded); } /// /// All state changes to the media element come through this code, we first /// look at all of the media element properties and the loaded behavior and /// source property to see whether to open or close the media, the we set /// other properties that actually control media and have been cached up. /// private void HandleStateChange( ) { // // First, just assume that our requested actions are going to be // the same as the media requested actions. // MediaState thisStateRequest = _mediaState._value; bool openClock = false; bool actionRequested = false; // // If the element is loaded // if (_isLoaded) { // // If we have a clock, then our loaded behavior is always manual. // The clock always wins. // if (_clock._value != null) { thisStateRequest = MediaState.Manual; openClock = true; } // // If the loaded behavior was set, it wins over whether the // source was set or not. // else if (_loadedBehavior != MediaState.Manual) { // // If it is manual, it doesn't override the requested state. // thisStateRequest = _loadedBehavior; } else if (_source._wasSet) { if (_loadedBehavior != MediaState.Manual) { thisStateRequest = MediaState.Play; } else { actionRequested = true; } } } else { // // If the unloaded behavior is manual, it doesn't override the // requested state, // if (_unloadedBehavior != MediaState.Manual) { thisStateRequest = _unloadedBehavior; } else { // // For situations in which we don't received loaded and unloaded // events, (like VisualBrush), we need to set our UnloadedBehavior // to Manual in order to allow storyboards to be able to control // the media element. // Invariant.Assert(_unloadedBehavior == MediaState.Manual); if (_clock._value != null) { thisStateRequest = MediaState.Manual; openClock = true; } // // Otherwise, an action was requested, we need to take it. // else { actionRequested = true; } } } bool openedMedia = false; // // If the media state is anything other than close // and the current state is closed, the media needs to be opened. // if ( thisStateRequest != MediaState.Close && thisStateRequest != MediaState.Manual) { // // We shouldn't have a clock to open because this would have a state // request of MediaState.Manual. // Invariant.Assert(openClock == false); // // If we had a clock, get rid of it now. This is to handle the case // where UnloadedBehavior is specified after the timing engine has // been in control. // if (_mediaPlayer.Clock != null) { _mediaPlayer.Clock = null; } // // If we are currently closed, we should open. If the source property // was assigned, we should also open. // if (_currentState == MediaState.Close || _source._isSet) { // // ScrubbingEnabled needs to be set before opening media in // order to get the initial scrub. // if (_isScrubbingEnabled._wasSet) { _mediaPlayer.ScrubbingEnabled = _isScrubbingEnabled._value; _isScrubbingEnabled._isSet = false; } if (_clock._value == null) { _mediaPlayer.Open(UriFromSourceUri(_source._value)); } openedMedia = true; } } else if (openClock) { // // If either we were closed before, or if a clock was re-assigned without // a state transition, then, re-apply the clock. // if (_currentState == MediaState.Close || _clock._isSet) { // // ScrubbingEnabled needs to be set before opening media in // order to get the initial scrub. // if (_isScrubbingEnabled._wasSet) { _mediaPlayer.ScrubbingEnabled = _isScrubbingEnabled._value; _isScrubbingEnabled._isSet = false; } _mediaPlayer.Clock = _clock._value; _clock._isSet = false; openedMedia = true; } } // // Otherwise, if the request is for a Close and and we aren't in a closed state, // we need to close. // else if (thisStateRequest == MediaState.Close) { if (_currentState != MediaState.Close) { // // Dis-associate the clock from the player (if it has one). // (Otherwise, it won't let us close it). // _mediaPlayer.Clock = null; _mediaPlayer.Close(); _currentState = MediaState.Close; } } // // If we either just opened the media, or if we weren't closed in the // first place, we get to perform all of the other actions. // if (_currentState != MediaState.Close || openedMedia) { // // If we have a position request, do it now. // if (_position._isSet) { _mediaPlayer.Position = _position._value; _position._isSet = false; } // // Do volume state changes before a play so that we don't get either // no sound or a loud sound on the play transition. // if (_volume._isSet || openedMedia && _volume._wasSet) { _mediaPlayer.Volume = _volume._value; _volume._isSet = false; } if (_balance._isSet || openedMedia && _balance._wasSet) { _mediaPlayer.Balance = _balance._value; _balance._isSet = false; } if (_isMuted._isSet || openedMedia && _isMuted._wasSet) { _mediaPlayer.IsMuted = _isMuted._value; _isMuted._isSet = false; } // // In the case that openedMedia is true, we will have already // applied the scrubbing enabled property prior to opening the // media. This is necessary for initial scrubbing to work // if (_isScrubbingEnabled._isSet) { _mediaPlayer.ScrubbingEnabled = _isScrubbingEnabled._value; _isScrubbingEnabled._isSet = false; } // // If we are asked to play because the source was reset, // then, start playing the media again. // if (thisStateRequest == MediaState.Play && _source._isSet) { // // We always want to Play() and then set the SpeedRatio to // 1. This ensures that whwn you change the source of a // MediaElement via databinding, we start playing the // media again. // _mediaPlayer.Play(); if (!_speedRatio._wasSet) { _mediaPlayer.SpeedRatio = 1; } // // We have effectively `swallowed the "Play" request, if this is // what finally brought us into this code path. // _source._isSet = false; _mediaState._isSet = false; } // // Might be missing out on a Play, Pause, or a stop. // If the source is changed, we always want to do the // requested action. Also, we want to mirror each call // to Play, Pause and Stop down to the underlying player. // else if ( _currentState != thisStateRequest || (actionRequested && _mediaState._isSet)) { switch(thisStateRequest) { case MediaState.Play: _mediaPlayer.Play(); break; case MediaState.Pause: _mediaPlayer.Pause(); break; case MediaState.Stop: _mediaPlayer.Stop(); break; case MediaState.Manual: break; default: Invariant.Assert(false, "Unexpected state request."); break; } // // If we did this transition because an action was requested, make sure // we don't do it again when we come in. // if (actionRequested) { _mediaState._isSet = false; } } _currentState = thisStateRequest; // // Finally, if the speed ratio has been set, change it. // if (_speedRatio._isSet || openedMedia && _speedRatio._wasSet) { _mediaPlayer.SpeedRatio = _speedRatio._value; _speedRatio._isSet = false; } } } ////// Looks at the current uri and the base uri and uses it to determine /// whether we should normalize the uri to the base or not. /// private Uri UriFromSourceUri( Uri sourceUri ) { if (sourceUri != null) { if (sourceUri.IsAbsoluteUri) { return sourceUri; } else if (BaseUri != null) { return new Uri(BaseUri, sourceUri); } } return sourceUri; } #endregion #region Delegates ////// Raised when source is changed /// ////// Critical: This code calls into PresentationSource.CriticalFromVisual to /// extract presentationsource. /// TreatAsSafe: The value is not exposed and the call simply checks to see /// if the value is null /// [SecurityCritical,SecurityTreatAsSafe] internal static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.IsASubPropertyChange) { return; } AVElementHelper aveh = AVElementHelper.GetHelper(d); aveh.MemberOnInvalidateSource(e); // call non-static } private void MemberOnInvalidateSource(DependencyPropertyChangedEventArgs e) { if (_clock._value != null) { throw new InvalidOperationException(SR.Get(SRID.MediaElement_CannotSetSourceOnMediaElementDrivenByClock)); } _source._value = (Uri)e.NewValue; _source._wasSet = _source._isSet = true; HandleStateChange(); } ////// Raised when there is a error with media playback /// private void OnMediaFailed( object sender, ExceptionEventArgs args ) { // // Propagate the error to the media element. // _element.OnMediaFailed(sender, args); } ////// Raised when media is opened /// private void OnMediaOpened( object sender, EventArgs args ) { // Whenever a new file is opened the size of the MediaElement may change _element.InvalidateMeasure(); _element.OnMediaOpened(sender, args); } private void OnBufferingStarted( object sender, EventArgs args ) { _element.OnBufferingStarted(sender, args); } private void OnBufferingEnded( object sender, EventArgs args ) { _element.OnBufferingEnded(sender, args); } private void OnMediaEnded( object sender, EventArgs args ) { _element.OnMediaEnded(sender, args); } private void OnScriptCommand( object sender, MediaScriptCommandEventArgs args ) { _element.OnScriptCommand(sender, args); } private void OnLoaded( object sender, RoutedEventArgs args ) { _isLoaded = true; HandleStateChange(); } private void OnUnloaded( object sender, RoutedEventArgs args ) { _isLoaded = false; HandleStateChange(); } #endregion #region Data Members ////// MediaPlayer /// private MediaPlayer _mediaPlayer; ////// UIElement that owns this helper /// private MediaElement _element; private Uri _baseUri; private MediaState _unloadedBehavior = MediaState.Close; private MediaState _loadedBehavior = MediaState.Play; private MediaState _currentState = MediaState.Close; private bool _isLoaded = false; // // The requested state, we need to know for each one whether it // was ever set and for // SettableState_position; SettableState _mediaState; SettableState _source; SettableState _clock; SettableState _speedRatio; SettableState _volume; SettableState _isMuted; SettableState _balance; SettableState _isScrubbingEnabled; #endregion } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: avelementhelper.cs // // Description: Contains the AVElementHelper class. // // History: // 05/04/2004 : [....] - Added // //--------------------------------------------------------------------------- using MS.Internal; using MS.Utility; using System.Diagnostics; using System.Windows.Threading; using System; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.Animation; using System.Security; using System.Security.Permissions; namespace System.Windows.Controls { #region SettableState /// /// Settable State, keeps track of what state was set and whether it has /// been set recently. /// internal struct SettableState{ internal T _value; internal bool _isSet; internal bool _wasSet; internal SettableState( T value ) { _value = value; _isSet = _wasSet = false; } } #endregion #region AVElementHelper /// /// AVElementHelper /// internal class AVElementHelper { #region Constructor ////// Constructor, point to the corresponding MediaElement. /// internal AVElementHelper(MediaElement element) { Debug.Assert((element != null), "Element is null"); _element = element; _position = new SettableState(new TimeSpan(0)); // // We always start off in a closed state. // _mediaState = new SettableState (MediaState.Close); _source = new SettableState (null); _clock = new SettableState (null); _speedRatio = new SettableState (1.0); _volume = new SettableState (0.5); _isMuted = new SettableState (false); _balance = new SettableState (0.0); _isScrubbingEnabled = new SettableState (false); _mediaPlayer = new MediaPlayer(); HookEvents(); } #endregion #region Internal and Private Properties / Methods /// /// Returns the helper class given a dependency object /// internal static AVElementHelper GetHelper(DependencyObject d) { MediaElement mediaElement = d as MediaElement; if (mediaElement != null) { return mediaElement.Helper; } else { throw new ArgumentException(SR.Get(SRID.AudioVideo_InvalidDependencyObject)); } } ////// MediaPlayer associated with the element. /// internal MediaPlayer Player { get { return _mediaPlayer; } } ////// Base Uri to use when resolving relative Uri's /// internal Uri BaseUri { get { return _baseUri; } set { // ignore pack URIs for now (see work items 45396 and 41636) if (value.Scheme != System.IO.Packaging.PackUriHelper.UriSchemePack) { _baseUri = value; } else { _baseUri = null; } } } ////// Allows the behavior the Media Element should have when it is unloaded /// to be expressed. This is a method because it can have side-effects /// (Media could start playing or pause or perform a number of other /// actions). /// internal void SetUnloadedBehavior( MediaState unloadedBehavior ) { _unloadedBehavior = unloadedBehavior; HandleStateChange(); } ////// Changes the loaded behavior. This is a method because it can cause /// side effects on other properties. (It could cause me to start or /// stop playing, for example). /// internal void SetLoadedBehavior( MediaState loadedBehavior ) { _loadedBehavior = loadedBehavior; HandleStateChange(); } ////// Returns the current position of the media. /// internal TimeSpan Position { get { // // If we have been closed, position is just a cached value, // return it. // if (_currentState == MediaState.Close) { return _position._value; } else { return _mediaPlayer.Position; } } } ////// Sets the current position of the media. This is a method /// and not a property because it has side effects. /// internal void SetPosition( TimeSpan position ) { _position._isSet = true; _position._value = position; // // If the media isn't closed, then we can actually send // this down to the unmanaged state engine. It gets // snippy if you try to change the position when it // is closed. // HandleStateChange(); } internal MediaClock Clock { get { return _clock._value; } } internal void SetClock( MediaClock clock ) { _clock._value = clock; // // We don't use _wasSet for clocks because our behavior changes dramatically // whether _value is null or not. // _clock._isSet = true; HandleStateChange(); } internal double SpeedRatio { get { return _speedRatio._value; } } internal void SetSpeedRatio( double speedRatio ) { _speedRatio._wasSet = _speedRatio._isSet = true; _speedRatio._value = speedRatio; HandleStateChange(); } internal void SetState( MediaState mediaState ) { // // If the caller hasn't requested any loaded or unloaded behavior to be manual // then calls to Play/Pause/Stop etc. will never take effect. // if (_loadedBehavior != MediaState.Manual && _unloadedBehavior != MediaState.Manual) { throw new NotSupportedException(SR.Get(SRID.AudioVideo_CannotControlMedia)); } _mediaState._value = mediaState; _mediaState._isSet = true; HandleStateChange(); } internal void SetVolume( double volume ) { _volume._wasSet = _volume._isSet = true; _volume._value = volume; HandleStateChange(); } internal void SetBalance( double balance ) { _balance._wasSet = _balance._isSet = true; _balance._value = balance; HandleStateChange(); } internal void SetIsMuted( bool isMuted ) { _isMuted._wasSet = _isMuted._isSet = true; _isMuted._value = isMuted; HandleStateChange(); } internal void SetScrubbingEnabled( bool isScrubbingEnabled ) { _isScrubbingEnabled._wasSet = _isScrubbingEnabled._isSet = true; _isScrubbingEnabled._value = isScrubbingEnabled; HandleStateChange(); } ////// Hook Events when clock is created/changed /// private void HookEvents() { // register the new clock events _mediaPlayer.MediaOpened += new EventHandler(OnMediaOpened); _mediaPlayer.MediaFailed += new EventHandler(OnMediaFailed); _mediaPlayer.BufferingStarted += new EventHandler(OnBufferingStarted); _mediaPlayer.BufferingEnded += new EventHandler(OnBufferingEnded); _mediaPlayer.MediaEnded += new EventHandler(OnMediaEnded); _mediaPlayer.ScriptCommand += new EventHandler (OnScriptCommand); _element.Loaded += new RoutedEventHandler(this.OnLoaded); _element.Unloaded += new RoutedEventHandler(this.OnUnloaded); } /// /// All state changes to the media element come through this code, we first /// look at all of the media element properties and the loaded behavior and /// source property to see whether to open or close the media, the we set /// other properties that actually control media and have been cached up. /// private void HandleStateChange( ) { // // First, just assume that our requested actions are going to be // the same as the media requested actions. // MediaState thisStateRequest = _mediaState._value; bool openClock = false; bool actionRequested = false; // // If the element is loaded // if (_isLoaded) { // // If we have a clock, then our loaded behavior is always manual. // The clock always wins. // if (_clock._value != null) { thisStateRequest = MediaState.Manual; openClock = true; } // // If the loaded behavior was set, it wins over whether the // source was set or not. // else if (_loadedBehavior != MediaState.Manual) { // // If it is manual, it doesn't override the requested state. // thisStateRequest = _loadedBehavior; } else if (_source._wasSet) { if (_loadedBehavior != MediaState.Manual) { thisStateRequest = MediaState.Play; } else { actionRequested = true; } } } else { // // If the unloaded behavior is manual, it doesn't override the // requested state, // if (_unloadedBehavior != MediaState.Manual) { thisStateRequest = _unloadedBehavior; } else { // // For situations in which we don't received loaded and unloaded // events, (like VisualBrush), we need to set our UnloadedBehavior // to Manual in order to allow storyboards to be able to control // the media element. // Invariant.Assert(_unloadedBehavior == MediaState.Manual); if (_clock._value != null) { thisStateRequest = MediaState.Manual; openClock = true; } // // Otherwise, an action was requested, we need to take it. // else { actionRequested = true; } } } bool openedMedia = false; // // If the media state is anything other than close // and the current state is closed, the media needs to be opened. // if ( thisStateRequest != MediaState.Close && thisStateRequest != MediaState.Manual) { // // We shouldn't have a clock to open because this would have a state // request of MediaState.Manual. // Invariant.Assert(openClock == false); // // If we had a clock, get rid of it now. This is to handle the case // where UnloadedBehavior is specified after the timing engine has // been in control. // if (_mediaPlayer.Clock != null) { _mediaPlayer.Clock = null; } // // If we are currently closed, we should open. If the source property // was assigned, we should also open. // if (_currentState == MediaState.Close || _source._isSet) { // // ScrubbingEnabled needs to be set before opening media in // order to get the initial scrub. // if (_isScrubbingEnabled._wasSet) { _mediaPlayer.ScrubbingEnabled = _isScrubbingEnabled._value; _isScrubbingEnabled._isSet = false; } if (_clock._value == null) { _mediaPlayer.Open(UriFromSourceUri(_source._value)); } openedMedia = true; } } else if (openClock) { // // If either we were closed before, or if a clock was re-assigned without // a state transition, then, re-apply the clock. // if (_currentState == MediaState.Close || _clock._isSet) { // // ScrubbingEnabled needs to be set before opening media in // order to get the initial scrub. // if (_isScrubbingEnabled._wasSet) { _mediaPlayer.ScrubbingEnabled = _isScrubbingEnabled._value; _isScrubbingEnabled._isSet = false; } _mediaPlayer.Clock = _clock._value; _clock._isSet = false; openedMedia = true; } } // // Otherwise, if the request is for a Close and and we aren't in a closed state, // we need to close. // else if (thisStateRequest == MediaState.Close) { if (_currentState != MediaState.Close) { // // Dis-associate the clock from the player (if it has one). // (Otherwise, it won't let us close it). // _mediaPlayer.Clock = null; _mediaPlayer.Close(); _currentState = MediaState.Close; } } // // If we either just opened the media, or if we weren't closed in the // first place, we get to perform all of the other actions. // if (_currentState != MediaState.Close || openedMedia) { // // If we have a position request, do it now. // if (_position._isSet) { _mediaPlayer.Position = _position._value; _position._isSet = false; } // // Do volume state changes before a play so that we don't get either // no sound or a loud sound on the play transition. // if (_volume._isSet || openedMedia && _volume._wasSet) { _mediaPlayer.Volume = _volume._value; _volume._isSet = false; } if (_balance._isSet || openedMedia && _balance._wasSet) { _mediaPlayer.Balance = _balance._value; _balance._isSet = false; } if (_isMuted._isSet || openedMedia && _isMuted._wasSet) { _mediaPlayer.IsMuted = _isMuted._value; _isMuted._isSet = false; } // // In the case that openedMedia is true, we will have already // applied the scrubbing enabled property prior to opening the // media. This is necessary for initial scrubbing to work // if (_isScrubbingEnabled._isSet) { _mediaPlayer.ScrubbingEnabled = _isScrubbingEnabled._value; _isScrubbingEnabled._isSet = false; } // // If we are asked to play because the source was reset, // then, start playing the media again. // if (thisStateRequest == MediaState.Play && _source._isSet) { // // We always want to Play() and then set the SpeedRatio to // 1. This ensures that whwn you change the source of a // MediaElement via databinding, we start playing the // media again. // _mediaPlayer.Play(); if (!_speedRatio._wasSet) { _mediaPlayer.SpeedRatio = 1; } // // We have effectively `swallowed the "Play" request, if this is // what finally brought us into this code path. // _source._isSet = false; _mediaState._isSet = false; } // // Might be missing out on a Play, Pause, or a stop. // If the source is changed, we always want to do the // requested action. Also, we want to mirror each call // to Play, Pause and Stop down to the underlying player. // else if ( _currentState != thisStateRequest || (actionRequested && _mediaState._isSet)) { switch(thisStateRequest) { case MediaState.Play: _mediaPlayer.Play(); break; case MediaState.Pause: _mediaPlayer.Pause(); break; case MediaState.Stop: _mediaPlayer.Stop(); break; case MediaState.Manual: break; default: Invariant.Assert(false, "Unexpected state request."); break; } // // If we did this transition because an action was requested, make sure // we don't do it again when we come in. // if (actionRequested) { _mediaState._isSet = false; } } _currentState = thisStateRequest; // // Finally, if the speed ratio has been set, change it. // if (_speedRatio._isSet || openedMedia && _speedRatio._wasSet) { _mediaPlayer.SpeedRatio = _speedRatio._value; _speedRatio._isSet = false; } } } ////// Looks at the current uri and the base uri and uses it to determine /// whether we should normalize the uri to the base or not. /// private Uri UriFromSourceUri( Uri sourceUri ) { if (sourceUri != null) { if (sourceUri.IsAbsoluteUri) { return sourceUri; } else if (BaseUri != null) { return new Uri(BaseUri, sourceUri); } } return sourceUri; } #endregion #region Delegates ////// Raised when source is changed /// ////// Critical: This code calls into PresentationSource.CriticalFromVisual to /// extract presentationsource. /// TreatAsSafe: The value is not exposed and the call simply checks to see /// if the value is null /// [SecurityCritical,SecurityTreatAsSafe] internal static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.IsASubPropertyChange) { return; } AVElementHelper aveh = AVElementHelper.GetHelper(d); aveh.MemberOnInvalidateSource(e); // call non-static } private void MemberOnInvalidateSource(DependencyPropertyChangedEventArgs e) { if (_clock._value != null) { throw new InvalidOperationException(SR.Get(SRID.MediaElement_CannotSetSourceOnMediaElementDrivenByClock)); } _source._value = (Uri)e.NewValue; _source._wasSet = _source._isSet = true; HandleStateChange(); } ////// Raised when there is a error with media playback /// private void OnMediaFailed( object sender, ExceptionEventArgs args ) { // // Propagate the error to the media element. // _element.OnMediaFailed(sender, args); } ////// Raised when media is opened /// private void OnMediaOpened( object sender, EventArgs args ) { // Whenever a new file is opened the size of the MediaElement may change _element.InvalidateMeasure(); _element.OnMediaOpened(sender, args); } private void OnBufferingStarted( object sender, EventArgs args ) { _element.OnBufferingStarted(sender, args); } private void OnBufferingEnded( object sender, EventArgs args ) { _element.OnBufferingEnded(sender, args); } private void OnMediaEnded( object sender, EventArgs args ) { _element.OnMediaEnded(sender, args); } private void OnScriptCommand( object sender, MediaScriptCommandEventArgs args ) { _element.OnScriptCommand(sender, args); } private void OnLoaded( object sender, RoutedEventArgs args ) { _isLoaded = true; HandleStateChange(); } private void OnUnloaded( object sender, RoutedEventArgs args ) { _isLoaded = false; HandleStateChange(); } #endregion #region Data Members ////// MediaPlayer /// private MediaPlayer _mediaPlayer; ////// UIElement that owns this helper /// private MediaElement _element; private Uri _baseUri; private MediaState _unloadedBehavior = MediaState.Close; private MediaState _loadedBehavior = MediaState.Play; private MediaState _currentState = MediaState.Close; private bool _isLoaded = false; // // The requested state, we need to know for each one whether it // was ever set and for // SettableState_position; SettableState _mediaState; SettableState _source; SettableState _clock; SettableState _speedRatio; SettableState _volume; SettableState _isMuted; SettableState _balance; SettableState _isScrubbingEnabled; #endregion } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AuthenticationService.cs
- Baml2006KeyRecord.cs
- CharacterMetrics.cs
- _AuthenticationState.cs
- _TLSstream.cs
- shaperfactory.cs
- SubclassTypeValidator.cs
- ContentValidator.cs
- DocumentGridPage.cs
- WindowProviderWrapper.cs
- NavigationWindowAutomationPeer.cs
- IndexExpression.cs
- BlockCollection.cs
- GeometryModel3D.cs
- RegionInfo.cs
- Storyboard.cs
- IisNotInstalledException.cs
- StickyNote.cs
- OperationBehaviorAttribute.cs
- StylusButtonEventArgs.cs
- XhtmlTextWriter.cs
- WindowsClaimSet.cs
- ValueSerializerAttribute.cs
- NamespaceList.cs
- XmlCountingReader.cs
- CommentEmitter.cs
- TextComposition.cs
- CodeTypeParameter.cs
- HTTPNotFoundHandler.cs
- PixelFormats.cs
- GacUtil.cs
- NamedPipeTransportBindingElement.cs
- ObjectIDGenerator.cs
- DesignTimeValidationFeature.cs
- HwndKeyboardInputProvider.cs
- DeflateEmulationStream.cs
- ScrollChrome.cs
- HttpCachePolicy.cs
- RtfNavigator.cs
- TextControl.cs
- FieldMetadata.cs
- wgx_sdk_version.cs
- ZipIOLocalFileBlock.cs
- ExplicitDiscriminatorMap.cs
- GeometryHitTestResult.cs
- SQLConvert.cs
- RepeatBehaviorConverter.cs
- AttributeData.cs
- DefaultDialogButtons.cs
- SemanticTag.cs
- ListViewItem.cs
- ConfigLoader.cs
- OneOfScalarConst.cs
- PatternMatcher.cs
- DetailsViewUpdatedEventArgs.cs
- PerformanceCounterCategory.cs
- Control.cs
- WebPartMinimizeVerb.cs
- QilExpression.cs
- UnorderedHashRepartitionStream.cs
- DataGridCheckBoxColumn.cs
- RelOps.cs
- TypeBuilderInstantiation.cs
- Random.cs
- ErrorEventArgs.cs
- SingleKeyFrameCollection.cs
- behaviorssection.cs
- PlaceHolder.cs
- ClassDataContract.cs
- ByteStorage.cs
- RowToParametersTransformer.cs
- DesignerCategoryAttribute.cs
- IsolatedStorage.cs
- XmlAggregates.cs
- WCFBuildProvider.cs
- CallInfo.cs
- GenericTypeParameterBuilder.cs
- TextOutput.cs
- SBCSCodePageEncoding.cs
- RawStylusActions.cs
- XmlCustomFormatter.cs
- SessionStateContainer.cs
- TableAdapterManagerHelper.cs
- _UriTypeConverter.cs
- UIPropertyMetadata.cs
- _IPv4Address.cs
- ClientSideQueueItem.cs
- PrimitiveType.cs
- DataGridViewMethods.cs
- Stack.cs
- IisTraceWebEventProvider.cs
- CharacterString.cs
- DataGridViewCellCancelEventArgs.cs
- StylusButtonCollection.cs
- DataTemplateKey.cs
- Int64.cs
- HttpDictionary.cs
- PropertyDescriptor.cs
- DbParameterCollection.cs
- DataGridRow.cs