using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Logging;
using MediaBrowser.UI.Configuration;
using MediaBrowser.UI.UserInput;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MediaBrowser.UI.Playback.ExternalPlayer
{
///
/// Class BaseExternalPlayer
///
public abstract class BaseExternalPlayer : BaseMediaPlayer
{
protected BaseExternalPlayer(ILogger logger) : base(logger)
{
}
///
/// Gets a value indicating whether this instance can mute.
///
/// true if this instance can mute; otherwise, false.
public override bool CanMute
{
get { return false; }
}
///
/// Gets a value indicating whether this instance can change volume.
///
/// true if this instance can change volume; otherwise, false.
public override bool CanControlVolume
{
get { return false; }
}
///
/// Gets a value indicating whether this instance can close automatically.
///
/// true if this instance can close automatically; otherwise, false.
protected virtual bool CanCloseAutomatically
{
get
{
return false;
}
}
///
/// Gets a value indicating whether [supports multi file playback].
///
/// true if [supports multi file playback]; otherwise, false.
public override bool SupportsMultiFilePlayback
{
get
{
return false;
}
}
///
/// Gets the current process.
///
/// The current process.
protected Process CurrentProcess { get; private set; }
///
/// Gets the process start info.
///
/// The items.
/// The options.
/// The player configuration.
/// ProcessStartInfo.
protected virtual ProcessStartInfo GetProcessStartInfo(List items, PlayOptions options, PlayerConfiguration playerConfiguration)
{
return new ProcessStartInfo
{
FileName = playerConfiguration.Command,
Arguments = GetCommandArguments(items, options, playerConfiguration)
};
}
///
/// Gets the command arguments.
///
/// The items.
/// The options.
/// The player configuration.
/// System.String.
protected virtual string GetCommandArguments(List items, PlayOptions options, PlayerConfiguration playerConfiguration)
{
var args = playerConfiguration.Args;
if (string.IsNullOrEmpty(args))
{
return string.Empty;
}
return GetCommandArguments(items, args);
}
///
/// Gets the command arguments.
///
/// The items.
/// The format string.
/// System.String.
protected string GetCommandArguments(List items, string formatString)
{
var paths = items.Select(i => "\"" + GetPathForCommandLine(i) + "\"");
return string.Format(formatString, string.Join(" ", paths.ToArray()));
}
///
/// Gets the path for command line.
///
/// The item.
/// System.String.
protected virtual string GetPathForCommandLine(BaseItemDto item)
{
return item.Path;
}
///
/// Gets a value indicating whether this instance can queue.
///
/// true if this instance can queue; otherwise, false.
public override bool CanQueue
{
get { return false; }
}
///
/// Gets a value indicating whether this instance can pause.
///
/// true if this instance can pause; otherwise, false.
public override bool CanPause
{
get { return false; }
}
///
/// Gets a value indicating whether this instance can seek.
///
/// true if this instance can seek; otherwise, false.
public override bool CanSeek
{
get { return false; }
}
///
/// Plays the internal.
///
/// The items.
/// The options.
/// The player configuration.
protected override void PlayInternal(List items, PlayOptions options, PlayerConfiguration playerConfiguration)
{
CurrentProcess = new Process
{
EnableRaisingEvents = true,
StartInfo = GetProcessStartInfo(items, options, playerConfiguration)
};
Logger.Info("{0} {1}", CurrentProcess.StartInfo.FileName, CurrentProcess.StartInfo.Arguments);
CurrentProcess.Start();
OnExternalPlayerLaunched();
if (!CanCloseAutomatically)
{
KeyboardListener.KeyDown += KeyboardListener_KeyDown;
}
CurrentProcess.Exited += CurrentProcess_Exited;
}
///
/// Handles the KeyDown event of the KeyboardListener control.
///
/// The source of the event.
/// The instance containing the event data.
void KeyboardListener_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.MediaStop)
{
var playstate = PlayState;
if (playstate == PlayState.Paused || playstate == PlayState.Playing)
{
Stop();
}
}
}
///
/// Handles the Exited event of the CurrentProcess control.
///
/// The source of the event.
/// The instance containing the event data.
void CurrentProcess_Exited(object sender, EventArgs e)
{
var process = (Process)sender;
process.Dispose();
OnPlayerStopped(CurrentPlaylistIndex, CurrentPositionTicks);
}
///
/// Stops the internal.
///
/// Task.
protected override Task StopInternal()
{
return Task.Run(() => CurrentProcess.Kill());
}
///
/// Called when [player stopped internal].
///
protected override void OnPlayerStoppedInternal()
{
KeyboardListener.KeyDown -= KeyboardListener_KeyDown;
base.OnPlayerStoppedInternal();
}
///
/// Called when [external player launched].
///
protected virtual void OnExternalPlayerLaunched()
{
}
}
}