PageRenderTime 30ms CodeModel.GetById 17ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/Multimedia/Vlc/VlcVideo.cs

#
C# | 247 lines | 158 code | 21 blank | 68 comment | 16 complexity | 735eda75204025eabdc6825bf0b7cd81 MD5 | raw file
  1using System;
  2using System.IO;
  3using Delta.Engine;
  4using Delta.Multimedia.Vlc.LibVlc;
  5using Delta.Utilities;
  6using Delta.Utilities.Datatypes;
  7
  8namespace Delta.Multimedia.Vlc
  9{
 10	/// <summary>
 11	/// Video class using vlc library to natively play the video. Note: Needs
 12	/// native libvlc.dll, libvlccore.dll file, plus plugins for the video
 13	/// format (see \External\Vlc\plugins).
 14	/// </summary>
 15	public class VlcVideo : Video
 16	{
 17		#region TimePlayed (Public)
 18		/// <summary>
 19		/// Return the time in seconds how long this video already played.
 20		/// </summary>
 21		public override float TimePlayed
 22		{
 23			get
 24			{
 25				return player == null
 26				       	? 0f
 27				       	: player.VideoPosition * 0.001f;
 28			}
 29		}
 30		#endregion
 31
 32		#region Private
 33
 34		#region vlcManager (Private)
 35		/// <summary>
 36		/// Vlc manager instance.
 37		/// </summary>
 38		private static VlcInstance vlcManager;
 39		#endregion
 40
 41		#region player (Private)
 42		/// <summary>
 43		/// Controller of the current video displayer, it provides basic function
 44		/// for handling the video player such as playing or stopping.
 45		/// </summary>
 46		private VlcMediaPlayer player;
 47		#endregion
 48
 49		#region nativeVideoData (Private)
 50		/// <summary>
 51		/// Video data
 52		/// </summary>
 53		private VlcMedia nativeVideoData;
 54		#endregion
 55
 56		#endregion
 57
 58		#region Constructors
 59		/// <summary>
 60		/// Initialize vlcManager for all VlcVideo instances!
 61		/// </summary>
 62		static VlcVideo()
 63		{
 64			// Attach to the application closing for accurately disposing the
 65			// VLC manager instance.
 66			Application.ApplicationClosing += delegate
 67			{
 68				if (vlcManager != null)
 69				{
 70					vlcManager.Dispose();
 71					vlcManager = null;
 72				}
 73			};
 74
 75			try
 76			{
 77				string currentPath = Directory.GetCurrentDirectory();
 78				string[] args = new[]
 79				{
 80					"-I",
 81					"dummy",
 82					"--ignore-config",
 83					"--plugin-path=" + Path.Combine(currentPath, "plugins"),
 84				};
 85				vlcManager = new VlcInstance(args);
 86			}
 87			catch (Exception ex)
 88			{
 89				Log.Warning("Failed to initialize the vlc system (unable to " +
 90				            "play videos), because: " + ex);
 91			}
 92		}
 93
 94		/// <summary>
 95		/// Create a VLC video.
 96		/// </summary>
 97		/// <param name="contentName">The name of the content file to load.</param>
 98		public VlcVideo(string contentName)
 99			: base(contentName)
100		{
101		}
102		#endregion
103
104		#region Methods (Private)
105
106		#region LoadNativeData
107		/// <summary>
108		/// Load the native content data.
109		/// </summary>
110		/// <param name="filename">Filename</param>
111		/// <returns>True if loading succeeded, otherwise False.</returns>
112		protected override bool LoadNativeData(string filename)
113		{
114			// We can only continue if the VlcManager could be created
115			if (vlcManager != null)
116			{
117				nativeVideoData = new VlcMedia(vlcManager, filename);
118				return true;
119			}
120			return false;
121		}
122		#endregion
123
124		#region PlayNative
125		/// <summary>
126		/// Native implementation of playing the native video data.
127		/// Note: This method will only be called, if the video is loaded.
128		/// </summary>
129		protected override void PlayNative()
130		{
131			if (player != null)
132			{
133				StopNative();
134			}
135
136			player = new VlcMediaPlayer(nativeVideoData);
137			player.Drawable = Application.Window.ViewportHandle;
138			player.Play();
139		}
140		#endregion
141
142		#region UpdateNative
143		/// <summary>
144		/// Native implementation of update, which simply checks the actual
145		/// video state and updates the base classes state.
146		/// </summary>
147		protected override void UpdateNative()
148		{
149			VlcMediaState state = nativeVideoData.State;
150			switch (state)
151			{
152				case VlcMediaState.Paused:
153					State = MediaState.Paused;
154					break;
155
156				case VlcMediaState.Opening:
157				case VlcMediaState.NothingSpecial:
158				case VlcMediaState.Buffering:
159				case VlcMediaState.Playing:
160					State = MediaState.Playing;
161					break;
162
163				case VlcMediaState.Error:
164				case VlcMediaState.Stopped:
165				case VlcMediaState.Ended:
166					// Only stop this and put the state to Stopped if we were playing
167					// before, because sometimes the player still needs to initialize
168					// the media (Buffering, etc.) but this happens async and our
169					// engine is already in this update method, the state of the media
170					// is Stopped or Ended from the last playback, then it will break
171					// the playback because of going into this switch case.
172					if (State != MediaState.Stopped)
173					{
174						StopNative();
175						State = MediaState.Stopped;
176					}
177					break;
178			} // switch
179		}
180		#endregion
181
182		#region DrawNative
183		/// <summary>
184		/// Native implementation of drawing the native video data.
185		/// Note: This method will only be called, if the video is loaded.
186		/// </summary>
187		/// <param name="drawArea">Draw area</param>
188		protected override void DrawNative(Rectangle drawArea)
189		{
190		}
191		#endregion
192
193		#region StopNative
194		/// <summary>
195		/// Stops the native playing video data.
196		/// Note: This method will only be called, if the video is currently played.
197		/// </summary>
198		protected override void StopNative()
199		{
200			// Just stop and dispose the player instead (we can recreate it)
201			if (player != null)
202			{
203				// This never ends when we quit the app while the video is playing,
204				// so we need to call Stop first!
205				player.Stop();
206				player.Dispose();
207				player = null;
208			}
209		}
210		#endregion
211
212		#region DisposeNativeData
213		/// <summary>
214		/// Dispose the native data object.
215		/// </summary>
216		protected override void DisposeNativeData()
217		{
218			if (nativeVideoData != null)
219			{
220				nativeVideoData.Dispose();
221				nativeVideoData = null;
222			}
223			if (player != null)
224			{
225				// This never ends when we quit the app while the video is playing,
226				// so we need to call Stop first!
227				player.Stop();
228				player.Dispose();
229				player = null;
230			}
231		}
232		#endregion
233
234		#region SetVolume
235		/// <summary>
236		/// Set the volume.
237		/// </summary>
238		/// <param name="setVolume">Volume value.</param>
239		protected override void SetVolume(float setVolume)
240		{
241			player.Volume = (int)(setVolume * 100);
242		}
243		#endregion
244
245		#endregion
246	}
247}