PageRenderTime 42ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Multimedia/Vlc/VlcVideo.cs

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