You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
8.9 KiB

  1. #if NET40 || NET461
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. using System.Media;
  7. using System.IO;
  8. using System.Security.Permissions;
  9. namespace Apewer.Internals.Interop
  10. {
  11. /// <summary>MCI。</summary>
  12. [HostProtection(SecurityAction.LinkDemand, Resources = HostProtectionResource.ExternalProcessMgmt)]
  13. [System.Security.SecuritySafeCritical]
  14. internal sealed class Mci
  15. {
  16. private static string MciSend(string argCommand)
  17. {
  18. string rs = "";
  19. WinMM.mciSendString(argCommand, ref rs, 0, IntPtr.Zero);
  20. return rs;
  21. }
  22. /// <summary>播放音频文件。</summary>
  23. /// <param name="argPath">音频文件的路径。</param>
  24. public static bool PlayByCommand(string argPath)
  25. {
  26. return PlayByCommand(argPath, "audioplay");
  27. }
  28. /// <summary>播放音频文件。</summary>
  29. /// <param name="argPath">音频文件的路径。</param>
  30. /// <param name="argAlias">别名。</param>
  31. public static bool PlayByCommand(string argPath, string argAlias = "audioplay")
  32. {
  33. if (!string.IsNullOrEmpty(argPath))
  34. {
  35. if (File.Exists(argPath))
  36. {
  37. string alias = argAlias;
  38. if (string.IsNullOrEmpty(argAlias))
  39. {
  40. alias = Guid.NewGuid().ToString("n");
  41. // valias = Guid.NewGuid().ToString().ToLower().Replace("-", "");
  42. }
  43. MciSend("open \"" + argPath + "\" alias " + alias + "");
  44. MciSend("play " + alias);
  45. return true;
  46. }
  47. }
  48. return false;
  49. }
  50. /// <summary>播放音频文件。</summary>
  51. /// <param name="argPath">音频文件的路径。</param>
  52. public static bool PlayBySnd(string argPath)
  53. {
  54. if (File.Exists(argPath))
  55. {
  56. WinMM.sndPlaySound(argPath, (long)(Constant.SND_ASYNC));
  57. return true;
  58. }
  59. return false;
  60. }
  61. /// <summary>暂停指定别名的音频实例。</summary>
  62. public static void Pause()
  63. {
  64. Pause("audioplay");
  65. }
  66. /// <summary>暂停指定别名的音频实例。</summary>
  67. /// <param name="argAlias">别名。</param>
  68. public static void Pause(string argAlias)
  69. {
  70. MciSend("pause " + argAlias);
  71. }
  72. /// <summary>停止指定别名的音频实例。</summary>
  73. public static void Stop()
  74. {
  75. Stop("audioplay");
  76. }
  77. /// <summary>停止指定别名的音频实例。</summary>
  78. /// <param name="argAlias">别名。</param>
  79. public static void Stop(string argAlias)
  80. {
  81. MciSend("stop " + argAlias);
  82. }
  83. /// <summary>停止并关闭指定别名的音频实例。</summary>
  84. public static void Close()
  85. {
  86. Close("audioplay");
  87. }
  88. /// <summary>停止并关闭指定别名的音频实例。</summary>
  89. /// <param name="argAlias">别名。</param>
  90. public static void Close(string argAlias)
  91. {
  92. MciSend("stop " + argAlias);
  93. MciSend("close " + argAlias);
  94. }
  95. /// <summary>设置实例的音量。</summary>
  96. /// <param name="argValue">音量值(0 ~ 1000)。</param>
  97. public static void Volume(int argValue)
  98. {
  99. Volume(argValue, "audioplay");
  100. }
  101. /// <summary>设置实例的音量。</summary>
  102. /// <param name="argAlias">别名。</param>
  103. /// <param name="argValue">音量值(0 ~ 1000)。</param>
  104. public static void Volume(int argValue, string argAlias)
  105. {
  106. int volume = argValue;
  107. if (volume < 0) volume = 0;
  108. if (volume < 1000) volume = 1000;
  109. MciSend("setaudio " + argAlias + " volume to " + volume.ToString());
  110. }
  111. /// <summary>获取实例的长度。</summary>
  112. public static int Length()
  113. {
  114. return Length("audioplay");
  115. }
  116. /// <summary>获取实例的长度。</summary>
  117. /// <param name="argAlias">别名。</param>
  118. public static int Length(string argAlias)
  119. {
  120. string rs = "";
  121. WinMM.mciSendString("status " + argAlias + " length", ref rs, 64, IntPtr.Zero);
  122. return Convert.ToInt32(rs);
  123. }
  124. /// <summary>获取实例的当前播放进度。</summary>
  125. public static int Position()
  126. {
  127. return Position("audioplay");
  128. }
  129. /// <summary>获取实例的当前播放进度。</summary>
  130. /// <param name="argAlias">别名。</param>
  131. public static int Position(string argAlias)
  132. {
  133. string rs = "";
  134. WinMM.mciSendString("status " + argAlias + " position", ref rs, 64, IntPtr.Zero);
  135. return Convert.ToInt32(rs);
  136. }
  137. /// <summary>设置播放实例的播放进度。</summary>
  138. /// <param name="argPosition">目标位置。</param>
  139. public static void Seek(int argPosition)
  140. {
  141. Seek("audioplay", argPosition, false);
  142. }
  143. /// <summary>设置播放实例的播放进度。</summary>
  144. /// <param name="argLast">设置播放进度为末尾,若为 True 则忽略 Position 参数。</param>
  145. public static void Seek(bool argLast)
  146. {
  147. Seek("audioplay", 0, argLast);
  148. }
  149. /// <summary>设置播放实例的播放进度。</summary>
  150. /// <param name="argAlias">别名。</param>
  151. /// <param name="argPosition">目标位置。</param>
  152. public static void Seek(string argAlias, int argPosition)
  153. {
  154. Seek(argAlias, argPosition, false);
  155. }
  156. /// <summary>设置播放实例的播放进度。</summary>
  157. /// <param name="argAlias">别名。</param>
  158. /// <param name="argLast">设置播放进度为末尾。</param>
  159. public static void Seek(string argAlias, bool argLast)
  160. {
  161. Seek(argAlias, 0, argLast);
  162. }
  163. /// <summary>设置播放实例的播放进度。</summary>
  164. /// <param name="argAlias">别名。</param>
  165. /// <param name="argPosition">目标位置。</param>
  166. /// <param name="argLast">设置播放进度为末尾,若为 True 则忽略 Position 参数。</param>
  167. public static void Seek(string argAlias, int argPosition, bool argLast)
  168. {
  169. if (argLast)
  170. {
  171. MciSend("seek " + argAlias + " to end");
  172. }
  173. else
  174. {
  175. if (argPosition == 0) MciSend("seek " + argAlias + " to start");
  176. else MciSend("seek " + argAlias + " to " + argPosition.ToString());
  177. }
  178. MciSend("play " + argAlias);
  179. }
  180. /// <summary>开始录音,若实例已存在则关闭。</summary>
  181. public static void Record()
  182. {
  183. Record("audiorecord", true);
  184. }
  185. /// <summary>开始录音,若实例已存在则关闭。</summary>
  186. /// <param name="argAlias">别名。</param>
  187. public static void Record(string argAlias)
  188. {
  189. Record(argAlias, true);
  190. }
  191. /// <summary>开始录音。</summary>
  192. /// <param name="argAlias">别名。</param>
  193. /// <param name="argClose">在录音前,若实例已存在则关闭。</param>
  194. public static void Record(string argAlias, bool argClose)
  195. {
  196. if (argClose) Close(argAlias);
  197. MciSend("set wave bitpersample 16");
  198. MciSend("set wave samplespersec 44100");
  199. MciSend("set wave channels 2");
  200. MciSend("set wave format tag pcm");
  201. MciSend("open new type waveaudio alias " + argAlias);
  202. MciSend("record " + argAlias);
  203. }
  204. /// <summary>保存录音。</summary>
  205. /// <param name="argPath">文件路径。</param>
  206. public static bool Save(string argPath)
  207. {
  208. return Save(argPath, "audiorecord");
  209. }
  210. /// <summary>保存录音。</summary>
  211. /// <param name="argPath">文件路径。</param>
  212. /// <param name="argAlias">别名。</param>
  213. public static bool Save(string argPath, string argAlias)
  214. {
  215. Stop(argAlias);
  216. if (string.IsNullOrEmpty(argPath)) return false;
  217. try
  218. {
  219. if (File.Exists(argPath)) File.Delete(argPath);
  220. if (File.Exists(argPath)) return false;
  221. else MciSend("save " + argAlias + " \"" + argPath + "\"");
  222. Close(argAlias);
  223. return File.Exists(argPath);
  224. }
  225. catch
  226. {
  227. Close(argAlias);
  228. return false;
  229. }
  230. }
  231. }
  232. }
  233. #endif