Skip to content

Commit

Permalink
Merge pull request #190 from xibosignage/develop
Browse files Browse the repository at this point in the history
Release v2 R256 patch 7
  • Loading branch information
dasgarner authored Dec 21, 2020
2 parents d6237dc + 02cb66e commit b758e2a
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 22 deletions.
10 changes: 10 additions & 0 deletions Action/Command.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;

namespace XiboClient.Logic
{
Expand Down Expand Up @@ -40,6 +41,15 @@ public bool Run()
return true;
}
}
else if (CommandString == "SoftRestart")
{
// Call close.
Application.Current.Dispatcher.Invoke(new System.Action(() => {
Application.Current.MainWindow.Close();
}));

return true;
}
else
{
// Process with CMD
Expand Down
42 changes: 42 additions & 0 deletions Helpers/ProxyRequestHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (C) 2020 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
using CefSharp;
using CefSharp.Handler;

namespace XiboClient.Helpers
{
class ProxyRequestHandler : RequestHandler
{
protected override bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
if (isProxy)
{
callback.Continue(ApplicationSettings.Default.ProxyUser, ApplicationSettings.Default.ProxyPassword);

return true;
}
else
{
return false;
}
}
}
}
4 changes: 3 additions & 1 deletion Logic/ApplicationSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private static readonly Lazy<ApplicationSettings>
/// </summary>
private List<string> ExcludedProperties;

public string ClientVersion { get; } = "2 R256.5";
public string ClientVersion { get; } = "2 R256.7";
public string Version { get; } = "5";
public int ClientCodeVersion { get; } = 256;

Expand Down Expand Up @@ -456,6 +456,8 @@ public string ServerUri
public string ClientInformationKeyCode { get; set; }
public string XmrNetworkAddress { get; set; }
public string AggregationLevel { get; set; }
public string AuthServerWhitelist { get; set; }
public string EdgeBrowserWhitelist { get; set; }

// Download window
public string DisplayTimeZone { get; set; }
Expand Down
10 changes: 6 additions & 4 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,12 @@ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
CefSharp.CefSharpSettings.SubprocessExitIfParentProcessClosed = true;

// Settings for Init
CefSharp.Wpf.CefSettings settings = new CefSharp.Wpf.CefSettings();
settings.CachePath = ApplicationSettings.Default.LibraryPath + @"\CEF";
settings.LogFile = ApplicationSettings.Default.LibraryPath + @"\CEF\cef.log";
settings.LogSeverity = CefSharp.LogSeverity.Fatal;
CefSharp.Wpf.CefSettings settings = new CefSharp.Wpf.CefSettings
{
CachePath = ApplicationSettings.Default.LibraryPath + @"\CEF",
LogFile = ApplicationSettings.Default.LibraryPath + @"\CEF\cef.log",
LogSeverity = CefSharp.LogSeverity.Fatal
};
settings.CefCommandLineArgs["autoplay-policy"] = "no-user-gesture-required";

CefSharp.Cef.Initialize(settings);
Expand Down
4 changes: 2 additions & 2 deletions Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.256.0.5")]
[assembly: AssemblyFileVersion("2.256.0.5")]
[assembly: AssemblyVersion("2.256.0.7")]
[assembly: AssemblyFileVersion("2.256.0.7")]
[assembly: Guid("3bd467a4-4ef9-466a-b156-a79c13a863f7")]
4 changes: 3 additions & 1 deletion Rendering/Region.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ private void StopMedia(Media media)
/// <param name="regionStopped"></param>
private void StopMedia(Media media, bool regionStopped)
{
Trace.WriteLine(new LogMessage("Region", "StopMedia: Stopping..."), LogType.Audit.ToString());
Trace.WriteLine(new LogMessage("Region", "StopMedia: " + media.Id + " stopping, region stopped " + regionStopped), LogType.Audit.ToString());

// Dispose of the current media
try
Expand Down Expand Up @@ -798,6 +798,8 @@ private void StopMedia(Media media, bool regionStopped)
/// <param name="media"></param>
private void Media_MediaStoppedEvent(Media media)
{
Trace.WriteLine(new LogMessage("Region", "Media_MediaStoppedEvent: " + media.Id), LogType.Audit.ToString());

media.MediaStoppedEvent -= Media_MediaStoppedEvent;
media.Stopped();

Expand Down
98 changes: 90 additions & 8 deletions Rendering/Video.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace XiboClient.Rendering
{
Expand All @@ -34,8 +35,21 @@ class Video : Media
private bool _detectEnd = false;
private bool isLooping = false;
private readonly bool isFullScreenRequest = false;
private bool _openCalled = false;

/// <summary>
/// Should this be visible? Audio sets this to false.
/// </summary>
protected bool ShouldBeVisible { get; set; }

/// <summary>
/// Muted?
/// </summary>
protected bool Muted { get; set; }

/// <summary>
/// Stretched?
/// </summary>
protected bool Stretch { get; set; }

/// <summary>
Expand All @@ -54,6 +68,7 @@ class Video : Media
/// <param name="options"></param>
public Video(RegionOptions options) : base(options)
{
// Videos should be visible
this.ShouldBeVisible = true;

_filePath = Uri.UnescapeDataString(options.uri).Replace('+', ' ');
Expand All @@ -79,20 +94,35 @@ public Video(RegionOptions options) : base(options)
Stretch = options.Dictionary.Get("scaleType", "aspect").ToLowerInvariant() == "stretch";
}

/// <summary>
/// Media Failed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
// Log and expire
Trace.WriteLine(new LogMessage("Video", "MediaElement_MediaFailed: Media Failed. E = " + e.ErrorException.Message), LogType.Error.ToString());
Trace.WriteLine(new LogMessage("Video", "MediaElement_MediaFailed: " + this.Id + " Media Failed. E = " + e.ErrorException.Message), LogType.Error.ToString());

// Failed is the opposite of open, but we mark this as open called so that our watchman doesn't also try to expire
this._openCalled = true;

// Add this to a temporary blacklist so that we don't repeat it too quickly
CacheManager.Instance.AddUnsafeItem(UnsafeItemType.Media, LayoutId, Id, "Video Failed: " + e.ErrorException.Message, 120);

// Expire
Expired = true;
SignalElapsedEvent();
}

private void MediaElement_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
/// <summary>
/// Media Ended
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
Trace.WriteLine(new LogMessage("Video", "MediaElement_MediaEnded: " + this.Id + " Ended, looping: " + isLooping), LogType.Audit.ToString());

// Should we loop?
if (isLooping)
{
Expand All @@ -106,23 +136,51 @@ private void MediaElement_MediaEnded(object sender, System.Windows.RoutedEventAr
}

/// <summary>
/// Media is loaded
/// MediaElement has been added to the visual tree
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MediaElement_Loaded(object sender, RoutedEventArgs e)
{
Trace.WriteLine(new LogMessage("Video", "MediaElement_Loaded: " + this.Id + " Control loaded, calling Play."), LogType.Audit.ToString());

try
{
this.mediaElement.Play();
}
catch (Exception ex)
{
// Problem calling play, we should expire.
Trace.WriteLine(new LogMessage("Video", "MediaElement_Loaded: Media Failed. E = " + ex.Message), LogType.Error.ToString());
Trace.WriteLine(new LogMessage("Video", "MediaElement_Loaded: " + this.Id + " Media Failed. E = " + ex.Message), LogType.Error.ToString());
}

// We make a watchman to check that the video actually gets loaded.
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(4) };
timer.Tick += (timerSender, args) =>
{
// You only tick once
timer.Stop();

// Check to see if open has been called.
if (!_openCalled)
{
Trace.WriteLine(new LogMessage("Video", "MediaElement_Loaded: " + this.Id + " Open not called after 4 seconds, marking unsafe and Expiring."), LogType.Error.ToString());

// Add this to a temporary blacklist so that we don't repeat it too quickly
CacheManager.Instance.AddUnsafeItem(UnsafeItemType.Media, LayoutId, Id, "Video Failed: Open not called after 4 seconds", 120);

// Expire
SignalElapsedEvent();
}
};

timer.Start();
}

/// <summary>
/// Render
/// </summary>
/// <param name="position"></param>
public override void RenderMedia(double position)
{
// Save the position
Expand All @@ -134,7 +192,7 @@ public override void RenderMedia(double position)

if (uri.IsFile && !File.Exists(_filePath))
{
Trace.WriteLine(new LogMessage("Video", "RenderMedia: File " + _filePath + " not found."));
Trace.WriteLine(new LogMessage("Video", "RenderMedia: " + this.Id + ", File " + _filePath + " not found."));
throw new FileNotFoundException();
}

Expand All @@ -143,13 +201,22 @@ public override void RenderMedia(double position)
this.mediaElement.Volume = this.volume;
this.mediaElement.IsMuted = this.Muted;
this.mediaElement.LoadedBehavior = MediaState.Manual;
this.mediaElement.UnloadedBehavior = MediaState.Close;

// This is false if we're an audio module, otherwise video.
if (!this.ShouldBeVisible)
{
this.mediaElement.Width = 0;
this.mediaElement.Height = 0;
this.mediaElement.Visibility = Visibility.Hidden;
}
else
{
// Assert the Width/Height of the Parent
this.mediaElement.Width = Width;
this.mediaElement.Height = Height;
this.mediaElement.Visibility = Visibility.Visible;
}

// Handle stretching
if (Stretch)
Expand All @@ -158,9 +225,16 @@ public override void RenderMedia(double position)
}

// Events
// MediaOpened is called after we've called Play()
this.mediaElement.MediaOpened += MediaElement_MediaOpened;

// Loaded is from the Framework and is called when the MediaElement is added to the visual tree (we call play in here)
this.mediaElement.Loaded += MediaElement_Loaded;

// Media ended is called when the media file has finished playing
this.mediaElement.MediaEnded += MediaElement_MediaEnded;

// Media Failed is called if the media file cannot be opened
this.mediaElement.MediaFailed += MediaElement_MediaFailed;

// Do we need to determine the end time ourselves?
Expand All @@ -183,7 +257,7 @@ public override void RenderMedia(double position)

this.MediaScene.Children.Add(this.mediaElement);

Trace.WriteLine(new LogMessage("Video", "RenderMedia: Video Started"), LogType.Audit.ToString());
Trace.WriteLine(new LogMessage("Video", "RenderMedia: " + this.Id + ", added MediaElement and set source, detect end is " + _detectEnd), LogType.Audit.ToString());
}
catch (Exception ex)
{
Expand All @@ -201,12 +275,18 @@ public override void RenderMedia(double position)
/// <param name="e"></param>
private void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
{
Debug.WriteLine("MediaElement_MediaOpened", "Video");
Trace.WriteLine(new LogMessage("Video", "MediaElement_MediaOpened: " + this.Id + " Opened, seek to: " + this._position), LogType.Audit.ToString());

// Open has been called.
this._openCalled = true;

// Try to seek
if (this._position > 0)
{
this.mediaElement.Position = TimeSpan.FromSeconds(this._position);

// Set the position to 0, so that if we loop around again we start from the beginning
this._position = 0;
}
}

Expand All @@ -215,6 +295,8 @@ private void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
/// </summary>
public override void Stopped()
{
Trace.WriteLine(new LogMessage("Video", "Stopped: " + this.Id), LogType.Audit.ToString());

// Remove the event handlers
this.mediaElement.MediaOpened -= MediaElement_MediaOpened;
this.mediaElement.Loaded -= MediaElement_Loaded;
Expand Down
30 changes: 29 additions & 1 deletion Rendering/WebCef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,34 @@ public override void RenderMedia(double position)
Name = "region_" + this.regionId
};

// Configure run time CEF settings?
if (!string.IsNullOrEmpty(ApplicationSettings.Default.AuthServerWhitelist)
|| !string.IsNullOrEmpty(ApplicationSettings.Default.ProxyUser))
{
CefSharp.Cef.UIThreadTaskFactory.StartNew(() =>
{
// NTLM/Auth Server White Lists.
if (!string.IsNullOrEmpty(ApplicationSettings.Default.AuthServerWhitelist))
{
if (!webView.RequestContext.SetPreference("auth.server_whitelist", ApplicationSettings.Default.AuthServerWhitelist, out string error))
{
Trace.WriteLine(new LogMessage("WebCef", "RenderMedia: auth.server_whitelist. e = " + error), LogType.Error.ToString());
}

if (!webView.RequestContext.SetPreference("auth.negotiate_delegate_whitelist", ApplicationSettings.Default.AuthServerWhitelist, out string error2))
{
Trace.WriteLine(new LogMessage("WebCef", "RenderMedia: auth.negotiate_delegate_whitelist. e = " + error2), LogType.Error.ToString());
}
}

// Proxy
if (!string.IsNullOrEmpty(ApplicationSettings.Default.ProxyUser))
{
webView.RequestHandler = new ProxyRequestHandler();
}
});
}

webView.Visibility = System.Windows.Visibility.Hidden;
webView.Loaded += WebView_Loaded;
webView.LoadError += WebView_LoadError;
Expand Down Expand Up @@ -106,7 +134,7 @@ private void WebView_Loaded(object sender, System.Windows.RoutedEventArgs e)

private void WebView_LoadError(object sender, CefSharp.LoadErrorEventArgs e)
{
Trace.WriteLine(new LogMessage("EdgeWebMedia", "Cannot navigate. e = " + e.ToString()), LogType.Error.ToString());
Trace.WriteLine(new LogMessage("WebCef", "WebView_LoadError: Cannot navigate. e = " + e.ToString()), LogType.Error.ToString());

// This should exipre the media
Duration = 5;
Expand Down
Loading

0 comments on commit b758e2a

Please sign in to comment.