/// <summary> /// Initializes a new instance of the <see cref="MediaEngine" /> class. /// </summary> /// <param name="parent">The associated parent object.</param> /// <param name="connector">The parent implementing connector methods.</param> /// <exception cref="InvalidOperationException">Thrown when the static Initialize method has not been called.</exception> public MediaEngine(object parent, IMediaConnector connector) { // var props = typeof(MediaEngine).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); // foreach (var p in props) // { // Console.WriteLine(p); // } // Assiciate the parent as the media connector that implements the callbacks Parent = parent; Connector = connector; Commands = new MediaCommandManager(this); // Don't start up timers or any other stuff if we are in design-time if (Platform.IsInDesignTime) { return; } // Check initialization has taken place lock (InitLock) { if (IsIntialized == false) { throw new InvalidOperationException( $"{nameof(MediaEngine)} not initialized. Call the static method {nameof(Initialize)}"); } } }
#pragma warning restore SA1401 // Fields must be private #endregion #region Constructors /// <summary> /// Initializes a new instance of the <see cref="MediaElementCore"/> class. /// </summary> /// <param name="parent">The parent.</param> /// <param name="isInDesignTime">if set to <c>true</c> [is in design time].</param> public MediaElementCore(object parent, bool isInDesignTime) { Parent = parent; Logger = new GenericMediaLogger <MediaElementCore>(this); Commands = new MediaCommandManager(this); if (!isInDesignTime) { // The UI Property update timer is responsible for timely updates to properties outside of the worker threads // We use the loaded priority because it is the priority right below the Render one. UIPropertyUpdateTimer = Platform.CreateTimer(CoreDispatcherPriority.Loaded); UIPropertyUpdateTimer.Interval = Constants.UIPropertyUpdateInterval; // The tick callback performs the updates UIPropertyUpdateTimer.Tick += (s, e) => { UpdatePosition(IsOpen ? Clock?.Position ?? TimeSpan.Zero : TimeSpan.Zero); if (HasMediaEnded == false && CanReadMorePackets && (IsOpening || IsOpen)) { var bufferedLength = Container?.Components?.PacketBufferLength ?? 0d; BufferingProgress = Math.Min(1d, bufferedLength / BufferCacheLength); var oldIsBugffering = IsBuffering; var newIsBuffering = bufferedLength < BufferCacheLength; if (oldIsBugffering == false && newIsBuffering) { RaiseBufferingStartedEvent(); } else if (oldIsBugffering && newIsBuffering == false) { RaiseBufferingEndedEvent(); } IsBuffering = HasMediaEnded == false && newIsBuffering; } else { BufferingProgress = 0; IsBuffering = false; } var downloadProgress = Math.Min(1d, Math.Round((Container?.Components.PacketBufferLength ?? 0d) / DownloadCacheLength, 3)); if (double.IsNaN(downloadProgress)) { downloadProgress = 0; } DownloadProgress = downloadProgress; }; // Go ahead and fire up the continuous updates UIPropertyUpdateTimer.IsEnabled = true; UIPropertyUpdateTimer.Start(); } }
/// <summary> /// Initializes a new instance of the <see cref="MediaElement" /> class. /// </summary> public MediaElement() : base() { Content = ViewBox; Stretch = ViewBox.Stretch; StretchDirection = ViewBox.StretchDirection; Logger = new GenericMediaLogger <MediaElement>(this); Commands = new MediaCommandManager(this); if (Utils.IsInDesignTime) { // Shows an FFmpeg image if we are in design-time var bitmap = Properties.Resources.FFmpegMediaElementBackground; var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var targetBitmap = new WriteableBitmap(bitmapSource); ViewBox.Source = targetBitmap; } else { // The UI Property update timer is responsible for timely updates to properties outside of the worker threads UIPropertyUpdateTimer = new DispatcherTimer(DispatcherPriority.DataBind) { Interval = Constants.UIPropertyUpdateInterval, IsEnabled = true }; // The tick callback performs the updates UIPropertyUpdateTimer.Tick += (s, e) => { UpdatePosition(IsOpen ? Clock?.Position ?? TimeSpan.Zero : TimeSpan.Zero); var downloadProgress = Math.Min(1d, Math.Round((Container?.Components.PacketBufferLength ?? 0d) / DownloadCacheLength, 3)); if (double.IsNaN(downloadProgress)) { downloadProgress = 0; } DownloadProgress = downloadProgress; }; // Go ahead and fire up the continuous updates UIPropertyUpdateTimer.Start(); } m_MetadataBase = new ObservableCollection <KeyValuePair <string, string> >(); m_Metadata = CollectionViewSource.GetDefaultView(m_MetadataBase) as ICollectionView; }
/// <summary> /// Initializes a new instance of the <see cref="MediaElement"/> class. /// </summary> public MediaElement() : base() { Content = ViewBox; Stretch = ViewBox.Stretch; StretchDirection = ViewBox.StretchDirection; Commands = new MediaCommandManager(this); if (Utils.IsInDesignTime) { // Shows an FFmpeg image if we are in design-time var bitmap = Properties.Resources.FFmpegMediaElementBackground; var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var targetBitmap = new WriteableBitmap(bitmapSource); ViewBox.Source = targetBitmap; } }
/// <summary> /// Initializes a new instance of the <see cref="MediaEngine" /> class. /// </summary> /// <param name="parent">The associated parent object.</param> /// <param name="connector">The parent implementing connector methods.</param> /// <exception cref="InvalidOperationException">Thrown when the static Initialize method has not been called.</exception> public MediaEngine(object parent, IMediaConnector connector) { // Assiciate the parent as the media connector that implements the callbacks Parent = parent; Connector = connector; Commands = new MediaCommandManager(this); // Don't start up timers or any other stuff if we are in design-time if (Platform.IsInDesignTime) { return; } // Check initialization has taken place lock (InitLock) { if (IsIntialized == false) { throw new InvalidOperationException( $"{nameof(MediaEngine)} not initialized. Call the static method {nameof(Initialize)}"); } } }
/// <summary> /// Initializes a new instance of the <see cref="PauseCommand" /> class. /// </summary> /// <param name="manager">The manager.</param> public PauseCommand(MediaCommandManager manager) : base(manager, MediaCommandType.Pause) { }
/// <summary> /// Initializes a new instance of the <see cref="PlayCommand" /> class. /// </summary> /// <param name="manager">The media element.</param> public PlayCommand(MediaCommandManager manager) : base(manager, MediaCommandType.Play) { }
/// <summary> /// Initializes a new instance of the <see cref="MediaElement" /> class. /// </summary> public MediaElement() : base() { ContentGrid = new Grid { Name = nameof(ContentGrid) }; Content = ContentGrid; ContentGrid.HorizontalAlignment = HorizontalAlignment.Stretch; ContentGrid.VerticalAlignment = VerticalAlignment.Stretch; ContentGrid.Children.Add(ViewBox); Stretch = ViewBox.Stretch; StretchDirection = ViewBox.StretchDirection; Logger = new GenericMediaLogger <MediaElement>(this); Commands = new MediaCommandManager(this); if (Utils.IsInDesignTime) { // Shows an FFmpeg image if we are in design-time var bitmap = Properties.Resources.FFmpegMediaElementBackground; var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var controlBitmap = new WriteableBitmap(bitmapSource); ViewBox.Source = controlBitmap; } else { // The UI Property update timer is responsible for timely updates to properties outside of the worker threads // We use the loaded priority because it is the priority right below the Render one. UIPropertyUpdateTimer = new DispatcherTimer(DispatcherPriority.Loaded) { Interval = Constants.UIPropertyUpdateInterval, IsEnabled = true }; // The tick callback performs the updates UIPropertyUpdateTimer.Tick += (s, e) => { UpdatePosition(IsOpen ? Clock?.Position ?? TimeSpan.Zero : TimeSpan.Zero); if (HasMediaEnded == false && CanReadMorePackets && (IsOpening || IsOpen)) { var bufferedLength = Container?.Components?.PacketBufferLength ?? 0d; BufferingProgress = Math.Min(1d, bufferedLength / BufferCacheLength); var oldIsBugffering = IsBuffering; var newIsBuffering = bufferedLength < BufferCacheLength; if (oldIsBugffering == false && newIsBuffering == true) { RaiseBufferingStartedEvent(); } else if (oldIsBugffering == true && newIsBuffering == false) { RaiseBufferingEndedEvent(); } IsBuffering = HasMediaEnded == false && newIsBuffering; } else { BufferingProgress = 0; IsBuffering = false; } var downloadProgress = Math.Min(1d, Math.Round((Container?.Components.PacketBufferLength ?? 0d) / DownloadCacheLength, 3)); if (double.IsNaN(downloadProgress)) { downloadProgress = 0; } DownloadProgress = downloadProgress; }; // Go ahead and fire up the continuous updates UIPropertyUpdateTimer.Start(); } m_MetadataBase = new ObservableCollection <KeyValuePair <string, string> >(); m_Metadata = CollectionViewSource.GetDefaultView(m_MetadataBase) as ICollectionView; }
/// <summary> /// Initializes a new instance of the <see cref="PauseCommand" /> class. /// </summary> /// <param name="manager">The manager.</param> public PauseCommand(MediaCommandManager manager) : base(manager, MediaCommandType.Pause) { // placeholder }