/// <summary> /// Gets called whenever the player has been initialized. /// </summary> public override void OnPlayerInitialized( ) { MediaComponent comp = MainWindow.Player.GetComponent <MediaComponent>( ); comp.OnMediaLoaded += (Sender, Args) => { OpenLocalSubs.IsEnabled = true; OpenOSSubs.IsEnabled = true; }; comp.OnMediaFailedToLoad += (Sender, Args) => { OpenLocalSubs.IsEnabled = false; OpenOSSubs.IsEnabled = false; EnableSubs.IsEnabled = false; EnableSubs.IsChecked = false; }; InputComponent inputComponent = Player.GetComponent <InputComponent>( ); inputComponent.OnShowControls += (Sender, Args) => this.Visibility = Visibility.Visible; inputComponent.OnHideControls += (Sender, Args) => this.Visibility = Visibility.Collapsed; SubtitlesComponent subs = MainWindow.Player.GetComponent <SubtitlesComponent>( ); subs.OnSubtitlesFailedToLoad += SubsOnOnSubtitlesFailedToLoad; subs.OnSubtitlesLoaded += SubsOnOnSubtitlesLoaded; }
public void AddAll(OptionArgs args) { foreach (Song song in songs) { MediaComponent.addSong(song); } }
public void Play(object sender, EventArgs e) { MediaComponent.start(); MediaComponent.getInfo(out artist, out album, out song); albumArt = MediaComponent.getArt(); }
public void Previous(object sender, EventArgs e) { MediaComponent.movePreviousSong(); MediaComponent.getInfo(out artist, out album, out song); albumArt = MediaComponent.getArt(); }
public int IndexOf(MediaComponent component) { if (component == null) { throw new System.ArgumentNullException(); } return(System.Array.IndexOf(Components, component)); }
public MediaFormat(MediaType mediaType, Common.Binary.ByteOrder byteOrder, DataLayout dataLayout, int components, int[] componentSizes, byte[] componentIds) { //Assign the media type MediaType = mediaType; if (byteOrder == Common.Binary.ByteOrder.Unknown) { throw new System.ArgumentException("byteOrder", "Cannot be Unknown"); } ByteOrder = byteOrder; //Validate the datalayout if (dataLayout == Media.Codec.DataLayout.Unknown) { throw new System.ArgumentException("dataLayout", "Cannot be Unknown"); } DataLayout = dataLayout; //Validate the amount of components if (components < 1) { throw new System.ArgumentException("components", "Must be greater than 0."); } //Create the array Components = new MediaComponent[components]; long length; //Validate the sizes array if (Common.Extensions.Array.ArrayExtensions.IsNullOrEmpty(componentSizes, out length) || length < components) { throw new System.ArgumentException("componentSizes", "Must have the amount of elements indicated by 'components'"); } //Validate the length of the id array if (Common.Extensions.Array.ArrayExtensions.IsNullOrEmpty(componentIds, out length) || length < components) { throw new System.ArgumentException("componentIds", "Must have the amount of elements indicated by 'components'"); } //Creates each component for (int i = 0; i < components; ++i) { length = componentSizes[i]; int ilen = (int)length; Components[i] = new MediaComponent(componentIds[i], ilen); Size += ilen; } }
public void Stop(object sender, EventArgs e) { playPause.revert(); artist = "<Artist>"; album = "<Album>"; song = "<Song>"; MediaComponent.stop(); albumArt = null; }
public override void update(InputHandler input) { playPause.update(input); stop.update(input); next.update(input); previous.update(input); shuffle.update(input); repeat.update(input); if (MediaComponent.playing) { MediaComponent.getInfo(out artist, out album, out song); } }
public MediaActor(ulong id, string path = "") : base(id) { InitializeComponent(); Name = "Media-" + id; _cmp = new MediaComponent(this); AddComponent(_cmp); if (string.IsNullOrEmpty(path)) { path = "http://flv3.bn.netease.com/videolib3/1801/04/MsbTq9983/SD/MsbTq9983-mobile.mp4"; } Media = new MediaElement() { Source = new Uri(string.Format("{0}", path)) }; }
/// <summary> /// Gets called whenever the player has been initialized. /// </summary> public override void OnPlayerInitialized( ) { Player.GetComponent <TimeComponent>( ).OnPositionChanged += OnOnPositionChanged; Player.GetComponent <StateComponent>( ).OnStateChanged += OnOnStateChanged; MediaComponent media = Player.GetComponent <MediaComponent>( ); media.OnMediaLoaded += MediaOnOnMediaLoaded; media.OnMediaUnloaded += MediaOnOnMediaUnloaded; InputComponent inputComponent = Player.GetComponent <InputComponent>( ); inputComponent.OnShowControls += (Sender, Args) => this.Visibility = Visibility.Visible; inputComponent.OnHideControls += (Sender, Args) => this.Visibility = Visibility.Collapsed; }
private void WaitForPackets(MediaComponent mediaComponent, int cycleCount = -1) { var cycleIndex = 0; while (mediaComponent.PacketBufferCount <= 0 && CanReadMorePackets && ShouldReadMorePackets) { PacketReadingCycle.Wait(Constants.Interval.LowPriority); if (cycleCount <= 0) { continue; } cycleIndex++; if (cycleCount >= cycleIndex) { break; } } }
private void SetMediaMessage(Message message) { if (message.IsStickerMessage) { mediaComponent = Instantiate(AssetController.GetGameObject("SimpleImage"), mediaParent).AddComponent <Sticker>(); ((Sticker)mediaComponent).ToggleClick(false); } else if (message.IsAudioMessage) { mediaComponent = Instantiate(AssetController.GetGameObject("SimpleImage"), mediaParent).AddComponent <Sound>(); } else if (message.IsPhotoMessage) { mediaComponent = Instantiate(AssetController.GetGameObject("SimpleImage"), mediaParent).AddComponent <Photo>(); } else if (message.IsVideoMessage) { mediaComponent = Instantiate(AssetController.GetGameObject("SimpleImage"), mediaParent).AddComponent <Video>(); } mediaComponent.InitiateComponent(message.GetMessageContent(), this); }
void initializeMediaPlayer() { mediaPlayer = new MediaComponent(this); mediaPlayer.setMenuBackgrounds("Menus/Standard Menu", new Vector2(), Color.White, new FadeComponent(15, 1), new FadeComponent(15, -1)); mediaPlayer.setMenuTitles("Fonts/MaturaTitle", new Vector2(60, 40), Color.Red, new FadeComponent(15, 1), new FadeComponent(15, -1)); mediaPlayer.setMenuDisplayLists("Fonts/MaturaOptions", "Menus/Highlighter", new Rectangle(30, 100, 212, 320), Color.Red, new Vector2(30, 100), 30, new MoveCollection(new Vector2(-200, 0), 15, true), new MoveCollection(null, new Vector2(200, 0), 15, true), new MoveCollection(new Vector2(-200, 0), 15, false), new MoveCollection(new Vector2(200, 0), 15, false)); mediaPlayer.setMenuBackOption("Fonts/MaturaOptions", new Vector2(136, 440), Color.Red, "Menus/Highlighter", new Vector2(136, 440), TextAlignment.center, new MoveCollection(new Vector2(-200, 0), 15, true), new MoveCollection(null, new Vector2(200, 0), 15, true), new MoveCollection(new Vector2(-200, 0), 15, false), new MoveCollection(new Vector2(200, 0), 15, false)); mediaPlayer.setMenuQueue(false); mediaPlayer.addMenus(menus); Components.Add(mediaPlayer); }
public void AddSong(OptionArgs args) { MediaComponent.addSong(songs[args.index - 1]); }
/// <summary> /// Continually decodes the available packet buffer to have as /// many frames as possible in each frame queue and /// up to the MaxFrames on each component /// </summary> /// <returns>The task.</returns> internal async Task RunFrameDecodingWorker() { var decodedFrameCount = 0; var wallClock = TimeSpan.Zero; var rangePercent = 0d; var isInRange = false; // Holds the main media type var main = Container.Components.Main.MediaType; // Holds the auxiliary media types var auxs = Container.Components.MediaTypes.Where(x => x != main).ToArray(); // Holds all components var all = Container.Components.MediaTypes.ToArray(); var isBuffering = false; var resumeClock = false; var hasPendingSeeks = false; MediaComponent comp = null; MediaBlockBuffer blocks = null; while (IsTaskCancellationPending == false) { #region 1. Setup the Decoding Cycle hasPendingSeeks = Commands.PendingCountOf(MediaCommandType.Seek) > 0; if (IsSeeking == false && hasPendingSeeks) { IsSeeking = true; RaiseSeekingStartedEvent(); } // Execute the following command at the beginning of the cycle await Commands.ProcessNext(); hasPendingSeeks = Commands.PendingCountOf(MediaCommandType.Seek) > 0; if (IsSeeking == true && hasPendingSeeks == false) { SnapVideoPosition(Clock.Position); IsSeeking = false; // Call the seek method on all renderers foreach (var kvp in Renderers) { kvp.Value.Seek(); } RaiseSeekingEndedEvent(); } // Wait for a seek operation to complete (if any) // and initiate a frame decoding cycle. SeekingDone.WaitOne(); // Check if one of the commands has requested an exit if (IsTaskCancellationPending) { break; } // Initiate the frame docding cycle FrameDecodingCycle.Reset(); // Set initial state wallClock = Clock.Position; decodedFrameCount = 0; #endregion #region 2. Main Component Decoding // Capture component and blocks for easier readability comp = Container.Components[main]; blocks = Blocks[main]; // Handle the main component decoding; Start by checking we have some packets if (comp.PacketBufferCount > 0) { // Detect if we are in range for the main component isInRange = blocks.IsInRange(wallClock); if (isInRange == false) { // Clear the media blocks if we are outside of the required range // we don't need them and we now need as many playback blocks as we can have available if (blocks.IsFull) { blocks.Clear(); } // detect a buffering scenario if (blocks.Count <= 0) { HasDecoderSeeked = true; isBuffering = true; resumeClock = Clock.IsRunning; Clock.Pause(); Logger.Log(MediaLogMessageType.Debug, $"SYNC BUFFER: Buffering Started."); } // Read some frames and try to get a valid range while (comp.PacketBufferCount > 0 && blocks.IsFull == false) { decodedFrameCount = AddBlocks(main); isInRange = blocks.IsInRange(wallClock); if (isInRange) { break; } // Try to get more packets by waiting for read cycles. if (CanReadMorePackets && comp.PacketBufferCount <= 0 && isInRange == false) { PacketReadingCycle.WaitOne(); } } // Unfortunately at this point we will need to adjust the clock after creating the frames. // to ensure tha mian component is within the clock range if the decoded // frames are not with range. This is normal while buffering though. if (isInRange == false) { wallClock = wallClock <= blocks.RangeStartTime ? blocks.RangeStartTime : blocks.RangeEndTime; if (isBuffering == false) { Logger.Log(MediaLogMessageType.Warning, $"SYNC CLOCK: {Clock.Position.Format()} set to {wallClock.Format()}"); } // Update the clock to what the main component range mandates Clock.Position = wallClock; } } else { // Check if we need more blocks for the current components rangePercent = blocks.GetRangePercent(wallClock); // Read as many blocks as we possibly can while (comp.PacketBufferCount > 0 && ((rangePercent > 0.75d && blocks.IsFull) || blocks.IsFull == false)) { decodedFrameCount = AddBlocks(main); rangePercent = blocks.GetRangePercent(wallClock); } } } #endregion #region 3. Auxiliary Component Decoding foreach (var t in auxs) { if (IsSeeking) { continue; } // Capture the current block buffer and component // for easier readability comp = Container.Components[t]; blocks = Blocks[t]; // wait for component to get there if we only have furutre blocks // in auxiliary component. if (blocks.RangeStartTime > wallClock) { continue; } // Wait for packets if we are buffering or we don't have enough packets if (CanReadMorePackets && (isBuffering || comp.PacketBufferCount <= 0)) { PacketReadingCycle.WaitOne(); } // catch up with the wall clock while (comp.PacketBufferCount > 0 && blocks.RangeEndTime <= wallClock) { decodedFrameCount = AddBlocks(t); // don't care if we are buffering // always try to catch up by reading more packets. if (comp.PacketBufferCount <= 0 && CanReadMorePackets) { PacketReadingCycle.WaitOne(); } } rangePercent = blocks.GetRangePercent(wallClock); isInRange = blocks.IsInRange(wallClock); // Wait for packets if we are buffering if (CanReadMorePackets && isBuffering) { PacketReadingCycle.WaitOne(); } while (comp.PacketBufferCount > 0 && ( (blocks.IsFull == true && isInRange && rangePercent > 0.75d && rangePercent < 1d) || (blocks.IsFull == false) )) { decodedFrameCount = AddBlocks(t); rangePercent = blocks.GetRangePercent(wallClock); isInRange = blocks.IsInRange(wallClock); if (CanReadMorePackets && isBuffering) { PacketReadingCycle.WaitOne(); } } } #endregion #region 4. Detect End of Media // Detect end of block rendering if (isBuffering == false && IsSeeking == false && CanReadMoreFramesOf(main) == false && Blocks[main].IndexOf(wallClock) == Blocks[main].Count - 1) { if (HasMediaEnded == false) { // Rendered all and nothing else to read Clock.Pause(); Clock.Position = NaturalDuration.HasTimeSpan ? NaturalDuration.TimeSpan : Blocks[main].RangeEndTime; wallClock = Clock.Position; HasMediaEnded = true; MediaState = MediaState.Pause; RaiseMediaEndedEvent(); } } else { HasMediaEnded = false; } #endregion #region 6. Finish the Cycle // complete buffering notifications if (isBuffering) { isBuffering = false; if (resumeClock) { Clock.Play(); } Logger.Log(MediaLogMessageType.Debug, $"SYNC BUFFER: Buffering Finished. Clock set to {wallClock.Format()}"); } // Complete the frame decoding cycle FrameDecodingCycle.Set(); // After a seek operation, always reset the has seeked flag. HasDecoderSeeked = false; // Simply exit the thread when cancellation has been requested if (IsTaskCancellationPending) { break; } // Give it a break if there was nothing to decode. // We probably need to wait for some more input if (decodedFrameCount <= 0 && Commands.PendingCount <= 0) { await Task.Delay(1); } #endregion } // Always exit notifying the cycle is done. FrameDecodingCycle.Set(); }
/// <summary> /// Continually decodes the available packet buffer to have as /// many frames as possible in each frame queue and /// up to the MaxFrames on each component /// </summary> internal void RunFrameDecodingWorker() { #region Worker State Setup // The delay provider prevents 100% core usage var delay = new DelayProvider(); // State variables var decodedFrameCount = 0; var wallClock = TimeSpan.Zero; var rangePercent = 0d; var isInRange = false; // Holds the main media type var main = Container.Components.Main.MediaType; // Holds the auxiliary media types var auxs = Container.Components.MediaTypes.Except(main); // State properties var isBuffering = false; var resumeClock = false; MediaComponent comp = null; MediaBlockBuffer blocks = null; #endregion #region Worker Loop try { while (Commands.IsStopWorkersPending == false) { #region 1. Setup the Decoding Cycle // Determine what to do on a priority command if (Commands.IsExecutingDirectCommand) { if (Commands.IsClosing) { break; } if (Commands.IsChanging) { Commands.WaitForDirectCommand(); } } // Update state properties -- this must be after processing commanmds as // a direct command might have changed the components main = Container.Components.Main.MediaType; auxs = Container.Components.MediaTypes.Except(main); // Execute the following command at the beginning of the cycle Commands.ExecuteNextQueuedCommand(); // Signal a Seek starting operation FrameDecodingCycle.Begin(); // Set initial state wallClock = WallClock; decodedFrameCount = 0; #endregion if (State.HasMediaEnded == false) { #region 2. Main Component Decoding // Capture component and blocks for easier readability // comp is current component, blocks is the block collection for the component comp = Container.Components[main]; blocks = Blocks[main]; // Detect if we are in range for the main component isInRange = blocks.IsInRange(wallClock); if (isInRange == false) { // Signal the start of a sync-buffering scenario isBuffering = true; State.SignalBufferingStarted(); resumeClock = Clock.IsRunning; Clock.Pause(); Log(MediaLogMessageType.Debug, $"SYNC-BUFFER: Started."); // Read some frames and try to get a valid range do { // Try to get more packets by waiting for read cycles. WaitForPackets(comp, 1); // Decode some frames and check if we are in reange now if (AddNextBlock(main) == false) { break; } decodedFrameCount += 1; isInRange = blocks.IsInRange(wallClock); // Break the cycle if we are in range if (isInRange || CanReadMorePackets == false || ShouldReadMorePackets == false) { break; } }while (blocks.IsFull == false); // Unfortunately at this point we will need to adjust the clock after creating the frames. // to ensure tha mian component is within the clock range if the decoded // frames are not with range. This is normal while buffering though. if (isInRange == false) { // Update the wall clock to the most appropriate available block. if (blocks.Count > 0) { wallClock = blocks[wallClock].StartTime; } else { resumeClock = false; // Hard stop the clock. } // Update the clock to what the main component range mandates Clock.Update(wallClock); // Force renderer invalidation InvalidateRenderer(main); // Try to recover the regular loop isInRange = true; } } if (isInRange) { // Check if we need more blocks for the current components rangePercent = blocks.GetRangePercent(wallClock); // Read as much as we can for this cycle but always within range. while (blocks.IsFull == false || (blocks.IsFull && rangePercent > 0.75d && rangePercent < 1d)) { if (AddNextBlock(main) == false) { break; } decodedFrameCount += 1; rangePercent = blocks.GetRangePercent(wallClock); continue; } } #endregion #region 3. Auxiliary Component Decoding foreach (var t in auxs) { if (State.IsSeeking) { continue; } // Capture the current block buffer and component // for easier readability comp = Container.Components[t]; blocks = Blocks[t]; isInRange = blocks.IsInRange(wallClock); // wait for component to get there if we only have furutre blocks // in auxiliary component. if (blocks.Count > 0 && blocks.RangeStartTime > wallClock) { continue; } // We need the other components to catch up with the main while (blocks.Count == 0 || blocks.RangeEndTime <= wallClock || (Blocks[main].Count > 0 && blocks.RangeEndTime < Blocks[main].RangeEndTime)) { // give up if we never received frames for the expected component if (AddNextBlock(t) == false) { break; } } // Check if we are finally within range isInRange = blocks.IsInRange(wallClock); // Invalidate the renderer if we don't have the block. if (isInRange == false) { InvalidateRenderer(t); } // Move to the next component if we don't meet a regular conditions if (isInRange == false || isBuffering) { continue; } // Decode as much as we can off the packet buffer for this cycle. rangePercent = blocks.GetRangePercent(wallClock); while (blocks.IsFull == false || (blocks.IsFull && rangePercent > 0.75d && rangePercent < 1d)) { if (AddNextBlock(t) == false) { break; } rangePercent = blocks.GetRangePercent(wallClock); } } #endregion } #region 4. Detect End of Media // Detect end of block rendering // TODO: Maybe this detection should be performed on the BlockRendering worker? if (isBuffering == false && decodedFrameCount <= 0 && State.IsSeeking == false && CanReadMoreFramesOf(main) == false && Blocks[main].IndexOf(wallClock) == Blocks[main].Count - 1) { if (State.HasMediaEnded == false) { // Rendered all and nothing else to read Clock.Pause(); wallClock = Blocks[main].RangeEndTime; Clock.Update(wallClock); if (State.NaturalDuration != null && State.NaturalDuration != TimeSpan.MinValue && State.NaturalDuration < wallClock) { Log(MediaLogMessageType.Warning, $"{nameof(State.HasMediaEnded)} conditions met at {wallClock.Format()} but " + $"{nameof(State.NaturalDuration)} reports {State.NaturalDuration.Value.Format()}"); } State.UpdateMediaEnded(true); State.UpdateMediaState(PlaybackStatus.Stop, wallClock); SendOnMediaEnded(); } } else { State.UpdateMediaEnded(false); } #endregion #region 6. Finish the Cycle // complete buffering notifications if (isBuffering) { // Always reset the buffering flag isBuffering = false; // Resume the clock if it was playing if (resumeClock) { Clock.Play(); } // log some message Log(MediaLogMessageType.Debug, $"SYNC-BUFFER: Finished. Clock set to {wallClock.Format()}"); } // If not already set, guess the 1-second buffer length State.GuessBufferingProperties(); // Complete the frame decoding cycle FrameDecodingCycle.Complete(); // Give it a break if there was nothing to decode. // We probably need to wait for some more input if (Commands.IsStopWorkersPending == false && decodedFrameCount <= 0 && Commands.HasQueuedCommands == false) { delay.WaitOne(); } #endregion } } catch { throw; } finally { // Always exit notifying the cycle is done. FrameDecodingCycle.Complete(); delay.Dispose(); } #endregion }
public void Pause(object sender, EventArgs e) { MediaComponent.pause(); }
//POST: /admin/pages/create public async Task <IActionResult> Create(IFormCollection request, [Bind("Name", "Description", "Section")] Page page) { PageTemplate template = await _Db.PageTemplates.FindAsync( request.Int("templateId")); if (template == null) { return(NotFound($"The chosen template was not found.")); } if (!ModelState.IsValid) { return(BadRequest("Server side validation failed.")); } try { await _Db.AddAsync(page); // Create initial page revision PageRevision pageRevision = new PageRevision { Page = page, Template = template, CreatedBy = await _Db.Accounts.FindAsync(User.AccountId()) }; await _Db.AddAsync(pageRevision); // Create empty text fields, and associate to new page for (int i = 0; i < template.TextAreas; i++) { TextComponent textField = new TextComponent { SlotNo = i }; await _Db.AddAsync(textField); await _Db.AddAsync(new RevisionTextComponent { TextComponent = textField, PageRevision = pageRevision, }); } // Create empty media fields, and associate to new page for (int i = 0; i < template.MediaAreas; i++) { MediaComponent mediaComponent = new MediaComponent { SlotNo = i }; await _Db.AddAsync(mediaComponent); await _Db.AddAsync(new RevisionMediaComponent { PageRevisionId = pageRevision.Id, MediaComponentId = mediaComponent.Id }); } // Save all to database in one transaction await _Db.SaveChangesAsync(); // Return new page URL to the caller return(Ok(page.AbsoluteUrl)); } catch (Exception ex) { _Logger.LogWarning("Error creating new page: {0}", ex.Message); _Logger.LogWarning(ex.StackTrace); return(BadRequest("There was an error creating the page. Please try again later.")); } }
/// <summary> /// Continually decodes the available packet buffer to have as /// many frames as possible in each frame queue and /// up to the MaxFrames on each component /// </summary> internal void RunFrameDecodingWorker() { try { // State variables var decodedFrameCount = 0; var wallClock = TimeSpan.Zero; var rangePercent = 0d; var isInRange = false; // Holds the main media type var main = Container.Components.Main.MediaType; // Holds the auxiliary media types var auxs = Container.Components.MediaTypes.Where(x => x != main).ToArray(); // Holds all components var all = Container.Components.MediaTypes.ToArray(); var isBuffering = false; var resumeClock = false; var hasPendingSeeks = false; MediaComponent comp = null; MediaBlockBuffer blocks = null; while (IsTaskCancellationPending == false) { #region 1. Setup the Decoding Cycle // Singal a Seek starting operation hasPendingSeeks = Commands.PendingCountOf(MediaCommandType.Seek) > 0; if (IsSeeking == false && hasPendingSeeks) { IsSeeking = true; RaiseSeekingStartedEvent(); } // Execute the following command at the beginning of the cycle Commands.ProcessNext(); // Signal a Seek ending operation hasPendingSeeks = Commands.PendingCountOf(MediaCommandType.Seek) > 0; if (IsSeeking == true && hasPendingSeeks == false) { SnapVideoPosition(Clock.Position); IsSeeking = false; // Call the seek method on all renderers foreach (var kvp in Renderers) { kvp.Value.Seek(); } RaiseSeekingEndedEvent(); } // Wait for a seek operation to complete (if any) // and initiate a frame decoding cycle. SeekingDone?.WaitOne(); // Initiate the frame docding cycle FrameDecodingCycle?.Reset(); // Set initial state wallClock = Clock.Position; decodedFrameCount = 0; #endregion #region 2. Main Component Decoding // Capture component and blocks for easier readability comp = Container.Components[main]; blocks = Blocks[main]; // Handle the main component decoding; Start by checking we have some packets if (comp.PacketBufferCount > 0) { // Detect if we are in range for the main component isInRange = blocks.IsInRange(wallClock); if (isInRange == false) { // Signal the start of a sync-buffering scenario HasDecoderSeeked = true; isBuffering = true; resumeClock = Clock.IsRunning; Clock.Pause(); Logger.Log(MediaLogMessageType.Debug, $"SYNC-BUFFER: Started."); // Read some frames and try to get a valid range do { // Try to get more packets by waiting for read cycles. if (CanReadMorePackets && comp.PacketBufferCount <= 0) { PacketReadingCycle?.WaitOne(); } // Decode some frames and check if we are in reange now decodedFrameCount += AddBlocks(main); isInRange = blocks.IsInRange(wallClock); // Break the cycle if we are in range if (isInRange || CanReadMorePackets == false) { break; } }while (decodedFrameCount <= 0 && blocks.IsFull == false); // Unfortunately at this point we will need to adjust the clock after creating the frames. // to ensure tha mian component is within the clock range if the decoded // frames are not with range. This is normal while buffering though. if (isInRange == false) { // Update the wall clock to the most appropriate available block. if (blocks.Count > 0) { wallClock = blocks[wallClock].StartTime; } else { resumeClock = false; // Hard stop the clock. } // Update the clock to what the main component range mandates Clock.Position = wallClock; // Call seek to invalidate renderer Renderers[main].Seek(); } } else { // Check if we need more blocks for the current components rangePercent = blocks.GetRangePercent(wallClock); // Read as many blocks as we possibly can while (comp.PacketBufferCount > 0 && ((rangePercent > 0.75d && blocks.IsFull) || blocks.IsFull == false)) { decodedFrameCount += AddBlocks(main); rangePercent = blocks.GetRangePercent(wallClock); } } } #endregion #region 3. Auxiliary Component Decoding foreach (var t in auxs) { if (IsSeeking) { continue; } // Capture the current block buffer and component // for easier readability comp = Container.Components[t]; blocks = Blocks[t]; isInRange = blocks.IsInRange(wallClock); // Invalidate the renderer if we don't have the block. if (isInRange == false) { Renderers[t].Seek(); } // wait for component to get there if we only have furutre blocks // in auxiliary component. if (blocks.Count > 0 && blocks.RangeStartTime > wallClock) { continue; } // Try to catch up with the wall clock while (blocks.Count == 0 || blocks.RangeEndTime <= wallClock) { // Wait for packets if we don't have enough packets if (CanReadMorePackets && comp.PacketBufferCount <= 0) { PacketReadingCycle?.WaitOne(); } if (comp.PacketBufferCount <= 0) { break; } else { decodedFrameCount += AddBlocks(t); } } isInRange = blocks.IsInRange(wallClock); // Move to the next component if we don't meet a regular conditions if (isInRange == false || isBuffering || comp.PacketBufferCount <= 0) { continue; } // Read as much as we can for this cycle. while (comp.PacketBufferCount > 0) { rangePercent = blocks.GetRangePercent(wallClock); if (blocks.IsFull == false || (blocks.IsFull && rangePercent > 0.75d && rangePercent < 1d)) { decodedFrameCount += AddBlocks(t); } else { break; } } } #endregion #region 4. Detect End of Media // Detect end of block rendering if (isBuffering == false && IsSeeking == false && CanReadMoreFramesOf(main) == false && Blocks[main].IndexOf(wallClock) == Blocks[main].Count - 1) { if (HasMediaEnded == false) { // Rendered all and nothing else to read Clock.Pause(); Clock.Position = NaturalDuration.HasTimeSpan ? NaturalDuration.TimeSpan : Blocks[main].RangeEndTime; wallClock = Clock.Position; HasMediaEnded = true; MediaState = MediaState.Pause; RaiseMediaEndedEvent(); } } else { HasMediaEnded = false; } #endregion #region 6. Finish the Cycle // complete buffering notifications if (isBuffering) { // Reset the buffering flag isBuffering = false; // Resume the clock if it was playing if (resumeClock) { Clock.Play(); } // log some message Logger.Log( MediaLogMessageType.Debug, $"SYNC-BUFFER: Finished. Clock set to {wallClock.Format()}"); } // Complete the frame decoding cycle FrameDecodingCycle?.Set(); // After a seek operation, always reset the has seeked flag. HasDecoderSeeked = false; // Give it a break if there was nothing to decode. // We probably need to wait for some more input if (decodedFrameCount <= 0 && Commands.PendingCount <= 0) { Task.Delay(1).GetAwaiter().GetResult(); } #endregion } } catch (ThreadAbortException) { } finally { // Always exit notifying the cycle is done. FrameDecodingCycle?.Set(); } }
/// <summary> /// Initializes Player. /// </summary> /// <param name="e"></param> protected override void OnInitialized(EventArgs e) { Application.Current.DispatcherUnhandledException += (Sender, Args) => { using (FileStream FS = File.Create("exception.txt")) using (TextWriter Writer = new StreamWriter(FS)) WriteExceptionDetails(Args.Exception, Writer); MessageBox.Show("An exception has been encountered. The exact details have been saved in exception.txt. Please contact the developer and hand them this file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); #if !DEBUG Args.Handled = true; #endif Application.Current.Shutdown( ); }; Player = new ViderePlayer(new WindowData { Window = this, MediaControlsContainer = MediaControlsContainer, MediaPlayer = new VLCPlayer(MediaArea.MediaPlayer), MediaArea = MediaArea }); MediaComponent mediaComponent = Player.GetComponent <MediaComponent>( ); mediaComponent.OnMediaLoaded += OnOnMediaLoaded; mediaComponent.OnMediaUnloaded += OnOnMediaUnloaded; mediaComponent.OnMediaFailedToLoad += MediaComponentOnOnMediaFailedToLoad; WindowButtonCommandsOverlayBehavior = WindowCommandsOverlayBehavior.Never; RightWindowCommandsOverlayBehavior = WindowCommandsOverlayBehavior.Never; LeftWindowCommandsOverlayBehavior = WindowCommandsOverlayBehavior.Never; Client = new Client(UserAgent); Application.Current.Exit += (sender, args) => { Settings.Default.SubtitleTimeOffset = 0; Settings.Default.Save( ); }; KeyDown += OnKeyDown; StateComponent stateComponent = Player.GetComponent <StateComponent>( ); ScreenComponent screenComponent = Player.GetComponent <ScreenComponent>( ); stateComponent.OnStateChanged += (Sender, Args) => { switch (Args.State) { case StateComponent.PlayerState.Playing: screenComponent.DisableSleeping( ); break; case StateComponent.PlayerState.Paused: case StateComponent.PlayerState.Stopped: screenComponent.EnableSleeping( ); break; } }; string[] cmdArgs = Environment.GetCommandLineArgs( ); if (cmdArgs.Length > 1) { Player.GetComponent <MediaComponent>( ).LoadMedia(cmdArgs[1]); } base.OnInitialized(e); (( OpenSubtitlesControl )this.OSFlyout.Content).InitWindow(this); }
public async Task <IActionResult> CreateRevision(int pageId, IFormCollection request) { /* To be supplied in request body - * * Reason for change - e.g. Updated pricing information * Template ID * Collection of text components * Collection of media components * */ try { // Load page from database Page page = await _Db.Pages.FindAsync(pageId); if (page == null) { return(BadRequest("No page exists for given page ID")); } List <TextComponent> newRevisionTextComponents = request.Deserialize(typeof(List <TextComponent>), "textComponents"); List <MediaComponent> newRevisionMediaComponents = request.Deserialize(typeof(List <MediaComponent>), "imageComponents"); // Todo: Do this after the view has had template switching enabled // Load template from database // PageTemplate template = await _Db.PageTemplates // .FindAsync(request.Int("templateId")); // Fetch the original revision PageRevision old = await _Db.PageRevisions .Include(pr => pr.Template) .Include(pr => pr.RevisionMediaComponents) .ThenInclude(rmc => rmc.MediaComponent) .Include(pr => pr.RevisionTextComponents) .ThenInclude(rtc => rtc.TextComponent) .ThenInclude(tc => tc.CmsButton) .Where(pr => pr.Page == page) .OrderByDescending(pr => pr.CreatedAt) .FirstOrDefaultAsync(); var oldRevision = new { old.Template, TextComponents = old.RevisionTextComponents .Select(rtc => rtc.TextComponent) .OrderBy(tc => tc.SlotNo) .ToList(), MediaComponents = old.RevisionMediaComponents .Select(rmc => rmc.MediaComponent) .OrderBy(tc => tc.SlotNo) .ToList() }; // Create the new page revision PageRevision newRevision = new PageRevision { Page = page, Template = oldRevision.Template, Reason = request.Str("reason"), CreatedBy = await _Db.Accounts.FindAsync(User.AccountId()), }; // Assign the new revision an ID await _Db.AddAsync(newRevision); for (int i = 0; i < newRevision.Template.TextAreas; i++) { TextComponent textComponentToSave = null; // Only save a new text component if it has changed if (!newRevisionTextComponents[i].Equals(oldRevision.TextComponents[i])) { textComponentToSave = newRevisionTextComponents[i]; // Set ID to 0 so that EF Core assigns us a new one textComponentToSave.Id = 0; // Save a new button if the components button does not yet exist in database. if (textComponentToSave.CmsButton != null && !textComponentToSave.CmsButton.Equals(oldRevision.TextComponents[i].CmsButton)) { await _Db.AddAsync(textComponentToSave.CmsButton); } // Generate ID for the new TextComponent await _Db.AddAsync(textComponentToSave); } // Add association between component and new revision await _Db.AddAsync(new RevisionTextComponent { // Use the new components ID if it exists, other use existing (unchanged) component // from previous revision TextComponentId = textComponentToSave?.Id ?? oldRevision.TextComponents[i].Id, PageRevisionId = newRevision.Id }); } // Do the same for media components for (int i = 0; i < newRevision.Template.MediaAreas; i++) { MediaComponent mediaComponentToSave = null; // Only create new media component if the old one was modified if (!newRevisionMediaComponents[i].Equals(oldRevision.MediaComponents[i])) { mediaComponentToSave = newRevisionMediaComponents[i]; // Generate new ID mediaComponentToSave.Id = 0; await _Db.AddAsync(mediaComponentToSave); } // Add association to new revision await _Db.AddAsync(new RevisionMediaComponent { PageRevisionId = newRevision.Id, MediaComponentId = mediaComponentToSave?.Id ?? oldRevision.MediaComponents[i].Id }); } // Save changes await _Db.SaveChangesAsync(); _Logger.LogDebug("New page revision created for page {0} ({1}): {2}", pageId, page.Name, newRevision.Reason); return(Ok()); } catch (Exception ex) { _Logger.LogError("Error creating new revision for page {0}: {1}", pageId, ex.Message); _Logger.LogError(ex.StackTrace); return(BadRequest("Something went wrong, please try again later.")); } }
/// <summary> /// Continually decodes the available packet buffer to have as /// many frames as possible in each frame queue and /// up to the MaxFrames on each component /// </summary> internal void RunFrameDecodingWorker() { #region Worker State Setup // The delay provider prevents 100% core usage var delay = new DelayProvider(); // State variables var decodedFrameCount = 0; var wallClock = TimeSpan.Zero; var rangePercent = 0d; var isInRange = false; var playAfterSeek = false; // Holds the main media type var main = Container.Components.Main.MediaType; // Holds the auxiliary media types var auxs = Container.Components.MediaTypes.ExcludeMediaType(main); // Holds all components var all = Container.Components.MediaTypes.DeepCopy(); var isBuffering = false; var resumeClock = false; var hasPendingSeeks = false; MediaComponent comp = null; MediaBlockBuffer blocks = null; #endregion #region Worker Loop try { while (IsTaskCancellationPending == false) { #region 1. Setup the Decoding Cycle // Singal a Seek starting operation hasPendingSeeks = Commands.PendingCountOf(MediaCommandType.Seek) > 0; if (State.IsSeeking == false && hasPendingSeeks) { playAfterSeek = State.IsPlaying; State.IsSeeking = true; SendOnSeekingStarted(); } // Execute the following command at the beginning of the cycle Commands.ProcessNext(); // Wait for a seek operation to complete (if any) // and initiate a frame decoding cycle. SeekingDone.Wait(); // Set initial state wallClock = WallClock; decodedFrameCount = 0; // Signal a Seek ending operation // TOD: Maybe this should go on the block rendering worker? hasPendingSeeks = Commands.PendingCountOf(MediaCommandType.Seek) > 0; if (State.IsSeeking && hasPendingSeeks == false) { // Detect a end of seek cycle and update to the final position wallClock = SnapToFramePosition(WallClock); Clock.Update(wallClock); State.UpdatePosition(wallClock); // Call the seek method on all renderers foreach (var kvp in Renderers) { LastRenderTime[kvp.Key] = TimeSpan.MinValue; kvp.Value.Seek(); } SendOnSeekingEnded(); State.IsSeeking = false; if (playAfterSeek) { Clock.Play(); State.UpdateMediaState(PlaybackStatus.Play); } else { State.UpdateMediaState(PlaybackStatus.Pause); } } else if (State.IsSeeking == false) { // Notify position changes State.UpdatePosition(wallClock); } // Initiate the frame docding cycle FrameDecodingCycle.Begin(); #endregion #region 2. Main Component Decoding // Capture component and blocks for easier readability comp = Container.Components[main]; blocks = Blocks[main]; // Handle the main component decoding; Start by checking we have some packets while (comp.PacketBufferCount <= 0 && CanReadMorePackets && ShouldReadMorePackets) { PacketReadingCycle.Wait(Constants.Interval.LowPriority); } if (comp.PacketBufferCount > 0) { // Detect if we are in range for the main component isInRange = blocks.IsInRange(wallClock); if (isInRange == false) { // Signal the start of a sync-buffering scenario HasDecoderSeeked = true; isBuffering = true; resumeClock = Clock.IsRunning; Clock.Pause(); Log(MediaLogMessageType.Debug, $"SYNC-BUFFER: Started."); // Read some frames and try to get a valid range do { // Try to get more packets by waiting for read cycles. if (CanReadMorePackets && comp.PacketBufferCount <= 0) { PacketReadingCycle.Wait(); } // Decode some frames and check if we are in reange now decodedFrameCount += AddBlocks(main); isInRange = blocks.IsInRange(wallClock); // Break the cycle if we are in range if (isInRange || CanReadMorePackets == false) { break; } }while (decodedFrameCount <= 0 && blocks.IsFull == false); // Unfortunately at this point we will need to adjust the clock after creating the frames. // to ensure tha mian component is within the clock range if the decoded // frames are not with range. This is normal while buffering though. if (isInRange == false) { // Update the wall clock to the most appropriate available block. if (blocks.Count > 0) { wallClock = blocks[wallClock].StartTime; } else { resumeClock = false; // Hard stop the clock. } // Update the clock to what the main component range mandates Clock.Update(wallClock); // Call seek to invalidate renderer LastRenderTime[main] = TimeSpan.MinValue; Renderers[main].Seek(); // Try to recover the regular loop isInRange = true; while (CanReadMorePackets && comp.PacketBufferCount <= 0) { PacketReadingCycle.Wait(); } } } if (isInRange) { // Check if we need more blocks for the current components rangePercent = blocks.GetRangePercent(wallClock); // Read as much as we can for this cycle. while (comp.PacketBufferCount > 0) { rangePercent = blocks.GetRangePercent(wallClock); if (blocks.IsFull == false || (blocks.IsFull && rangePercent > 0.75d && rangePercent < 1d)) { decodedFrameCount += AddBlocks(main); } else { break; } } } } #endregion #region 3. Auxiliary Component Decoding foreach (var t in auxs) { if (State.IsSeeking) { continue; } // Capture the current block buffer and component // for easier readability comp = Container.Components[t]; blocks = Blocks[t]; isInRange = blocks.IsInRange(wallClock); // Invalidate the renderer if we don't have the block. if (isInRange == false) { LastRenderTime[t] = TimeSpan.MinValue; Renderers[t].Seek(); } // wait for component to get there if we only have furutre blocks // in auxiliary component. if (blocks.Count > 0 && blocks.RangeStartTime > wallClock) { continue; } // Try to catch up with the wall clock while (blocks.Count == 0 || blocks.RangeEndTime <= wallClock) { // Wait for packets if we don't have enough packets if (CanReadMorePackets && comp.PacketBufferCount <= 0) { PacketReadingCycle.Wait(); } if (comp.PacketBufferCount <= 0) { break; } else { decodedFrameCount += AddBlocks(t); } } isInRange = blocks.IsInRange(wallClock); // Move to the next component if we don't meet a regular conditions if (isInRange == false || isBuffering || comp.PacketBufferCount <= 0) { continue; } // Read as much as we can for this cycle. while (comp.PacketBufferCount > 0) { rangePercent = blocks.GetRangePercent(wallClock); if (blocks.IsFull == false || (blocks.IsFull && rangePercent > 0.75d && rangePercent < 1d)) { decodedFrameCount += AddBlocks(t); } else { break; } } } #endregion #region 4. Detect End of Media // Detect end of block rendering // TODO: Maybe this detection should be performed on the BlockRendering worker? if (isBuffering == false && State.IsSeeking == false && CanReadMoreFramesOf(main) == false && Blocks[main].IndexOf(wallClock) == Blocks[main].Count - 1) { if (State.HasMediaEnded == false) { // Rendered all and nothing else to read Clock.Pause(); if (State.NaturalDuration != null && State.NaturalDuration != TimeSpan.MinValue) { wallClock = State.NaturalDuration.Value; } else { wallClock = Blocks[main].RangeEndTime; } Clock.Update(wallClock); State.HasMediaEnded = true; State.UpdateMediaState(PlaybackStatus.Stop, wallClock); SendOnMediaEnded(); } } else { State.HasMediaEnded = false; } #endregion #region 6. Finish the Cycle // complete buffering notifications if (isBuffering) { // Reset the buffering flag isBuffering = false; // Resume the clock if it was playing if (resumeClock) { Clock.Play(); } // log some message Log( MediaLogMessageType.Debug, $"SYNC-BUFFER: Finished. Clock set to {wallClock.Format()}"); } // Complete the frame decoding cycle FrameDecodingCycle.Complete(); // After a seek operation, always reset the has seeked flag. HasDecoderSeeked = false; // If not already set, guess the 1-second buffer length State.GuessBufferingProperties(); // Give it a break if there was nothing to decode. // We probably need to wait for some more input if (decodedFrameCount <= 0 && Commands.PendingCount <= 0) { delay.WaitOne(); } #endregion } } catch (ThreadAbortException) { /* swallow */ } catch { if (!IsDisposed) { throw; } } finally { // Always exit notifying the cycle is done. FrameDecodingCycle.Complete(); delay.Dispose(); } #endregion }
private void RemoveSong(OptionArgs args) { MediaComponent.removeSong(args.text); dynamicInitialize(); }