Files
ZuneShell.dll/ZuneUI/TransportControls.cs
T

2068 lines
86 KiB
C#

// Decompiled with JetBrains decompiler
// Type: ZuneUI.TransportControls
// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
using Microsoft.Iris;
using Microsoft.Zune.Configuration;
using Microsoft.Zune.PerfTrace;
using Microsoft.Zune.QuickMix;
using Microsoft.Zune.Service;
using Microsoft.Zune.Util;
using MicrosoftZuneLibrary;
using MicrosoftZunePlayback;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using UIXControls;
namespace ZuneUI
{
public class TransportControls : SingletonModelItem<TransportControls>
{
internal const long c_TicksPerSecond = 10000000;
private const long _rewindDelay = 50000000;
private const float c_overscanFactor = 0.1f;
private const int c_maxConsecutiveErrors = 5;
private const int c_ratingUnrated = -1;
private const string c_knownInvalidUri = ".:* INVALID URI *:.";
private PlayerInterop _playbackWrapper;
private BooleanChoice _shuffling;
private BooleanChoice _repeating;
private BooleanChoice _muted;
private BooleanChoice _showTotalTime;
private BooleanChoice _showNowPlayingList;
private BooleanChoice _fastforwarding;
private BooleanChoice _rewinding;
private RangedValue _volume;
private Command _play;
private Command _pause;
private Command _back;
private Command _forward;
private Command _stop;
private bool _playingVideo;
private bool _opening;
private bool _buffering;
private bool _seekEnabled;
private int _zoomScaleFactor;
private Command _fastforwardhotkey;
private Command _rewindhotkey;
private NowPlayingList _playlistPending;
private NowPlayingList _playlistCurrent;
private Microsoft.Iris.Timer _timerDelayedConfigPersist;
private VideoStream _videoStream;
private MCPlayerState _lastKnownPlayerState;
private MCTransportState _lastKnownTransportState;
private long _lastKnownPosition;
private Notification _nowPlayingNotification;
private float _currentTrackDuration;
private float _currentTrackPosition;
private float _downloadProgress;
private PlaybackTrack _lastKnownPreparedTrack;
private PlaybackTrack _lastKnownPlaybackTrack;
private List<PlaybackTrack> _tracksSubmittedToPlayer = new List<PlaybackTrack>(2);
private Dictionary<PlaybackTrack, int> _errors = new Dictionary<PlaybackTrack, int>();
private int _consecutiveErrors;
private bool _showErrors = true;
private int _lastKnownSetUriCallID;
private static string _savedNowPlayingFilename = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Shell.LoadString(StringId.IDS_APPDATAFOLDERNAME).TrimStart('\\')), "NowPlaying.dat");
private Shell _shellInstance;
private PlayerState _playerState;
private bool _streamingReportIsOpen;
private Guid _streamingReportMediaId;
private Guid _streamingReportMediaInstanceId;
private TaskbarPlayer _taskbarPlayer;
private bool _isInitialized;
private bool _resumeLastNowPlayingRequested;
private bool _shuffleAllRequested;
private JumpListPin _requestedJumpListPin;
private PlaybackContext _pagePlaybackContext;
private PlaybackTrack _currentTrack;
private bool _isPlaying;
private bool _hasPlaylist;
private bool _playlistSupportsShuffle = true;
private bool _hasPlayed;
private int _currentTrackIndex = -1;
private ArrayListDataSet _currentPlaylist;
private bool _isContextCompatible;
private bool _isStreamingVideo;
private bool _supressDownloads;
private DateTime _currentPlayStartTime = DateTime.MinValue;
private List<SpectrumOutputConfig> _spectrumConfigList;
private bool _isSpectrumAvailable;
private int _lastKnownCurrentTrackRating;
private EventHandler _currentTrackRatingChangedEventHandler;
private Microsoft.Iris.Timer _isStreamingTimeoutTimer;
private bool _dontPlayMarketplaceTracks;
private int _bandwidthCapacity;
private BandwidthUpdateArgs _bandwidthUpdateInfo;
public TransportControls()
{
this._playbackWrapper = PlayerInterop.Instance;
this._taskbarPlayer = TaskbarPlayer.Instance;
this._videoStream = new VideoStream();
if (!this.CanRender3DVideo)
this._videoStream.DisplayDetailsChanged += new EventHandler(this.OnVideoDetailsChanged);
this._shuffling = new BooleanChoice(this);
this._shuffling.Value = ClientConfiguration.Playback.ModeShuffle;
this._shuffling.ChosenChanged += new EventHandler(this.OnShufflingChanged);
this.UpdateShufflingDescription();
this._repeating = new BooleanChoice(this);
this._repeating.Value = ClientConfiguration.Playback.ModeLoop;
this._repeating.ChosenChanged += new EventHandler(this.OnRepeatingChanged);
this.UpdateRepeatingDescription();
this._muted = new BooleanChoice(this);
this._muted.Value = ClientConfiguration.Playback.Mute;
this._muted.ChosenChanged += new EventHandler(this.OnMutingChanged);
this.UpdateMutingDescription();
this._showTotalTime = new BooleanChoice(this);
this._showTotalTime.Value = ClientConfiguration.Playback.ShowTotalTime;
this._showTotalTime.ChosenChanged += new EventHandler(this.OnShowTotalTimeChanged);
this._showNowPlayingList = new BooleanChoice(this);
this._showNowPlayingList.Value = ClientConfiguration.Playback.ShowNowPlayingList;
this._showNowPlayingList.ChosenChanged += new EventHandler(this.OnShowNowPlayingListChanged);
this.UpdateShowNowPlayingListDescription();
this._fastforwarding = new BooleanChoice(this);
this._fastforwarding.ChosenChanged += new EventHandler(this.OnFastforwardingChanged);
this._rewinding = new BooleanChoice(this);
this._rewinding.ChosenChanged += new EventHandler(this.OnRewindingChanged);
float num = ClientConfiguration.Playback.Volume;
if (num < 0.0 || num > 100.0)
num = 50f;
this._volume = new RangedValue(this);
this._volume.MinValue = 0.0f;
this._volume.MaxValue = 100f;
this._volume.Value = num;
this._volume.PropertyChanged += new PropertyChangedEventHandler(this.OnVolumeControlChanged);
this._play = new Command(this, Shell.LoadString(StringId.IDS_PLAY), new EventHandler(this.OnPlayClicked));
this._play.Available = false;
this._pause = new Command(this, Shell.LoadString(StringId.IDS_PAUSE), new EventHandler(this.OnPauseClicked));
this._pause.Available = false;
this._back = new Command(this, Shell.LoadString(StringId.IDS_PREVIOUS), new EventHandler(this.OnBackClicked));
this._back.Available = false;
this._forward = new Command(this, Shell.LoadString(StringId.IDS_NEXT), new EventHandler(this.OnForwardClicked));
this._forward.Available = false;
this._stop = new Command(this, Shell.LoadString(StringId.IDS_STOP), new EventHandler(this.OnStopClicked));
this._stop.Available = false;
this._fastforwardhotkey = new Command(this, new EventHandler(this.OnFastforwardHotkeyPressed));
this._rewindhotkey = new Command(this, new EventHandler(this.OnRewindHotkeyPressed));
this._playbackWrapper.StatusChanged += new EventHandler(this.OnPlaybackStatusChanged);
this._playbackWrapper.TransportStatusChanged += new EventHandler(this.OnTransportStatusChanged);
this._playbackWrapper.TransportPositionChanged += new EventHandler(this.OnTransportPositionChanged);
this._playbackWrapper.UriSet += new EventHandler(this.OnUriSet);
this._playbackWrapper.AlertSent += new AnnouncementHandler(this.OnAlertSent);
this._playbackWrapper.PlayerPropertyChanged += new PlayerPropertyChangedEventHandler(this.OnPlayerPropertyChanged);
this._playbackWrapper.PlayerBandwithUpdate += new PlayerBandwithUpdateEventHandler(this.OnBandwidthCapacityUpdate);
this._lastKnownPlayerState = this._playbackWrapper.State;
this._lastKnownTransportState = this._playbackWrapper.TransportState;
this._lastKnownPosition = this._playbackWrapper.Position;
this._shellInstance = (Shell)ZuneShell.DefaultInstance;
this._shellInstance.PropertyChanged += new PropertyChangedEventHandler(this.OnShellPropertyChanged);
this._timerDelayedConfigPersist = new Microsoft.Iris.Timer();
this._timerDelayedConfigPersist.Interval = 500;
this._timerDelayedConfigPersist.AutoRepeat = false;
this._timerDelayedConfigPersist.Tick += new EventHandler(this.OnDelayedConfigPersistTimerTick);
this._playerState = PlayerState.Stopped;
this._spectrumConfigList = new List<SpectrumOutputConfig>();
this._isSpectrumAvailable = false;
this.IsSeekEnabled = this._playbackWrapper.CanSeek;
Download.Instance.DownloadProgressEvent += new DownloadEventProgressHandler(this.OnDownloadProgressed);
this._lastKnownCurrentTrackRating = -1;
this._currentTrackRatingChangedEventHandler = new EventHandler(this.OnCurrentTrackRatingChanged);
this._isStreamingTimeoutTimer = new Microsoft.Iris.Timer(this);
this._isStreamingTimeoutTimer.Interval = 30000;
this._isStreamingTimeoutTimer.AutoRepeat = false;
this._isStreamingTimeoutTimer.Tick += new EventHandler(this.OnIsStreamingTimeout);
SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInEvent);
}
protected override void OnDispose(bool fDisposing)
{
base.OnDispose(fDisposing);
if (!fDisposing)
return;
this.DisconnectAllSpectrumAnimationSources();
this._isSpectrumAvailable = false;
Microsoft.Zune.Util.Notification.ResetNowPlaying();
if (this.WillSaveCurrentPlaylistOnShutdown())
{
try
{
using (Stream serializationStream = File.Create(_savedNowPlayingFilename))
new BinaryFormatter().Serialize(serializationStream, _playlistCurrent);
}
catch (Exception ex)
{
}
}
else if (File.Exists(_savedNowPlayingFilename))
{
try
{
File.Delete(_savedNowPlayingFilename);
}
catch (Exception ex)
{
}
}
if (this._lastKnownPlaybackTrack != null)
this._lastKnownPlaybackTrack.OnEndPlayback(false);
this._playbackWrapper.StatusChanged -= new EventHandler(this.OnPlaybackStatusChanged);
this._playbackWrapper.TransportStatusChanged -= new EventHandler(this.OnTransportStatusChanged);
this._playbackWrapper.TransportPositionChanged -= new EventHandler(this.OnTransportPositionChanged);
this._playbackWrapper.UriSet -= new EventHandler(this.OnUriSet);
this._playbackWrapper.AlertSent -= new AnnouncementHandler(this.OnAlertSent);
this._playbackWrapper.PlayerPropertyChanged -= new PlayerPropertyChangedEventHandler(this.OnPlayerPropertyChanged);
if (this._videoStream != null && !this.CanRender3DVideo)
this._videoStream.DisplayDetailsChanged -= new EventHandler(this.OnVideoDetailsChanged);
PlayerInterop.Instance.Dispose();
if (this._videoStream != null)
{
this._videoStream.Dispose();
this._videoStream = null;
}
if (this._timerDelayedConfigPersist != null)
{
this._timerDelayedConfigPersist.Tick -= new EventHandler(this.OnDelayedConfigPersistTimerTick);
this._timerDelayedConfigPersist.Dispose();
this._timerDelayedConfigPersist = null;
}
this._shellInstance.PropertyChanged -= new PropertyChangedEventHandler(this.OnShellPropertyChanged);
Download.Instance.DownloadProgressEvent -= new DownloadEventProgressHandler(this.OnDownloadProgressed);
if (this._currentTrack != null)
this._currentTrack.RatingChanged.Invoked -= this._currentTrackRatingChangedEventHandler;
SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInEvent);
}
private void OnSignInEvent(object sender, EventArgs args)
{
if (this._playlistCurrent != null)
this._playlistCurrent.UpdateTracks();
if (this._playlistPending == null)
return;
this._playlistPending.UpdateTracks();
}
private void PersistSettings()
{
if (this._timerDelayedConfigPersist == null)
return;
this._timerDelayedConfigPersist.Stop();
this._timerDelayedConfigPersist.Start();
}
private void OnDelayedConfigPersistTimerTick(object sender, EventArgs args)
{
ClientConfiguration.Playback.ModeShuffle = this._shuffling.Value;
ClientConfiguration.Playback.ModeLoop = this._repeating.Value;
ClientConfiguration.Playback.Mute = this._muted.Value;
ClientConfiguration.Playback.Volume = (int)this._volume.Value;
ClientConfiguration.Playback.ShowTotalTime = this._showTotalTime.Value;
ClientConfiguration.Playback.ShowNowPlayingList = this._showNowPlayingList.Value;
}
private void OnCurrentTrackRatingChanged(object sender, EventArgs args)
{
int num = -1;
if (this.CurrentTrack != null && this.CurrentTrack.CanRate)
num = this.CurrentTrackRating;
if (num == this._lastKnownCurrentTrackRating)
return;
this.FirePropertyChanged("CurrentTrackRating");
this._lastKnownCurrentTrackRating = num;
}
public void TrackRatingUpdatedExternally(int mediaID, int newRating)
{
if (this.CurrentPlaylist == null)
return;
foreach (PlaybackTrack playbackTrack in CurrentPlaylist)
{
if (playbackTrack is LibraryPlaybackTrack libraryPlaybackTrack && libraryPlaybackTrack.MediaId == mediaID)
libraryPlaybackTrack.RatingUpdatedExternally(newRating);
}
}
private void OnIsStreamingTimeout(object sender, EventArgs args) => this.SupressDownloads = false;
private void DeserializeNowPlayingList(object arg)
{
string path = arg as string;
object args = null;
if (path != null)
{
if (File.Exists(path))
{
try
{
using (Stream serializationStream = File.OpenRead(path))
args = new BinaryFormatter().Deserialize(serializationStream);
}
catch (Exception ex)
{
}
}
}
if (args == null)
return;
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeserializationComplete), args);
}
private void DeserializationComplete(object arg)
{
NowPlayingList nowPlayingList = arg as NowPlayingList;
if (this._playlistCurrent != null || nowPlayingList == null)
return;
this._playlistCurrent = nowPlayingList;
this.ShowNotification();
this.UpdatePropertiesAndCommands();
if (!this._resumeLastNowPlayingRequested)
return;
this.Play.Invoke();
}
public bool IsInitialized
{
get => this._isInitialized;
private set
{
if (this._isInitialized == value)
return;
this._isInitialized = value;
this.FirePropertyChanged(nameof(IsInitialized));
}
}
public bool HasPlayed
{
get => this._hasPlayed;
private set
{
if (this._hasPlayed == value)
return;
this._hasPlayed = value;
this.FirePropertyChanged(nameof(HasPlayed));
}
}
public event EventHandler PlaybackStopped;
public BooleanChoice Shuffling => this._shuffling;
public BooleanChoice Repeating => this._repeating;
public BooleanChoice Muted => this._muted;
public BooleanChoice ShowTotalTime => this._showTotalTime;
public BooleanChoice ShowNowPlayingList => this._showNowPlayingList;
public BooleanChoice Fastforwarding => this._fastforwarding;
public BooleanChoice Rewinding => this._rewinding;
public RangedValue Volume => this._volume;
public Command Play => this._play;
public Command Pause => this._pause;
public Command Stop => this._stop;
public Command Back => this._back;
public Command Forward => this._forward;
public bool Opening
{
get => this._opening;
private set
{
if (this._opening == value)
return;
this._opening = value;
this.FirePropertyChanged(nameof(Opening));
}
}
public bool Buffering
{
get => this._buffering;
private set
{
if (this._buffering == value)
return;
this._buffering = value;
this.FirePropertyChanged(nameof(Buffering));
}
}
public bool IsSeekEnabled
{
get => this._seekEnabled;
private set
{
if (this._seekEnabled == value)
return;
this._seekEnabled = value;
this.FirePropertyChanged(nameof(IsSeekEnabled));
}
}
public bool IsStreamingVideo
{
get => this._isStreamingVideo;
private set
{
if (this._isStreamingVideo == value)
return;
this._isStreamingVideo = value;
this.FirePropertyChanged(nameof(IsStreamingVideo));
}
}
public bool SupressDownloads
{
get => this._supressDownloads;
private set
{
if (this._supressDownloads == value)
return;
this._supressDownloads = value;
this.FirePropertyChanged(nameof(SupressDownloads));
}
}
public int ZoomScaleFactor
{
get => this._zoomScaleFactor;
set
{
this._zoomScaleFactor = value;
this.FirePropertyChanged(nameof(ZoomScaleFactor));
}
}
public bool Playing => this._isPlaying;
public bool PlayingVideo
{
get => this._playingVideo;
private set
{
if (this._playingVideo == value)
return;
this._playingVideo = value;
this.FirePropertyChanged(nameof(PlayingVideo));
}
}
public Command FastforwardHotkey => this._fastforwardhotkey;
public Command RewindHotkey => this._rewindhotkey;
public int CurrentTrackIndex => this._currentTrackIndex;
public bool WillSaveCurrentPlaylistOnShutdown() => this._playlistCurrent != null && this._playlistCurrent.CurrentTrack != null && !this._playlistCurrent.CurrentTrack.IsVideo && this._playlistCurrent.QuickMixSession == null;
public void StartPlayingAt(PlaybackTrack track)
{
if (this._playlistCurrent == null || this._playlistCurrent.TrackList == null)
return;
int newCurrentIndex = this._playlistCurrent.TrackList.IndexOf(track);
if (newCurrentIndex <= -1)
return;
this.StartPlayingAt(newCurrentIndex);
}
public void StartPlayingAt(int newCurrentIndex)
{
if (this._playlistCurrent == null)
return;
this._playlistCurrent.MoveToTrackIndex(newCurrentIndex);
if (this._playerState == PlayerState.Playing)
{
this.SetUriOnPlayer();
}
else
{
this._playlistPending = this._playlistCurrent;
if (this._playerState == PlayerState.Paused)
this._playbackWrapper.Stop();
else
this.PlayPendingList();
}
}
public void CloseCurrentSession() => this.Stop.Invoke();
public void SeekToPosition(float value)
{
long offsetIn100nsUnits = (long)(value * 10000000.0);
if (this._playbackWrapper != null)
this._playbackWrapper.SeekToAbsolutePosition(offsetIn100nsUnits);
this._rewinding.Value = false;
this._fastforwarding.Value = false;
}
public float CurrentTrackDuration
{
get => this._currentTrackDuration;
private set
{
if (_currentTrackDuration == (double)value)
return;
this._currentTrackDuration = value;
this.FirePropertyChanged(nameof(CurrentTrackDuration));
}
}
public float CurrentTrackPosition
{
get => this._currentTrackPosition;
private set
{
if (_currentTrackPosition == (double)value)
return;
this._currentTrackPosition = value;
this.FirePropertyChanged(nameof(CurrentTrackPosition));
}
}
public float CurrentTrackDownloadProgress
{
get => this._downloadProgress;
private set
{
if (_downloadProgress == (double)value)
return;
this._downloadProgress = value;
this.FirePropertyChanged(nameof(CurrentTrackDownloadProgress));
}
}
public PlaybackTrack CurrentTrack => this._currentTrack;
public int CurrentTrackRating => this.CurrentTrack == null || !this.CurrentTrack.CanRate ? 0 : this.CurrentTrack.UserRating;
public bool ShowErrors
{
get => this._showErrors;
set
{
if (this._showErrors == value)
return;
this._showErrors = value;
this.FirePropertyChanged(nameof(ShowErrors));
}
}
public void ClearAllErrors()
{
if (this._errors.Count <= 0)
return;
this._errors.Clear();
this.FirePropertyChanged("ErrorCount");
}
public bool IsCurrentTrack(Guid zuneMediaId)
{
PlaybackTrack currentTrack = this.CurrentTrack;
return currentTrack != null && !GuidHelper.IsEmpty(currentTrack.ZuneMediaId) && currentTrack.ZuneMediaId == zuneMediaId;
}
public int GetErrorCode(Guid zuneMediaId)
{
if (this._errors.Count > 0)
{
foreach (KeyValuePair<PlaybackTrack, int> error in this._errors)
{
PlaybackTrack key = error.Key;
if (key != null && key.ZuneMediaId == zuneMediaId)
return error.Value;
}
}
return 0;
}
public bool IsCurrentTrack(int id, MediaType type, Guid zuneMediaId)
{
if (!(this.CurrentTrack is LibraryPlaybackTrack currentTrack))
return this.IsCurrentTrack(zuneMediaId);
return currentTrack.MediaId == id && currentTrack.MediaType == type;
}
public int GetLibraryErrorCode(int id, MediaType type)
{
if (this._errors.Count > 0)
{
foreach (KeyValuePair<PlaybackTrack, int> error in this._errors)
{
if (error.Key is LibraryPlaybackTrack key && key.MediaId == id && key.MediaType == type)
return error.Value;
}
}
return 0;
}
public int GetLibraryErrorCode(PlaybackTrack track)
{
int num;
return this._errors.TryGetValue(track, out num) ? num : 0;
}
internal void ClearError(PlaybackTrack track)
{
if (!this._errors.Remove(track))
return;
this.FirePropertyChanged("ErrorCount");
}
public int ErrorCount => this._errors.Count;
public VideoStream VideoStream => this._videoStream;
public bool CanRender3DVideo => Application.RenderingType != RenderingType.GDI;
public bool HasPlaylist => this._hasPlaylist;
public bool PlaylistSupportsShuffle => this._playlistSupportsShuffle;
public ArrayListDataSet CurrentPlaylist => this._currentPlaylist;
public string QuickMixTitle
{
get
{
string str = string.Empty;
if (this._playlistCurrent != null)
str = this._playlistCurrent.QuickMixTitle;
return str;
}
}
public EQuickMixType QuickMixType
{
get
{
EQuickMixType equickMixType = EQuickMixType.eQuickMixTypeInvalid;
if (this._playlistCurrent != null)
equickMixType = this._playlistCurrent.QuickMixType;
return equickMixType;
}
}
public bool DontPlayMarketplaceTracks
{
get => this._dontPlayMarketplaceTracks;
set
{
if (value == this._dontPlayMarketplaceTracks)
return;
this._dontPlayMarketplaceTracks = value;
if (this._playlistCurrent != null)
this._playlistCurrent.DontPlayMarketplaceTracks = this._dontPlayMarketplaceTracks;
if (this._playlistPending == null)
return;
this._playlistPending.DontPlayMarketplaceTracks = this._dontPlayMarketplaceTracks;
}
}
public QuickMixSession QuickMixSession
{
get
{
QuickMixSession quickMixSession = null;
if (this._playlistCurrent != null)
quickMixSession = this._playlistCurrent.QuickMixSession;
return quickMixSession;
}
}
public bool IsPlaybackContextCompatible => this._isContextCompatible;
public JumpListPin RequestedJumpListPin
{
get => !this.IsInitialized ? null : this._requestedJumpListPin;
set
{
if (this._requestedJumpListPin == value)
return;
this._requestedJumpListPin = value;
if (!this.IsInitialized)
return;
this.FirePropertyChanged(nameof(RequestedJumpListPin));
}
}
public bool ShuffleAllRequested
{
get => this.IsInitialized && this._shuffleAllRequested;
set
{
if (this._shuffleAllRequested == value)
return;
this._shuffleAllRequested = value;
if (!this.IsInitialized)
return;
this.FirePropertyChanged(nameof(ShuffleAllRequested));
}
}
public int BandwidthCapacity
{
get => this._bandwidthCapacity;
private set
{
this._bandwidthCapacity = value;
this.FirePropertyChanged(nameof(BandwidthCapacity));
}
}
public BandwidthUpdateArgs BandwidthUpdateInfo
{
get => this._bandwidthUpdateInfo;
private set
{
this._bandwidthUpdateInfo = value;
this.FirePropertyChanged(nameof(BandwidthUpdateInfo));
}
}
private void OnBandwidthCapacityUpdate(object sender, BandwidthUpdateArgs args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnBandwidthCapacityUpdateOnApp), args);
private void OnBandwidthCapacityUpdateOnApp(object obj)
{
if (obj == null)
return;
BandwidthUpdateArgs bandwidthUpdateArgs = (BandwidthUpdateArgs)obj;
if (bandwidthUpdateArgs == null || bandwidthUpdateArgs.currentState != MBRHeuristicState.Playback)
return;
this.BandwidthCapacity = bandwidthUpdateArgs.RecentAverageBandwidth;
this.BandwidthUpdateInfo = bandwidthUpdateArgs;
}
private void OnStreamingRestrictionResponse(HRESULT hr)
{
if (!hr.IsError)
return;
string title = Shell.LoadString(StringId.IDS_PLAYBACK_CANNOT_PLAY);
string description;
if (hr == HRESULT._ZEST_E_MAX_CONCURRENTSTREAMING_EXCEEDED || hr == HRESULT._ZEST_E_MULTITUNER_CONCURRENTSTREAMING_DETECTED || hr == HRESULT._ZEST_E_MEDIAINSTANCE_STREAMING_OCCUPIED)
description = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int).Description;
else
description = Shell.LoadString(StringId.IDS_PLAYBACK_UNKNOWN_CONCURRENT_STREAMING_RESTRICTION);
Application.DeferredInvoke(delegate
{
this.Stop.Invoke();
MessageBox.Show(title, description, null);
}, DeferredInvokePriority.Low);
}
private void ReportStreamingAction(PlayerState previousPlayerState)
{
if (this.CurrentTrack != null && this.CurrentTrack.IsVideo && this.CurrentTrack.IsStreaming)
{
Guid zuneMediaId = this.CurrentTrack.ZuneMediaId;
if (zuneMediaId != this._streamingReportMediaId && this._streamingReportIsOpen)
{
this._streamingReportIsOpen = false;
previousPlayerState = PlayerState.Stopped;
Service.Instance.ReportStreamingAction(EStreamingActionType.Stop, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse));
}
if (previousPlayerState == PlayerState.Stopped && this._playerState == PlayerState.Playing)
{
this._streamingReportMediaInstanceId = this.CurrentTrack.ZuneMediaInstanceId;
if (!(this._streamingReportMediaInstanceId != Guid.Empty))
return;
this._streamingReportIsOpen = true;
this._streamingReportMediaId = zuneMediaId;
Service.Instance.ReportStreamingAction(EStreamingActionType.Start, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse));
}
else if (previousPlayerState == PlayerState.Paused && this._playerState == PlayerState.Playing)
Service.Instance.ReportStreamingAction(EStreamingActionType.Resume, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse));
else if (this._playerState == PlayerState.Paused)
{
Service.Instance.ReportStreamingAction(EStreamingActionType.Pause, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse));
}
else
{
if (this._playerState != PlayerState.Stopped)
return;
this._streamingReportIsOpen = false;
Service.Instance.ReportStreamingAction(EStreamingActionType.Stop, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse));
}
}
else
{
if (!this._streamingReportIsOpen)
return;
this._streamingReportIsOpen = false;
Service.Instance.ReportStreamingAction(EStreamingActionType.Stop, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse));
}
}
private void SetPlayerState(PlayerState stateNew)
{
PlayerState playerState = this._playerState;
if (stateNew != this._playerState)
{
this._playerState = stateNew;
if (this._playerState == PlayerState.Stopped)
{
this._rewinding.Value = false;
this._fastforwarding.Value = false;
++this._lastKnownSetUriCallID;
this.FirePropertyChanged("PlaybackStopped");
if (this.PlaybackStopped != null)
this.PlaybackStopped(this, null);
}
}
this.UpdatePropertiesAndCommands();
this.ReportStreamingAction(playerState);
}
public void PlayItem(
object item,
PlayNavigationOptions playNavigationOptions,
PlaybackContext playbackContext)
{
ArrayListDataSet arrayListDataSet = new ArrayListDataSet();
arrayListDataSet.Add(item);
this.PlayItemsWorker(arrayListDataSet, -1, true, playNavigationOptions, playbackContext, null);
}
public void PlayItem(object item) => this.PlayItem(item, PlayNavigationOptions.NavigateVideosToNowPlaying);
public void PlayItem(object item, PlayNavigationOptions playNavigationOptions)
{
ArrayListDataSet arrayListDataSet = new ArrayListDataSet();
arrayListDataSet.Add(item);
this.PlayItemsWorker(arrayListDataSet, -1, true, playNavigationOptions, null);
}
public void PlayItem(object item, PlaybackContext playbackContext)
{
ArrayListDataSet arrayListDataSet = new ArrayListDataSet();
arrayListDataSet.Add(item);
this.PlayItemsWorker(arrayListDataSet, -1, true, PlayNavigationOptions.NavigateVideosToNowPlaying, playbackContext, null);
}
public void PlayItems(IList items) => this.PlayItemsWorker(items, -1, true, PlayNavigationOptions.NavigateVideosToNowPlaying, null);
public void PlayItems(IList items, PlayNavigationOptions playNavigationOptions) => this.PlayItemsWorker(items, -1, true, playNavigationOptions, null);
public void PlayItems(
IList items,
PlayNavigationOptions playNavigationOptions,
ContainerPlayMarker containerPlayMarker)
{
this.PlayItemsWorker(items, -1, true, playNavigationOptions, containerPlayMarker);
}
public void PlayItems(
IList items,
PlayNavigationOptions playNavigationOptions,
PlaybackContext playbackContext)
{
this.PlayItemsWorker(items, -1, true, playNavigationOptions, playbackContext, null);
}
public void PlayItems(IList items, PlaybackContext playbackContext) => this.PlayItemsWorker(items, -1, true, PlayNavigationOptions.NavigateVideosToNowPlaying, playbackContext, null);
public void PlayItems(IList items, int startIndex) => this.PlayItemsWorker(items, startIndex, true, PlayNavigationOptions.NavigateVideosToNowPlaying, null);
public void PlayItems(
IList items,
int startIndex,
PlayNavigationOptions playNavigationOptions,
ContainerPlayMarker containerPlayMarker)
{
this.PlayItemsWorker(items, startIndex, true, PlayNavigationOptions.NavigateVideosToNowPlaying, containerPlayMarker);
}
public void AddToNowPlaying(IList items)
{
int count = this.PlayItemsWorker(items, -1, false, PlayNavigationOptions.NavigateVideosToNowPlaying, null);
if (count <= 0)
return;
PlaylistManager.Instance.NotifyItemsAdded(-1, count);
}
private int PlayItemsWorker(
IList items,
int startIndex,
bool clearQueue,
PlayNavigationOptions playNavigationOptions,
ContainerPlayMarker containerPlayMarker)
{
return this.PlayItemsWorker(items, startIndex, clearQueue, playNavigationOptions, this._shellInstance.CurrentPage.PlaybackContext, containerPlayMarker);
}
private int PlayItemsWorker(
IList items,
int startIndex,
bool clearQueue,
PlayNavigationOptions playNavigationOptions,
PlaybackContext playbackContext,
ContainerPlayMarker containerPlayMarker)
{
PerfTrace.TraceUICollectionEvent(UICollectionEvent.PlayRequestIssued, "");
bool flag = this._playlistCurrent != null;
int num;
if (clearQueue || !flag)
{
if (clearQueue || this._playlistPending == null)
{
if (this._playlistPending != null)
this._playlistPending.Dispose();
this._playlistPending = new NowPlayingList(items, startIndex, playbackContext, playNavigationOptions, this._shuffling.Value, containerPlayMarker, this._dontPlayMarketplaceTracks);
num = this._playlistPending.Count;
}
else
num = this._playlistPending.AddItems(items);
if (playbackContext == PlaybackContext.QuickMix)
{
if (this._lastKnownTransportState == MCTransportState.Playing || this._lastKnownTransportState == MCTransportState.Paused)
this._playbackWrapper.Stop();
else
this._playlistPending.PlayWhenReady = true;
}
else if (this._playlistPending.Count == 0)
{
this._playlistPending.Dispose();
this._playlistPending = null;
this.Stop.Invoke();
}
else if (flag && (this._lastKnownTransportState == MCTransportState.Playing || this._lastKnownTransportState == MCTransportState.Paused))
this._playbackWrapper.Stop();
else
this.PlayPendingList();
}
else
{
num = this._playlistCurrent.AddItems(items);
if (this._playlistPending != null)
this._playlistPending.Dispose();
this._playlistPending = null;
this.UpdateNextTrack();
}
return num;
}
internal void PlayPendingList()
{
if (this._playlistPending == null)
return;
if (this._playlistCurrent != null && this._playlistCurrent != this._playlistPending)
this._playlistCurrent.Dispose();
this._playlistCurrent = this._playlistPending;
this._playlistPending = null;
this._playlistCurrent.SetShuffling(this._shuffling.Value);
this._playlistCurrent.SetRepeating(this._repeating.Value);
this._consecutiveErrors = 0;
if (this._errors.Count > 0)
{
this.FirePropertyChanged("ErrorCount");
this._errors.Clear();
}
this.SetPlayerState(PlayerState.Playing);
this.SetUriOnPlayer();
bool flag1 = false;
if (this._playlistCurrent != null)
{
PlaybackTrack currentTrack = this._playlistCurrent.CurrentTrack;
PlayNavigationOptions navigationOptions = this._playlistCurrent.PlayNavigationOptions;
bool flag2 = false;
if (currentTrack != null && currentTrack.IsVideo)
flag1 = true;
switch (navigationOptions)
{
case PlayNavigationOptions.None:
if (flag2)
{
NowPlayingLand.NavigateToLand(navigationOptions == PlayNavigationOptions.NavigateToNowPlayingWithMix, true);
break;
}
break;
case PlayNavigationOptions.NavigateVideosToNowPlaying:
if (flag1)
{
flag2 = true;
goto case PlayNavigationOptions.None;
}
else
goto case PlayNavigationOptions.None;
default:
flag2 = true;
this._playlistCurrent.PlayNavigationOptions = PlayNavigationOptions.NavigateVideosToNowPlaying;
goto case PlayNavigationOptions.None;
}
}
this.PlayingVideo = flag1;
}
public void RemoveFromNowPlaying(IList indices)
{
if (this._playlistCurrent == null)
return;
bool flag = this._playlistCurrent.Remove(indices);
if (this._playlistCurrent.Count == 0)
this.Stop.Invoke();
else if (flag)
this.SetUriOnPlayer();
else
this.UpdateNextTrack();
}
public void ReorderNowPlaying(IList indices, int targetIndex)
{
if (this._playlistCurrent == null)
return;
this._playlistCurrent.Reorder(indices, targetIndex);
this.UpdateNextTrack();
}
public IList GetNextTracks(int count)
{
IList list = null;
if (this._playlistCurrent != null)
list = this._playlistCurrent.GetNextTracks(count);
return list;
}
public IList CreateAlbumListForBackground(IList allAlbums, int totalDesired)
{
List<object> objectList1 = new List<object>(totalDesired);
Dictionary<int, object> dictionary = new Dictionary<int, object>();
if (this._playlistCurrent != null)
{
int num = Math.Min(this._playlistCurrent.Count, totalDesired);
for (int itemIndex = 0; itemIndex < num; ++itemIndex)
{
if (this._playlistCurrent.TrackList[itemIndex] is LibraryPlaybackTrack track && track.MediaType == MediaType.Track)
dictionary[track.AlbumLibraryId] = null;
}
}
List<object> objectList2 = new List<object>(totalDesired);
for (int index = 0; index < allAlbums.Count; ++index)
{
DataProviderObject allAlbum = (DataProviderObject)allAlbums[index];
int property = (int)allAlbum.GetProperty("LibraryId");
if ((bool)allAlbum.GetProperty("HasAlbumArt"))
{
if (dictionary.ContainsKey(property))
objectList1.Add(allAlbum);
else if (objectList2.Count < totalDesired)
objectList2.Add(allAlbum);
}
if (objectList1.Count >= totalDesired)
break;
}
for (int index = 0; index < objectList2.Count && objectList1.Count < totalDesired; ++index)
objectList1.Add(objectList2[index]);
if (objectList1.Count == 0)
return null;
foreach (object album in objectList1)
this.DisableSlowDataThumbnailExtraction(album);
int num1 = 0;
while (objectList1.Count < totalDesired)
objectList1.Add(objectList1[num1++]);
Random random = new Random();
for (int index1 = objectList1.Count - 1; index1 > 0; --index1)
{
int index2 = random.Next(index1 + 1);
object obj = objectList1[index2];
objectList1[index2] = objectList1[index1];
objectList1[index1] = obj;
}
return new ListDataSet(objectList1);
}
public void DisableSlowDataThumbnailExtraction(object album)
{
if (!(album is LibraryDataProviderItemBase providerItemBase))
return;
providerItemBase.SetSlowDataThumbnailExtraction(false);
}
public void Phase2Init()
{
if (!this.CanRender3DVideo)
this._playbackWrapper.WindowHandle = Application.Window.Handle;
else
this._playbackWrapper.DynamicImage = this._videoStream.StreamID;
ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncPhase2Init), null);
}
private void AsyncPhase2Init(object arg)
{
this._playbackWrapper.Initialize();
Application.DeferredInvoke(new DeferredInvokeHandler(this.CompletePhase2Init), null);
}
private void CompletePhase2Init(object obj)
{
this._playbackWrapper.Volume = (int)this._volume.Value;
this._playbackWrapper.Mute = this._muted.Value;
this._isSpectrumAvailable = true;
this.ConnectAllSpectrumAnimationSources();
this._taskbarPlayer.Initialize(Application.Window.Handle, new TaskbarPlayerCommandHandler(this.OnTaskbarPlayerCommand));
this.IsInitialized = true;
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DeserializeNowPlayingList), _savedNowPlayingFilename);
if (this.RequestedJumpListPin != null)
this.FirePropertyChanged("RequestedJumpListPin");
if (!this.ShuffleAllRequested)
return;
this.FirePropertyChanged("ShuffleAllRequested");
}
private void OnTaskbarPlayerCommand(ETaskbarPlayerCommand command, int value)
{
switch (command)
{
case ETaskbarPlayerCommand.PC_Connect:
this.UpdateTaskbarPlayer();
break;
case ETaskbarPlayerCommand.PC_Play:
this.Play.Invoke();
break;
case ETaskbarPlayerCommand.PC_Pause:
this.Pause.Invoke();
break;
case ETaskbarPlayerCommand.PC_Forward:
this.Forward.Invoke();
break;
case ETaskbarPlayerCommand.PC_Back:
this.Back.Invoke();
break;
case ETaskbarPlayerCommand.PC_Rate:
if (this.CurrentTrack == null || !this.CurrentTrack.CanRate)
break;
switch ((ETaskbarPlayerState)value)
{
case ETaskbarPlayerState.PS_RatingNotRated:
this.CurrentTrack.UserRating = 0;
break;
case ETaskbarPlayerState.PS_RatingLoveIt:
this.CurrentTrack.UserRating = 8;
break;
case ETaskbarPlayerState.PS_RatingHateIt:
this.CurrentTrack.UserRating = 2;
break;
}
this.UpdateTaskbarPlayer();
break;
}
}
private void UpdateTaskbarPlayer()
{
ETaskbarPlayerState etaskbarPlayerState1 = (ETaskbarPlayerState)(0 | (this._playerState == PlayerState.Playing ? 2 : 0) | (this._playerState == PlayerState.Paused ? 4 : 0) | (this._playerState == PlayerState.Stopped ? 1 : 0));
ETaskbarPlayerState etaskbarPlayerState2;
if (this.CurrentTrack != null && this.CurrentTrack.CanRate)
{
RatingConstants userRating = (RatingConstants)this.CurrentTrack.UserRating;
etaskbarPlayerState2 = userRating != RatingConstants.Unrated ? (userRating > RatingConstants.MaxHateIt ? etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingLoveIt : etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingHateIt) : etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingNotRated;
}
else
etaskbarPlayerState2 = etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingNotRated;
ETaskbarPlayerState state = etaskbarPlayerState2 | (this.Play.Available ? ETaskbarPlayerState.PS_CanPlay : 0) | (this.Pause.Available ? ETaskbarPlayerState.PS_CanPause : 0) | (this.Forward.Available ? ETaskbarPlayerState.PS_CanForward : 0) | (this.Back.Available ? ETaskbarPlayerState.PS_CanBack : 0);
if (this.CurrentTrack != null && this.CurrentTrack.CanRate)
state |= ETaskbarPlayerState.PS_CanRate;
this._taskbarPlayer.UpdateToolbar(state);
}
public int CreateSpectrumAnimationSource(
int numBands,
bool outputFrequencyData,
bool outputWaveformData,
bool enableStereoOutput)
{
Dictionary<string, int> dictionary = new Dictionary<string, int>();
for (int index = 0; index < numBands; ++index)
{
if (outputFrequencyData)
{
if (!enableStereoOutput)
{
dictionary[string.Format("Frequency{0}", index)] = index;
}
else
{
dictionary[string.Format("FrequencyL{0}", index)] = index;
dictionary[string.Format("FrequencyR{0}", index)] = index + 1024;
}
}
if (outputWaveformData)
{
if (!enableStereoOutput)
{
dictionary[string.Format("Waveform{0}", index)] = index + 2048;
}
else
{
dictionary[string.Format("WaveformL{0}", index)] = index + 2048;
dictionary[string.Format("WaveformR{0}", index)] = index + 3072;
}
}
}
int externalAnimationInput = Application.CreateExternalAnimationInput(dictionary);
SpectrumOutputConfig spectrumOutputConfig = new SpectrumOutputConfig();
spectrumOutputConfig.SourceId = (uint)externalAnimationInput;
spectrumOutputConfig.NumBands = (uint)numBands;
spectrumOutputConfig.Frequency = outputFrequencyData;
spectrumOutputConfig.Waveform = outputWaveformData;
spectrumOutputConfig.Stereo = enableStereoOutput;
spectrumOutputConfig.IsConnected = this._isSpectrumAvailable;
this._spectrumConfigList.Add(spectrumOutputConfig);
if (this._isSpectrumAvailable)
this._playbackWrapper.ConnectAnimationsToSpectrumAnalyzer(spectrumOutputConfig.SourceId, spectrumOutputConfig.NumBands, spectrumOutputConfig.Frequency, spectrumOutputConfig.Waveform, spectrumOutputConfig.Stereo);
return externalAnimationInput;
}
public void DisposeSpectrumAnimationSource(int inputSourceId)
{
if (inputSourceId <= 0)
return;
for (int index = 0; index < this._spectrumConfigList.Count; ++index)
{
SpectrumOutputConfig spectrumConfig = this._spectrumConfigList[index];
if (spectrumConfig.SourceId == inputSourceId)
{
if (spectrumConfig.IsConnected)
{
this._playbackWrapper.DisconnectAnimationsFromSpectrumAnalyzer(spectrumConfig.SourceId);
spectrumConfig.IsConnected = false;
}
Application.DisposeExternalAnimationInput(inputSourceId);
this._spectrumConfigList.RemoveAt(index);
break;
}
}
}
public void ConnectAllSpectrumAnimationSources()
{
for (int index = 0; index < this._spectrumConfigList.Count; ++index)
{
SpectrumOutputConfig spectrumConfig = this._spectrumConfigList[index];
if (!spectrumConfig.IsConnected)
{
this._playbackWrapper.ConnectAnimationsToSpectrumAnalyzer(spectrumConfig.SourceId, spectrumConfig.NumBands, spectrumConfig.Frequency, spectrumConfig.Waveform, spectrumConfig.Stereo);
spectrumConfig.IsConnected = true;
this._spectrumConfigList[index] = spectrumConfig;
}
}
}
public void DisconnectAllSpectrumAnimationSources()
{
if (!this._isSpectrumAvailable)
return;
for (int index = 0; index < this._spectrumConfigList.Count; ++index)
{
SpectrumOutputConfig spectrumConfig = this._spectrumConfigList[index];
if (spectrumConfig.IsConnected)
{
this._playbackWrapper.DisconnectAnimationsFromSpectrumAnalyzer(spectrumConfig.SourceId);
spectrumConfig.IsConnected = false;
this._spectrumConfigList[index] = spectrumConfig;
}
}
}
public void ResumeLastNowPlayingHandler()
{
if (!this.IsInitialized)
{
this._resumeLastNowPlayingRequested = true;
}
else
{
if (this._isPlaying)
return;
this.Play.Invoke();
}
}
private void OnShellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
if (!(args.PropertyName == "CurrentPage"))
return;
this._pagePlaybackContext = this._shellInstance.CurrentPage.PlaybackContext;
this.UpdatePropertiesAndCommands();
}
private void OnDownloadProgressed(Guid zuneMediaId, float percent)
{
if (this.CurrentTrack == null || !(this.CurrentTrack.ZuneMediaId == zuneMediaId))
return;
this.CurrentTrackDownloadProgress = percent;
}
private void OnShufflingChanged(object sender, EventArgs e)
{
if (this._playlistCurrent != null)
{
this._playlistCurrent.SetShuffling(this._shuffling.Value);
this.UpdateNextTrack();
}
this.UpdateShufflingDescription();
this.PersistSettings();
SQMLog.Log(SQMDataId.ShuffleClicks, 1);
}
private void UpdateShufflingDescription() => this._shuffling.Description = Shell.LoadString(!this._shuffling.Value ? StringId.IDS_SHUFFLE_ON : StringId.IDS_SHUFFLE_OFF);
private void OnRepeatingChanged(object sender, EventArgs e)
{
if (this._playlistCurrent != null)
{
this._playlistCurrent.SetRepeating(this._repeating.Value);
this.UpdateNextTrack();
}
SQMLog.Log(SQMDataId.RepeatClicks, 1);
this.UpdateRepeatingDescription();
this.PersistSettings();
}
private void UpdateRepeatingDescription() => this._repeating.Description = Shell.LoadString(!this._repeating.Value ? StringId.IDS_REPEAT_ON : StringId.IDS_REPEAT_OFF);
private void OnMutingChanged(object sender, EventArgs e)
{
this.UpdateMutingDescription();
this._playbackWrapper.Mute = this._muted.Value;
SQMLog.Log(SQMDataId.VolumeMuteClicks, 1);
this.PersistSettings();
}
private void UpdateMutingDescription() => this._muted.Description = Shell.LoadString(!this._muted.Value ? StringId.IDS_MUTE : StringId.IDS_UNMUTE);
private void OnShowTotalTimeChanged(object sender, EventArgs e) => this.PersistSettings();
private void OnShowNowPlayingListChanged(object sender, EventArgs e)
{
this.UpdateShowNowPlayingListDescription();
this.PersistSettings();
}
private void UpdateShowNowPlayingListDescription() => this._showNowPlayingList.Description = Shell.LoadString(!this._showNowPlayingList.Value ? StringId.IDS_NOWPLAYINGLIST_ON : StringId.IDS_NOWPLAYINGLIST_OFF);
private void OnPlayingChanged(object sender, EventArgs e)
{
}
private void OnPlayClicked(object sender, EventArgs e)
{
if (!this._play.Available)
return;
SQMLog.Log(SQMDataId.PlayClicks, 1);
if (this.Playing || this._playlistCurrent == null)
return;
if (this._lastKnownPlayerState != MCPlayerState.Closed)
{
this.SetPlayerState(PlayerState.Playing);
this._playbackWrapper.Play();
if (!this.PlayingVideo || this._playlistCurrent.PlayNavigationOptions != PlayNavigationOptions.NavigateVideosToNowPlaying)
return;
NowPlayingLand.NavigateToLand();
}
else
{
if (this._playlistPending != null)
this._playlistPending.Dispose();
this._playlistPending = this._playlistCurrent;
this.PlayPendingList();
}
}
private void OnPauseClicked(object sender, EventArgs e)
{
if (!this._pause.Available)
return;
SQMLog.Log(SQMDataId.PauseClicks, 1);
if (!this.Playing)
return;
this.SetPlayerState(PlayerState.Paused);
this._playbackWrapper.Pause();
}
private void OnStopClicked(object sender, EventArgs e)
{
if (!this._stop.Available)
return;
SQMLog.Log(SQMDataId.StopClicks, 1);
if (this._playlistPending != null)
this._playlistPending.Dispose();
this._playlistPending = null;
if (this._playlistCurrent != null)
this._playlistCurrent.Dispose();
this._playlistCurrent = null;
if (this._playerState != PlayerState.Stopped)
{
this.SetPlayerState(PlayerState.Stopped);
this._playbackWrapper.Stop();
}
else
this.UpdatePropertiesAndCommands();
}
private void OnBackClicked(object sender, EventArgs e)
{
if (!this._back.Available || this._playlistCurrent == null)
return;
SQMLog.Log(SQMDataId.SkipBackwardClicks, 1);
if (this._lastKnownPosition > 50000000L || !this._playlistCurrent.CanRetreat)
{
this._playbackWrapper.SeekToAbsolutePosition(0L);
}
else
{
this._playlistCurrent.Retreat();
this.SetUriOnPlayer();
}
}
private void OnForwardClicked(object sender, EventArgs e)
{
if (!this._forward.Available || this._playlistCurrent == null)
return;
SQMLog.Log(SQMDataId.SkipForwardClicks, 1);
if (this._currentTrack != null && this._currentTrack.IsVideo)
return;
if (this._lastKnownPlaybackTrack != null)
this._lastKnownPlaybackTrack.OnSkip();
if (this._playlistCurrent.CanAdvance)
{
this._playlistCurrent.Advance();
this.SetUriOnPlayer();
}
else
{
this.SetPlayerState(PlayerState.Stopped);
this._playbackWrapper.Stop();
}
}
private void OnFastforwardingChanged(object sender, EventArgs e)
{
if ((this._currentTrack == null || !this._currentTrack.IsVideo || this._playbackWrapper.CanChangeVideoRate) && this._fastforwarding.Value)
{
this._rewinding.Value = false;
this._playbackWrapper.Rate = 5f;
}
else
this._playbackWrapper.Rate = 1f;
}
private void OnRewindingChanged(object sender, EventArgs e)
{
if ((this._currentTrack == null || !this._currentTrack.IsVideo || this._playbackWrapper.CanChangeVideoRate) && this._rewinding.Value)
{
this._fastforwarding.Value = false;
this._playbackWrapper.Rate = -5f;
}
else
this._playbackWrapper.Rate = 1f;
}
private void OnFastforwardHotkeyPressed(object sender, EventArgs e) => this._fastforwarding.Value = !this._fastforwarding.Value;
private void OnRewindHotkeyPressed(object sender, EventArgs e) => this._rewinding.Value = !this._rewinding.Value;
private void OnPlaybackStatusChanged(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPlaybackStatusChanged), new object[2]
{
_playbackWrapper.State,
_playbackWrapper.EndOfMedia
});
private void OnTransportStatusChanged(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredTransportStatusChanged), new object[3]
{
_playbackWrapper.TransportState,
_playbackWrapper.EndOfMedia,
_playbackWrapper.CanSeek
});
private void OnTransportPositionChanged(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredTransportPositionChanged), _playbackWrapper.Position);
private void OnUriSet(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredUriSet), new object[2]
{
_playbackWrapper.CurrentUri,
_playbackWrapper.CurrentUriID
});
private void OnAlertSent(Announcement alert) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredAlertHandler), alert);
private void OnPlayerPropertyChanged(object sender, PlayerPropertyChangedEventArgs e)
{
if (e.Key == "presentationinfo")
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPresentationInfoChangedHandler), e.Value);
else if (e.Key == "volumeinfo")
{
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredVolumeInfoChangedHandler), e.Value);
}
else
{
if (!(e.Key == "canchangevideorate"))
return;
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredCanChangeVideoRateHandler), e.Value);
}
}
private void OnVolumeControlChanged(object sender, PropertyChangedEventArgs e)
{
if (!(e.PropertyName == "Value"))
return;
this._muted.Value = false;
this._playbackWrapper.Mute = false;
this._playbackWrapper.Volume = (int)this._volume.Value;
SQMLog.Log(SQMDataId.VolumeAdjustmentClicks, 1);
this.PersistSettings();
}
private void OnVideoDetailsChanged(object sender, EventArgs args)
{
this._playbackWrapper.VideoPosition = new VideoWindow(this._videoStream.DisplayPosition.X, this._videoStream.DisplayPosition.Y, this._videoStream.DisplayPosition.X + this._videoStream.DisplaySize.Width, this._videoStream.DisplayPosition.Y + this._videoStream.DisplaySize.Height);
this._playbackWrapper.ShowGDIVideo = this._videoStream.DisplayVisibility;
}
private void DeferredPlaybackStatusChanged(object obj)
{
if (this.IsDisposed)
return;
object[] objArray = (object[])obj;
MCPlayerState mcPlayerState = (MCPlayerState)objArray[0];
bool endOfMedia = (bool)objArray[1];
bool flag = false;
switch (mcPlayerState)
{
case MCPlayerState.Closed:
if (this.Playing)
{
this.SetUriOnPlayer();
break;
}
break;
case MCPlayerState.Open:
this._rewinding.Value = false;
this._fastforwarding.Value = false;
flag = true;
break;
case MCPlayerState.Built:
if (this.Playing && this._lastKnownPlaybackTrack != null)
{
this._lastKnownPlaybackTrack.OnEndPlayback(endOfMedia);
this._lastKnownPlaybackTrack = this._lastKnownPreparedTrack;
this._lastKnownPreparedTrack = null;
if (this._lastKnownPlaybackTrack != null)
this._lastKnownPlaybackTrack.OnBeginPlayback(this._playbackWrapper);
}
this.CurrentTrackDuration = this._playbackWrapper.Duration >= 0L ? _playbackWrapper.Duration / 1E+07f : 0.0f;
break;
}
this._lastKnownPlayerState = mcPlayerState;
if (this._opening == flag)
return;
this.Opening = flag;
}
private void ShowNotification()
{
if (this._nowPlayingNotification == null)
{
this._nowPlayingNotification = new NowPlayingNotification();
NotificationArea.Instance.Add(this._nowPlayingNotification);
}
else
NotificationArea.Instance.ForceToFront(this._nowPlayingNotification);
}
private void HideNotification()
{
if (this._nowPlayingNotification == null)
return;
NotificationArea.Instance.Remove(this._nowPlayingNotification);
this._nowPlayingNotification = null;
}
public void ShowPreparingNotification()
{
this.HideNotification();
this.HidePreparingNotification(false);
NotificationArea.Instance.Add(new PreparingPlayNotification());
}
public void HidePreparingNotification() => this.HidePreparingNotification(true);
private void HidePreparingNotification(bool restoreNowPlayingNotification)
{
NotificationArea.Instance.RemoveAll(NotificationTask.PreparingPlay, NotificationState.Normal);
if (!restoreNowPlayingNotification || this._playlistCurrent == null)
return;
this.ShowNotification();
}
private void DeferredTransportStatusChanged(object obj)
{
if (this.IsDisposed)
return;
object[] objArray = (object[])obj;
MCTransportState mcTransportState = (MCTransportState)objArray[0];
bool endOfMedia = (bool)objArray[1];
this.IsSeekEnabled = (bool)objArray[2];
if (mcTransportState == MCTransportState.Buffering)
{
this.Buffering = true;
this.UpdatePropertiesAndCommands();
}
else
{
if (this.Buffering)
{
this.Buffering = false;
this.UpdatePropertiesAndCommands();
}
switch (mcTransportState)
{
case MCTransportState.Stopped:
bool flag = this._playlistCurrent != null && this._playlistCurrent.Count == 1 && this._repeating.Value && endOfMedia;
if (this._lastKnownPlaybackTrack != null)
{
this._lastKnownPlaybackTrack.OnEndPlayback(endOfMedia);
if (!flag)
this._lastKnownPlaybackTrack = null;
}
if (this._playlistPending != null)
{
if (this._playlistPending.TrackList != null && this._playlistPending.TrackList.Count > 0)
{
this.PlayPendingList();
break;
}
this.SetPlayerState(PlayerState.Stopped);
this._playlistPending.PlayWhenReady = true;
break;
}
if (this._lastKnownPreparedTrack != null)
{
this._lastKnownPlaybackTrack = this._lastKnownPreparedTrack;
this._lastKnownPlaybackTrack.OnBeginPlayback(this._playbackWrapper);
if (this.Playing)
this._playbackWrapper.Play();
this._lastKnownPreparedTrack = null;
break;
}
if (flag && this._lastKnownPlaybackTrack != null)
{
this._lastKnownPlaybackTrack.OnBeginPlayback(this._playbackWrapper);
this._playbackWrapper.SeekToAbsolutePosition(0L);
this._playbackWrapper.Play();
break;
}
if (this._playlistCurrent != null)
this._playlistCurrent.ResetForReplay();
this.SetPlayerState(PlayerState.Stopped);
this._playbackWrapper.Close();
break;
case MCTransportState.Playing:
PerfTrace.TraceUICollectionEvent(UICollectionEvent.PlayRequestComplete, "");
break;
}
}
this._lastKnownTransportState = mcTransportState;
}
private void DeferredTransportPositionChanged(object obj)
{
if (this.IsDisposed)
return;
this._lastKnownPosition = (long)obj;
this.CurrentTrackPosition = _lastKnownPosition / 1E+07f;
if (this._lastKnownPlaybackTrack == null)
return;
if (this._lastKnownPosition > 0L)
this._consecutiveErrors = 0;
this._lastKnownPlaybackTrack.OnPositionChanged(this._lastKnownPosition);
}
private void DeferredUriSet(object obj)
{
if (this.IsDisposed)
return;
object[] objArray = (object[])obj;
string str = (string)objArray[0];
int num1 = (int)objArray[1];
this._lastKnownPreparedTrack = null;
int num2;
for (num2 = 0; num2 < this._tracksSubmittedToPlayer.Count; ++num2)
{
PlaybackTrack playbackTrack = this._tracksSubmittedToPlayer[num2];
if (playbackTrack.PlaybackID == num1)
{
this._lastKnownPreparedTrack = playbackTrack;
++num2;
break;
}
}
this._tracksSubmittedToPlayer.RemoveRange(0, num2);
if (this._lastKnownPreparedTrack == null || this._tracksSubmittedToPlayer.Count != 0)
return;
if (this._playlistCurrent != null)
this._playlistCurrent.SyncCurrentTrackTo(this._lastKnownPreparedTrack);
this.UpdateNextTrack();
}
private void DeferredAlertHandler(object obj)
{
if (this.IsDisposed || !(obj is Announcement announcement))
return;
PlaybackTrack playbackTrack = null;
if (this.CurrentTrack != null && this.CurrentTrack.PlaybackID == announcement.PlaybackID)
{
playbackTrack = this.CurrentTrack;
}
else
{
for (int index = this._tracksSubmittedToPlayer.Count - 1; index >= 0; --index)
{
if (this._tracksSubmittedToPlayer[index].PlaybackID == announcement.PlaybackID)
{
playbackTrack = this._tracksSubmittedToPlayer[index];
break;
}
}
}
if (playbackTrack != null)
{
++this._consecutiveErrors;
this._errors[playbackTrack] = announcement.HResult;
if (this._playlistCurrent != null)
this._playlistCurrent.SyncCurrentTrackTo(playbackTrack);
this.FirePropertyChanged("ErrorCount");
}
bool flag = announcement.HResult == HRESULT._NS_E_CD_BUSY;
if (this._consecutiveErrors < 5 && !flag && this.Playing && (this._playlistCurrent != null && this._playlistCurrent.CanAdvance))
{
this._playlistCurrent.Advance();
this._playbackWrapper.Close();
}
else
{
this.SetPlayerState(PlayerState.Stopped);
this._playbackWrapper.Close();
if (this._lastKnownPlaybackTrack != null)
{
this._lastKnownPlaybackTrack.OnEndPlayback(false);
this._lastKnownPlaybackTrack = null;
}
if (flag || !this.ShowErrors)
return;
ErrorDialogInfo.Show(announcement.HResult, Shell.LoadString(StringId.IDS_PLAYBACK_ERROR));
}
}
private void DeferredPresentationInfoChangedHandler(object obj)
{
if (this.IsDisposed || this._videoStream == null)
return;
PresentationInfo presentationInfo = (PresentationInfo)obj;
this._videoStream.ContentWidth = presentationInfo.ContentWidth;
this._videoStream.ContentHeight = presentationInfo.ContentHeight;
this._videoStream.ContentAspectWidth = presentationInfo.ContentAspectWidth;
this._videoStream.ContentAspectHeight = presentationInfo.ContentAspectHeight;
this._videoStream.ContentOverscanPercent = presentationInfo.NeedOverscan ? 0.1f : 0.0f;
this.FirePropertyChanged("VideoStream");
}
private void DeferredVolumeInfoChangedHandler(object obj)
{
this._volume.Value = _playbackWrapper.Volume;
this.FirePropertyChanged("Volume");
this._muted.Value = this._playbackWrapper.Mute;
this.FirePropertyChanged("Mute");
}
private void DeferredCanChangeVideoRateHandler(object obj)
{
if (this._currentTrack == null || !this._currentTrack.IsVideo)
return;
this._forward.Available = this._playbackWrapper.CanChangeVideoRate;
}
private void SetUriOnPlayer()
{
PlaybackTrack track = null;
if (this._playlistCurrent != null)
track = this._playlistCurrent.CurrentTrack;
PlaybackTrack nextTrack = null;
if (this._playlistCurrent != null && this._playlistCurrent.Count > 1)
nextTrack = this._playlistCurrent.NextTrack;
if (track != null)
{
this.SetUrisOnPlayerAsync(track, nextTrack);
}
else
{
this.SetPlayerState(PlayerState.Stopped);
this._playbackWrapper.Close();
this.UpdatePropertiesAndCommands();
}
}
private void SetNextUriOnPlayer()
{
PlaybackTrack nextTrack = null;
if (this._playlistCurrent != null)
nextTrack = this._playlistCurrent.NextTrack;
if (nextTrack != null && this._playlistCurrent.Count > 1)
this.SetUrisOnPlayerAsync(null, nextTrack);
else
this._playbackWrapper.CancelNext();
}
private void SetUrisOnPlayerAsync(PlaybackTrack track, PlaybackTrack nextTrack)
{
int myID = ++this._lastKnownSetUriCallID;
ThreadPool.QueueUserWorkItem(args =>
{
if (track != null)
{
string trackUri;
HRESULT uri = track.GetURI(out trackUri);
if (string.IsNullOrEmpty(trackUri))
trackUri = ".:* INVALID URI *:.";
if (uri.IsSuccess)
Application.DeferredInvoke(delegate
{
if (this.IsDisposed || myID != this._lastKnownSetUriCallID)
return;
this._playbackWrapper.SetUri(trackUri, 0L, track.PlaybackID);
this.ReportStreamingAction(PlayerState.Stopped);
this._tracksSubmittedToPlayer.Remove(track);
this._tracksSubmittedToPlayer.Add(track);
if (nextTrack != null)
return;
this._playbackWrapper.CancelNext();
this.UpdatePropertiesAndCommands();
}, null);
else
this.OnAlertSent(new Announcement()
{
HResult = uri.Int,
PlaybackID = track.PlaybackID
});
}
if (nextTrack == null)
return;
string nextTrackUri;
HRESULT uri1 = nextTrack.GetURI(out nextTrackUri);
if (string.IsNullOrEmpty(nextTrackUri))
nextTrackUri = ".:* INVALID URI *:.";
if (!uri1.IsSuccess)
return;
Application.DeferredInvoke(delegate
{
if (this.IsDisposed || myID != this._lastKnownSetUriCallID)
return;
this._playbackWrapper.SetNextUri(nextTrackUri, 0L, nextTrack.PlaybackID);
this._tracksSubmittedToPlayer.Remove(nextTrack);
this._tracksSubmittedToPlayer.Add(nextTrack);
this.UpdatePropertiesAndCommands();
}, null);
}, null);
}
private void UpdateNextTrack()
{
this.SetNextUriOnPlayer();
this.UpdatePropertiesAndCommands();
}
private bool AreContextsCompatible(PlaybackContext contextCurrent, PlaybackContext contextNext) => contextCurrent == PlaybackContext.None || contextNext == contextCurrent;
public bool IsCurrentPlaylistContextCompatible(PlaybackContext context)
{
bool flag = true;
if (this._playlistCurrent != null)
flag = this.AreContextsCompatible(context, this._playlistCurrent.PlaybackContext);
return flag;
}
private void UpdatePropertiesAndCommands()
{
bool isPlaying = this._playerState == PlayerState.Playing;
ArrayListDataSet arrayListDataSet;
bool isPlaylist;
bool flag3;
PlaybackTrack playbackTrack;
int num;
bool supportsShuffle;
if (this._playlistCurrent != null)
{
arrayListDataSet = this._playlistCurrent.TrackList;
isPlaylist = true;
flag3 = this.IsCurrentPlaylistContextCompatible(this._pagePlaybackContext);
playbackTrack = this._playlistCurrent.CurrentTrack;
num = this._playlistCurrent.ListIndexOfCurrentTrack;
supportsShuffle = this._playlistCurrent.QuickMixSession == null;
}
else
{
isPlaylist = false;
arrayListDataSet = null;
flag3 = true;
playbackTrack = null;
num = -1;
this.PlayingVideo = false;
supportsShuffle = true;
}
if (arrayListDataSet != this._currentPlaylist)
{
this._currentPlaylist = arrayListDataSet;
this.FirePropertyChanged("CurrentPlaylist");
}
if (isPlaylist != this._hasPlaylist)
{
this._hasPlaylist = isPlaylist;
this.FirePropertyChanged("HasPlaylist");
}
if (supportsShuffle != this._playlistSupportsShuffle)
{
this._playlistSupportsShuffle = supportsShuffle;
this.FirePropertyChanged("PlaylistSupportsShuffle");
}
if (isPlaying != this._isPlaying)
{
this._isPlaying = isPlaying;
this.FirePropertyChanged("Playing");
if (this._isPlaying)
{
this.HasPlayed = true;
this._currentPlayStartTime = DateTime.Now;
}
else if (this._currentPlayStartTime != DateTime.MinValue)
{
Telemetry.Instance.ReportPlaybackTime((int)DateTime.Now.Subtract(this._currentPlayStartTime).TotalSeconds);
this._currentPlayStartTime = DateTime.MinValue;
}
}
if (num != this._currentTrackIndex)
{
if (this._currentPlayStartTime != DateTime.MinValue)
{
Telemetry.Instance.ReportPlaybackTime((int)DateTime.Now.Subtract(this._currentPlayStartTime).TotalSeconds);
this._currentPlayStartTime = DateTime.Now;
}
this._currentTrackIndex = num;
this.FirePropertyChanged("CurrentTrackIndex");
}
if (!ReferenceEquals(playbackTrack, _currentTrack))
{
if (this._currentTrack != null)
this._currentTrack.RatingChanged.Invoked -= this._currentTrackRatingChangedEventHandler;
this._currentTrack = playbackTrack;
if (this._currentTrack != null)
this._currentTrack.RatingChanged.Invoked += this._currentTrackRatingChangedEventHandler;
this.FirePropertyChanged("CurrentTrack");
this.OnCurrentTrackRatingChanged(this, null);
this.CurrentTrackDownloadProgress = 0.0f;
if (this._currentTrack != null)
this.ShowNotification();
else
this.HideNotification();
this.ZoomScaleFactor = 0;
}
if (flag3 != this._isContextCompatible)
{
this._isContextCompatible = flag3;
this.FirePropertyChanged("IsPlaybackContextCompatible");
}
this.UpdateAvailabilityOfCommands();
if (this.Playing && this.CurrentTrack != null && (this.CurrentTrack.IsVideo && this.CurrentTrack.IsStreaming))
{
this._isStreamingTimeoutTimer.Enabled = false;
this.IsStreamingVideo = true;
this.SupressDownloads = true;
}
else
{
if (this.SupressDownloads)
this._isStreamingTimeoutTimer.Enabled = true;
this.IsStreamingVideo = false;
}
}
private void UpdateAvailabilityOfCommands()
{
bool playing = this.Playing;
bool flag = this._playlistCurrent != null;
this._play.Available = !playing && flag && !this.Buffering;
this._pause.Available = playing && !this.Buffering;
this._stop.Available = flag;
if (this._playerState == PlayerState.Stopped || this.Buffering)
{
this._forward.Available = false;
this._back.Available = false;
}
else if (this._playerState == PlayerState.Playing)
{
if (this._currentTrack == null)
{
this._forward.Available = false;
this._back.Available = false;
}
else
{
this._forward.Available = !this._currentTrack.IsVideo || this._playbackWrapper.CanChangeVideoRate;
this._back.Available = true;
}
}
else
{
this._forward.Available = this._currentTrack == null ? this._playlistCurrent != null : this._playlistCurrent != null && !this._currentTrack.IsVideo;
this._back.Available = this._playlistCurrent != null && this._playlistCurrent.CanRetreat;
}
this.UpdateTaskbarPlayer();
}
public static string FormatDuration(float seconds, bool prefixWithNegative) => Shell.TimeSpanToString(new TimeSpan(0, 0, (int)seconds), prefixWithNegative);
public static string FormatDuration(float seconds) => FormatDuration(seconds, false);
[Conditional("DEBUG_TRANSPORT")]
private static void _DEBUG_Trace(string message, params object[] args)
{
}
[Conditional("DEBUG_TRANSPORT_PROPERTIES")]
private static void _DEBUG_TracePropChange(string name, object arg)
{
}
private struct SpectrumOutputConfig
{
public uint SourceId;
public uint NumBands;
public bool Frequency;
public bool Waveform;
public bool Stereo;
public bool IsConnected;
}
private enum PlayerState
{
Stopped,
Playing,
Paused,
}
}
}