diff --git a/LibMPlayerCommon/LibMPlayerCommon.csproj b/LibMPlayerCommon/LibMPlayerCommon.csproj index d986940..07f3b84 100644 --- a/LibMPlayerCommon/LibMPlayerCommon.csproj +++ b/LibMPlayerCommon/LibMPlayerCommon.csproj @@ -1,128 +1,130 @@ - - - - {5D3616D0-160D-4601-AB67-E1ED9111C676} - Debug - AnyCPU - Library - LibMPlayerCommon - LibMplayerCommon - v4.5 - Properties - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - x86 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - - - bin\Release\ - False - None - True - False - TRACE - - - 4 - - - 4 - 1591 - bin\Release\LibMplayerCommon.xml - - - 4 - - - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Windows Installer 3.1 - true - - - - - {C859FA27-7882-4814-9202-9C9D807C2CE5} - LibImages - - - - - - - - - - - - + + + + {5D3616D0-160D-4601-AB67-E1ED9111C676} + Debug + AnyCPU + Library + LibMPlayerCommon + LibMplayerCommon + v4.5 + Properties + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + x86 + + + bin\Debug\ + True + Full + False + True + DEBUG;TRACE + + + bin\Release\ + False + None + True + False + TRACE + + + 4 + + + 4 + 1591 + bin\Release\LibMplayerCommon.xml + + + 4 + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + {C859FA27-7882-4814-9202-9C9D807C2CE5} + LibImages + + + + + + + + + + + + \ No newline at end of file diff --git a/LibMPlayerCommon/MPlayer.cs b/LibMPlayerCommon/MPlayer.cs index b190355..b739a76 100644 --- a/LibMPlayerCommon/MPlayer.cs +++ b/LibMPlayerCommon/MPlayer.cs @@ -33,7 +33,7 @@ namespace LibMPlayerCommon public class MPlayer : IDisposable, Player { - private int _wid; + private long _wid; private bool _fullscreen; private int _mplayerProcessID = -1; private MplayerBackends _mplayerBackend; @@ -84,12 +84,12 @@ private MPlayer() { } - public MPlayer(int wid, MplayerBackends backend) + public MPlayer(long wid, MplayerBackends backend) : this(wid, backend, "") { } - public MPlayer(int wid, MplayerBackends backend, string mplayerPath) + public MPlayer(long wid, MplayerBackends backend, string mplayerPath) : this(wid, backend, mplayerPath, false, TimeSpan.FromMilliseconds(1000)) { } @@ -105,7 +105,7 @@ public MPlayer(int wid, MplayerBackends backend, string mplayerPath) /// play any files until MplayerRunning is true. /// Interval of periodical position updates /// Specify custom console arguments here; default "-slave -quiet -idle -v -ontop" ( do not set -vo and -wid ) - public MPlayer(int wid, MplayerBackends backend, string mplayerPath, bool loadMplayer, TimeSpan positionUpdateInterval, string consoleArguments = "-slave -quiet -idle -v -ontop") + public MPlayer(long wid, MplayerBackends backend, string mplayerPath, bool loadMplayer, TimeSpan positionUpdateInterval, string consoleArguments = "-slave -quiet -idle -v -ontop") { this._wid = wid; this._fullscreen = false; @@ -341,6 +341,14 @@ private void InitializeMplayer() } + /// + /// This is only useful if mplayer has not yet been initialized + /// + public void SetHandle(long wid) + { + _wid = wid; + } + /// /// Load and start playing a video. /// diff --git a/LibMPlayerCommon/MpvPlayer.cs b/LibMPlayerCommon/MpvPlayer.cs new file mode 100644 index 0000000..a36e241 --- /dev/null +++ b/LibMPlayerCommon/MpvPlayer.cs @@ -0,0 +1,587 @@ +/* + +Copyright 2010 (C) Peter Gill + +This file is part of LibMPlayerCommon. + +LibMPlayerCommon is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +LibMPlayerCommon 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 Lesser General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +*/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Timers; + + +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Globalization; + + +namespace LibMPlayerCommon +{ + + public class MpvPlayer : IDisposable, Player + { + + private const int MpvFormatString = 1; + private IntPtr _libMpvDll; + private IntPtr _mpvHandle; + + #region Linux + + [DllImport ("libdl.so")] + protected static extern IntPtr dlopen (string filename, int flags); + + [DllImport ("libdl.so")] + protected static extern IntPtr dlsym (IntPtr handle, string symbol); + + const int RTLD_NOW = 2; + // for dlopen's flags + + #endregion + + [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false)] + internal static extern IntPtr LoadLibrary (string dllToLoad); + + [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false)] + internal static extern IntPtr GetProcAddress (IntPtr hModule, string procedureName); + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate IntPtr MpvCreate (); + + private MpvCreate _mpvCreate; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvInitialize (IntPtr mpvHandle); + + private MpvInitialize _mpvInitialize; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvCommand (IntPtr mpvHandle, IntPtr strings); + + private MpvCommand _mpvCommand; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvTerminateDestroy (IntPtr mpvHandle); + + private MpvTerminateDestroy _mpvTerminateDestroy; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvSetOption (IntPtr mpvHandle, byte[] name, int format, ref long data); + + private MpvSetOption _mpvSetOption; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvSetOptionString (IntPtr mpvHandle, byte[] name, byte[] value); + + private MpvSetOptionString _mpvSetOptionString; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvGetPropertystring (IntPtr mpvHandle, byte[] name, int format, ref IntPtr data); + + private MpvGetPropertystring _mpvGetPropertyString; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate int MpvSetProperty (IntPtr mpvHandle, byte[] name, int format, ref byte[] data); + + private MpvSetProperty _mpvSetProperty; + + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + private delegate void MpvFree (IntPtr data); + + private MpvFree _mpvFree; + + + private object GetDllType (Type type, string name) + { + IntPtr address; + var platform = PlatformCheck.RunningPlatform (); + if (platform == Platform.Windows) { + address = GetProcAddress (_libMpvDll, name); + } else if (platform == Platform.Linux) { + address = dlsym (_libMpvDll, name); + } else { + throw new NotImplementedException (); + } + + if (address != IntPtr.Zero) + return Marshal.GetDelegateForFunctionPointer (address, type); + return null; + } + + private void LoadMpvDynamic () + { + var platform = PlatformCheck.RunningPlatform (); + if (platform == Platform.Windows) { + _libMpvDll = LoadLibrary (_libMpvPath); // "mpv-1.dll"); // The dll is included in the DEV builds by lachs0r: https://mpv.srsfckn.biz/ + } else if (platform == Platform.Linux) { + _libMpvDll = dlopen (_libMpvPath, RTLD_NOW); //("/usr/lib/x86_64-linux-gnu/libmpv.so.1", RTLD_NOW); + } else { + throw new NotImplementedException (); + } + + + _mpvCreate = (MpvCreate)GetDllType (typeof(MpvCreate), "mpv_create"); + _mpvInitialize = (MpvInitialize)GetDllType (typeof(MpvInitialize), "mpv_initialize"); + _mpvTerminateDestroy = (MpvTerminateDestroy)GetDllType (typeof(MpvTerminateDestroy), "mpv_terminate_destroy"); + _mpvCommand = (MpvCommand)GetDllType (typeof(MpvCommand), "mpv_command"); + _mpvSetOption = (MpvSetOption)GetDllType (typeof(MpvSetOption), "mpv_set_option"); + _mpvSetOptionString = (MpvSetOptionString)GetDllType (typeof(MpvSetOptionString), "mpv_set_option_string"); + _mpvGetPropertyString = (MpvGetPropertystring)GetDllType (typeof(MpvGetPropertystring), "mpv_get_property"); + _mpvSetProperty = (MpvSetProperty)GetDllType (typeof(MpvSetProperty), "mpv_set_property"); + _mpvFree = (MpvFree)GetDllType (typeof(MpvFree), "mpv_free"); + } + + // ******************************************* + + private long _wid; + private bool _fullscreen; + + // Current position in seconds in stream. + private float _currentPosition = 0; + + // The total length that the video is in seconds. + private int _totalTime = 0; + + private string currentFilePath; + private string _libMpvPath; + + + public event MplayerEventHandler VideoExited; + /// + /// This event is the most accurate way to get the current position of the current playing file. + /// Whenever the postion changes this event will notify that the positon has changed with the value + /// being the new position (seconds into the file). + /// + public event MplayerEventHandler CurrentPosition; + + private System.Timers.Timer _currentPostionTimer; + + + public MpvPlayer (long wid) + : this (wid, "") + { + } + + public MpvPlayer (long wid, string libMpvPath) + : this (wid, libMpvPath, false, TimeSpan.FromMilliseconds (1000)) + { + } + + /// + /// Create a new instance of mplayer class. + /// + /// Window ID that mplayer should attach itself + /// The full filepath to libmpv. + /// If true mplayer will immediately be loaded and you should not attempt to + /// play any files until MplayerRunning is true. + /// Interval of periodical position updates + public MpvPlayer (long wid, string libMpvPath, bool loadMplayer, TimeSpan positionUpdateInterval) + { + System.Environment.SetEnvironmentVariable ("LC_NUMERIC", "C"); + + this._wid = wid; + this._fullscreen = false; + this.MplayerRunning = false; + this._libMpvPath = libMpvPath; + this.CurrentStatus = MediaStatus.Stopped; + + // This timer will send an event every second with the current video postion when video + // is in play mode. + this._currentPostionTimer = new System.Timers.Timer (positionUpdateInterval.TotalMilliseconds); + this._currentPostionTimer.Elapsed += new ElapsedEventHandler (_currentPostionTimer_Elapsed); + this._currentPostionTimer.Enabled = false; + + if (loadMplayer) { + Action caller = new Action (InitializeMplayer); + caller.BeginInvoke (null, null); + } + + } + + /// + /// Cleanup resources. Currently this means that mplayer is closed if it is still running. + /// + /// Alternatively call the Dispose method. + ~MpvPlayer () + { + // Cleanup + + if (_mpvHandle != IntPtr.Zero) { + _mpvTerminateDestroy (_mpvHandle); + } + + } + + bool disposed = false; + + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + protected virtual void Dispose (bool disposing) + { + if (disposed) + return; + + if (disposing) { + if (_mpvHandle != IntPtr.Zero) { + _mpvTerminateDestroy (_mpvHandle); + } + } + + disposed = true; + } + + /// + /// Is mplayer alreadying running? True or False. + /// + public bool MplayerRunning { get; set; } + + /// + /// The current status of the player. + /// + public MediaStatus CurrentStatus { get; set; } + + public bool HardwareAccelerated { get; set; } + + + private void InitializeMplayer () + { + this._currentPostionTimer.Start (); + this.MplayerRunning = true; + } + + /// + /// Load and start playing a video. + /// + /// + public void Play (string filePath) + { + LoadFile (filePath); + + if (_mpvHandle == IntPtr.Zero) { + return; + } + + var bytes = GetUtf8Bytes ("no"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("pause"), MpvFormatString, ref bytes); + + this.CurrentStatus = MediaStatus.Playing; + } + + + + private void DoMpvCommand (params string[] args) + { + // https://github.com/mpv-player/mpv/blob/master/DOCS/man/input.rst + + IntPtr[] byteArrayPointers; + var mainPtr = AllocateUtf8IntPtrArrayWithSentinel (args, out byteArrayPointers); + _mpvCommand (_mpvHandle, mainPtr); + foreach (var ptr in byteArrayPointers) { + Marshal.FreeHGlobal (ptr); + } + Marshal.FreeHGlobal (mainPtr); + } + + public static IntPtr AllocateUtf8IntPtrArrayWithSentinel (string[] arr, out IntPtr[] byteArrayPointers) + { + int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel) + byteArrayPointers = new IntPtr [numberOfStrings]; + IntPtr rootPointer = Marshal.AllocCoTaskMem (IntPtr.Size * numberOfStrings); + for (int index = 0; index < arr.Length; index++) { + var bytes = GetUtf8Bytes (arr [index]); + IntPtr unmanagedPointer = Marshal.AllocHGlobal (bytes.Length); + Marshal.Copy (bytes, 0, unmanagedPointer, bytes.Length); + byteArrayPointers [index] = unmanagedPointer; + } + Marshal.Copy (byteArrayPointers, 0, rootPointer, numberOfStrings); + return rootPointer; + } + + + private static byte [] GetUtf8Bytes (string s) + { + return Encoding.UTF8.GetBytes (s + "\0"); + } + + /// + /// Starts a new video/audio file immediatly. Requires that Play has been called. + /// + /// string + public void LoadFile (string filePath) + { + this.currentFilePath = filePath; + + if (_mpvHandle != IntPtr.Zero) + _mpvTerminateDestroy (_mpvHandle); + + LoadMpvDynamic (); + if (_libMpvDll == IntPtr.Zero) + return; + + _mpvHandle = _mpvCreate.Invoke (); + if (_mpvHandle == IntPtr.Zero) + return; + + _mpvInitialize.Invoke (_mpvHandle); + _mpvSetOptionString (_mpvHandle, GetUtf8Bytes ("keep-open"), GetUtf8Bytes ("always")); + int mpvFormatInt64 = 4; + _mpvSetOption (_mpvHandle, GetUtf8Bytes ("wid"), mpvFormatInt64, ref _wid); + DoMpvCommand ("loadfile", filePath); + + this.LoadCurrentPlayingFileLength (); + } + + public void SetHandle (long wid) + { + _wid = wid; + //int mpvFormatInt64 = 4; + //_mpvSetOption (_mpvHandle, GetUtf8Bytes ("wid"), mpvFormatInt64, ref _wid); + } + + /// + /// Prepare filepaths to be used witht the loadfile command. + /// + /// + /// + /// + /// For some reason it strips the DirectorySeperatorChar so we double it up here. + /// + private string PrepareFilePath (string filePath) + { + string preparedPath = filePath.Replace ("" + System.IO.Path.DirectorySeparatorChar, "" + System.IO.Path.DirectorySeparatorChar + System.IO.Path.DirectorySeparatorChar); + + return preparedPath; + } + + + /// + /// Move to a new position in the video. + /// + /// Seconds. The position to seek move to. + public void MovePosition (int timePosition) + { + if (_mpvHandle == IntPtr.Zero) { + return; + } + + DoMpvCommand ("seek", timePosition.ToString (CultureInfo.InvariantCulture), "absolute"); + } + + + + /// + /// Seek a new postion. + /// Seek to some place in the movie. + /// Seek.Relative is a relative seek of +/- value seconds (default). + /// Seek.Percentage is a seek to value % in the movie. + /// Seek.Absolute is a seek to an absolute position of value seconds. + /// + /// + /// + public void Seek (int value, Seek type) + { + if (_mpvHandle == IntPtr.Zero) { + return; + } + + DoMpvCommand ("seek", value.ToString (CultureInfo.InvariantCulture), type.ToString ().ToLower ()); + } + + public void SetSize (int width, int height) + { + if (this.CurrentStatus != MediaStatus.Playing) { + return; + } + + if (_mpvHandle == IntPtr.Zero) { + return; + } + + var widthBytes = GetUtf8Bytes (width.ToString (CultureInfo.InvariantCulture)); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("width"), MpvFormatString, ref widthBytes); + + var heightBytes = GetUtf8Bytes (height.ToString (CultureInfo.InvariantCulture)); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("height"), MpvFormatString, ref heightBytes); + } + + /// + /// Pause the current video. If paused it will unpause. + /// + public void Pause () + { + if (this.CurrentStatus != MediaStatus.Playing && this.CurrentStatus != MediaStatus.Paused) { + return; + } + + try { + if (_mpvHandle == IntPtr.Zero) { + return; + } + + var bytes = GetUtf8Bytes ("yes"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("pause"), MpvFormatString, ref bytes); + + } catch (Exception ex) { + Logging.Instance.WriteLine (ex); + return; + } + + if (this.CurrentStatus == MediaStatus.Paused) { + this.CurrentStatus = MediaStatus.Playing; + } else { + this.CurrentStatus = MediaStatus.Paused; + } + } + + /// + /// Stop the current video. + /// + public void Stop () + { + if (this.CurrentStatus != MediaStatus.Stopped) { + Pause (); + Seek (0, LibMPlayerCommon.Seek.Absolute); + } + this.CurrentStatus = MediaStatus.Stopped; + } + + + /// + /// Retrieves the number of seconds of the current playing video. + /// + public int CurrentPlayingFileLength () + { + return this._totalTime; + } + // Sets in motions events to set this._totalTime. Is called as soon as the video starts. + private void LoadCurrentPlayingFileLength () + { + var lpBuffer = IntPtr.Zero; + _mpvGetPropertyString (_mpvHandle, GetUtf8Bytes ("duration"), MpvFormatString, ref lpBuffer); + + var duration = Marshal.PtrToStringAnsi (lpBuffer); + _mpvFree (lpBuffer); + + this._totalTime = Globals.IntParse (duration); + } + + private void _currentPostionTimer_Elapsed (object sender, ElapsedEventArgs e) + { + if (this.CurrentStatus == MediaStatus.Playing) { + var lpBuffer = IntPtr.Zero; + _mpvGetPropertyString (_mpvHandle, GetUtf8Bytes ("time-pos"), MpvFormatString, ref lpBuffer); + + var pos = Marshal.PtrToStringAnsi (lpBuffer); + _mpvFree (lpBuffer); + + this._currentPosition = Globals.FloatParse (pos); + + this.CurrentPosition?.Invoke (this, new MplayerEvent (this._currentPosition)); + } + } + + + /// + /// Get if the video is full is screen or not. Set video to play in fullscreen. + /// + public bool FullScreen { + get { return _fullscreen; } + set { + _fullscreen = value; + + var bytes = _fullscreen == true ? GetUtf8Bytes ("yes") : GetUtf8Bytes ("no"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("fullscreen"), MpvFormatString, ref bytes); + } + } + + /// + /// Toggle Fullscreen. + /// + public void ToggleFullScreen () + { + if (this.MplayerRunning) { + var lpBuffer = IntPtr.Zero; + _mpvGetPropertyString (_mpvHandle, GetUtf8Bytes ("fullscreen"), MpvFormatString, ref lpBuffer); + + var isFullScreen = Marshal.PtrToStringAnsi (lpBuffer); + _mpvFree (lpBuffer); + + if (isFullScreen == "yes") { + var bytes = GetUtf8Bytes ("no"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("fullscreen"), MpvFormatString, ref bytes); + } else { + var bytes = GetUtf8Bytes ("yes"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("fullscreen"), MpvFormatString, ref bytes); + } + + } + } + + /// + /// Toggle Mute. + /// + public void Mute () + { + var lpBuffer = IntPtr.Zero; + _mpvGetPropertyString (_mpvHandle, GetUtf8Bytes ("ao-mute"), MpvFormatString, ref lpBuffer); + + var isMuted = Marshal.PtrToStringAnsi (lpBuffer); + _mpvFree (lpBuffer); + + if (isMuted == "yes") { + var bytes = GetUtf8Bytes ("no"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("ao-mute"), MpvFormatString, ref bytes); + } else { + var bytes = GetUtf8Bytes ("yes"); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("ao-mute"), MpvFormatString, ref bytes); + } + + } + + + /// + /// Accepts a volume value of 0 - 100. + /// + /// + public void Volume (int volume) + { + Debug.Assert (volume >= 0 && volume <= 100); + + + var bytes = GetUtf8Bytes (volume.ToString ()); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("ao-volume"), MpvFormatString, ref bytes); + + } + + public void SwitchAudioTrack (int track) + { + var bytes = GetUtf8Bytes (track.ToString ()); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("audio-reload"), MpvFormatString, ref bytes); + } + + public void SwitchSubtitle (int sub) + { + var bytes = GetUtf8Bytes (sub.ToString ()); + _mpvSetProperty (_mpvHandle, GetUtf8Bytes ("sub-reload"), MpvFormatString, ref bytes); + } + + } +} diff --git a/LibMPlayerCommon/PlatformCheck.cs b/LibMPlayerCommon/PlatformCheck.cs new file mode 100644 index 0000000..8f5b7f0 --- /dev/null +++ b/LibMPlayerCommon/PlatformCheck.cs @@ -0,0 +1,43 @@ +using System; + +namespace LibMPlayerCommon +{ + public enum Platform + { + Windows, + Linux, + Mac + } + + public static class PlatformCheck + { + + public static Platform RunningPlatform() + { + switch (Environment.OSVersion.Platform) + { + case PlatformID.Unix: + // Well, there are chances MacOSX is reported as Unix instead of MacOSX. + // Instead of platform check, we'll do a feature checks (Mac specific root folders) + if (System.IO.Directory.Exists("/Applications") + & System.IO.Directory.Exists("/System") + & System.IO.Directory.Exists("/Users") + & System.IO.Directory.Exists("/Volumes")) + { + return Platform.Mac; + } + else + { + return Platform.Linux; + } + + case PlatformID.MacOSX: + return Platform.Mac; + default: + return Platform.Windows; + } + } + + } +} + diff --git a/LibMPlayerCommon/Player.cs b/LibMPlayerCommon/Player.cs index 6b52bfb..3e22637 100644 --- a/LibMPlayerCommon/Player.cs +++ b/LibMPlayerCommon/Player.cs @@ -7,14 +7,26 @@ public interface Player event MplayerEventHandler VideoExited; event MplayerEventHandler CurrentPosition; + bool FullScreen { get; set; } + MediaStatus CurrentStatus { get; set; } + void ToggleFullScreen(); + void Stop(); void Pause(); void Mute(); + /// + /// The window id that the video will play in + /// + /// Wid. + void SetHandle(long wid); + + void MovePosition(int timePosition); + void Play(string filePath); void Seek(int value, Seek type); @@ -26,6 +38,9 @@ public interface Player void SwitchSubtitle(int sub); int CurrentPlayingFileLength(); + + void Volume(int volume); + } } diff --git a/LibMPlayerCommon/PlayerFactory.cs b/LibMPlayerCommon/PlayerFactory.cs new file mode 100644 index 0000000..c456f1b --- /dev/null +++ b/LibMPlayerCommon/PlayerFactory.cs @@ -0,0 +1,57 @@ +using System; + +namespace LibMPlayerCommon +{ + public static class PlayerFactory + { + /// + /// Attempt to auto detect prefered backends. + /// + /// Handle. + /// Path to mplayer executable or mpv library + public static Player Get(long handle, string path) + { + if (PlatformCheck.RunningPlatform() == Platform.Windows) + { + return PlayerFactory.Windows(handle, path); + } + else if (PlatformCheck.RunningPlatform() == Platform.Linux) + { + return PlayerFactory.Linux(handle, path); + } + else + { + throw new NotImplementedException(); + } + } + + private static LibMPlayerCommon.Player Windows(long handle, string path) + { + if (path.Contains("mplayer")) + { + return new MPlayer(handle, MplayerBackends.Direct3D, path); + } + else if (path.Contains("libmpv")) + { + return new MpvPlayer(handle, path); + } + + return null; + } + + private static LibMPlayerCommon.Player Linux(long handle, string path) + { + if (path.Contains("mplayer")) + { + return new MPlayer(handle, MplayerBackends.XV, path); + } + else if (path.Contains("libmpv")) + { + return new MpvPlayer(handle, path); + } + + return null; + } + } +} + diff --git a/LibMPlayerWinform/WinFormMPlayerControl.cs b/LibMPlayerWinform/WinFormMPlayerControl.cs index 3610253..b767055 100644 --- a/LibMPlayerWinform/WinFormMPlayerControl.cs +++ b/LibMPlayerWinform/WinFormMPlayerControl.cs @@ -12,13 +12,28 @@ namespace LibMPlayerWinform { public partial class WinFormMPlayerControl : UserControl { - MPlayer _play; + Player _play; public WinFormMPlayerControl() { InitializeComponent(); } + public WinFormMPlayerControl(Player play) + { + InitializeComponent(); + + _play = play; + } + + public long Handle + { + get + { + return this.panelVideo.Handle.ToInt64(); + } + } + private void buttonStop_Click(object sender, EventArgs e) { if (_play != null) @@ -34,9 +49,7 @@ private void buttonPlay_Click(object sender, EventArgs e) _play.Stop(); } - int handle = (int)this.panelVideo.Handle; - - if (System.IO.File.Exists(MPlayerPath) == false) + if (System.IO.File.Exists(MPlayerPath) == false && _play is LibMPlayerCommon.MPlayer) { throw new System.IO.FileNotFoundException("File not found", MPlayerPath); } @@ -46,11 +59,15 @@ private void buttonPlay_Click(object sender, EventArgs e) throw new System.IO.FileNotFoundException("File not found", VideoPath); } - _play = new MPlayer(handle, MplayerBackends.Direct3D, MPlayerPath); + if (_play == null) + { + //_play = new MPlayer(Handle, MplayerBackends.Direct3D, MPlayerPath); + } _play.Play(VideoPath); } public string MPlayerPath { get; set; } + public string VideoPath { get; set; } } } diff --git a/MPlayerControl.sln b/MPlayerControl.sln index b779cbb..a4ceb7a 100644 --- a/MPlayerControl.sln +++ b/MPlayerControl.sln @@ -37,8 +37,8 @@ Global {5D3616D0-160D-4601-AB67-E1ED9111C676}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5D3616D0-160D-4601-AB67-E1ED9111C676}.Release|x86.ActiveCfg = Release|x86 {5D3616D0-160D-4601-AB67-E1ED9111C676}.Release|x86.Build.0 = Release|x86 - {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|Any CPU.ActiveCfg = Debug|x86 - {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|Any CPU.Build.0 = Debug|x86 + {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|Mixed Platforms.Build.0 = Debug|x86 {6B5C1B79-1CDF-409C-8CAF-B3D2F25E27B5}.Debug|x86.ActiveCfg = Debug|x86 @@ -97,8 +97,8 @@ Global {F8A7EE08-6BEA-4CB4-A0BA-22169133289A}.Release|Mixed Platforms.Build.0 = Release|Any CPU {F8A7EE08-6BEA-4CB4-A0BA-22169133289A}.Release|x86.ActiveCfg = Release|x86 {F8A7EE08-6BEA-4CB4-A0BA-22169133289A}.Release|x86.Build.0 = Release|x86 - {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|Any CPU.ActiveCfg = Debug|x86 - {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|Any CPU.Build.0 = Debug|x86 + {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|Any CPU.Build.0 = Debug|Any CPU {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|Mixed Platforms.Build.0 = Debug|x86 {FAF8DCB0-403C-4120-A70C-89DD942564A9}.Debug|x86.ActiveCfg = Debug|x86 diff --git a/MediaPlayer/Player.cs b/MediaPlayer/Player.cs index 7db06bd..c878a90 100644 --- a/MediaPlayer/Player.cs +++ b/MediaPlayer/Player.cs @@ -97,7 +97,7 @@ private void MainForm_Load(object sender, EventArgs e) } - this._play = new MPlayer(panelVideo.Handle.ToInt32(), backend, MediaPlayer.Properties.Settings.Default.MPlayerPath); + this._play = new MPlayer(panelVideo.Handle.ToInt64(), backend, MediaPlayer.Properties.Settings.Default.MPlayerPath); this._play.VideoExited += new MplayerEventHandler(play_VideoExited); this._play.CurrentPosition += new MplayerEventHandler(_play_CurrentPosition);