这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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