PageRenderTime 193ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/WebPages/Source/Microsoft.Web.Helpers/Video.cs

#
C# | 298 lines | 254 code | 34 blank | 10 comment | 39 complexity | 6d2bcdf5e67ba1d6898b875e15a8e33d MD5 | raw file
Possible License(s): Apache-2.0
  1. namespace Microsoft.Web.Helpers {
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Diagnostics;
  6. using System.Diagnostics.CodeAnalysis;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Web;
  11. using Microsoft.Internal.Web.Utils;
  12. using Microsoft.Web.Helpers.Resources;
  13. using System.Web.WebPages;
  14. public static class Video {
  15. private const string FlashCab =
  16. "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab";
  17. private const string FlashClassId = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000";
  18. private const string FlashMimeType = "application/x-shockwave-flash";
  19. private const string MediaPlayerClassId = "clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6";
  20. private const string MediaPlayerMimeType = "application/x-mplayer2";
  21. private const string OleMimeType = "application/x-oleobject";
  22. private const string SilverlightMimeType = "application/x-silverlight-2";
  23. // These attributes can't be specified using anonymous objects (either because they are available as separate arguments or because
  24. // they don't make sense in the context of the helper).
  25. private static string[] GlobalBlacklist = new string[] { "width", "height", "type", "data", "classid", "codebase" };
  26. private static string[] MediaPlayerBlacklist = new string[] { "autoStart", "playCount", "uiMode", "stretchToFit", "enableContextMenu", "mute", "volume", "baseURL" };
  27. private static string[] SilverlightBlacklist = new string[] { "background", "initparams", "minruntimeversion", "autoUpgrade" };
  28. private static string[] FlashBlacklist = new string[] { "play", "loop", "menu", "bgColor", "quality", "scale", "wmode", "base" };
  29. private static VirtualPathUtilityWrapper _pathUtility = new VirtualPathUtilityWrapper();
  30. #if CODE_COVERAGE
  31. [ExcludeFromCodeCoverage]
  32. #endif
  33. private static HttpContextBase HttpContext {
  34. get {
  35. var httpContext = System.Web.HttpContext.Current;
  36. return httpContext == null ? null : new HttpContextWrapper(httpContext);
  37. }
  38. }
  39. // see: http://kb2.adobe.com/cps/127/tn_12701.html
  40. #if CODE_COVERAGE
  41. [ExcludeFromCodeCoverage]
  42. #endif
  43. [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "10#",
  44. Justification = "string parameter passed to flash in object tag")]
  45. public static HelperResult Flash(string path, string width = null, string height = null,
  46. bool play = true, bool loop = true, bool menu = true, string bgColor = null,
  47. string quality = null, string scale = null, string windowMode = null, string baseUrl = null,
  48. string version = null, object options = null, object htmlAttributes = null, string embedName = null) {
  49. return Flash(HttpContext, _pathUtility, path, width, height, play, loop, menu, bgColor,
  50. quality, scale, windowMode, baseUrl, version, options, htmlAttributes, embedName);
  51. }
  52. // see: http://msdn.microsoft.com/en-us/library/aa392321
  53. #if CODE_COVERAGE
  54. [ExcludeFromCodeCoverage]
  55. #endif
  56. [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "10#",
  57. Justification = "string parameter passed to media player in object tag")]
  58. public static HelperResult MediaPlayer(string path, string width = null, string height = null,
  59. bool autoStart = true, int playCount = 1, string uiMode = null, bool stretchToFit = false,
  60. bool enableContextMenu = true, bool mute = false, int volume = -1, string baseUrl = null,
  61. object options = null, object htmlAttributes = null, string embedName = null) {
  62. return MediaPlayer(HttpContext, _pathUtility, path, width, height, autoStart, playCount, uiMode, stretchToFit,
  63. enableContextMenu, mute, volume, baseUrl, options, htmlAttributes, embedName);
  64. }
  65. // should users really use Silverlight.js?
  66. // see: http://msdn.microsoft.com/en-us/library/cc838259(v=VS.95).aspx
  67. #if CODE_COVERAGE
  68. [ExcludeFromCodeCoverage]
  69. #endif
  70. public static HelperResult Silverlight(string path, string width, string height,
  71. string bgColor = null, string initParameters = null, string minimumVersion = null, bool autoUpgrade = true,
  72. object options = null, object htmlAttributes = null) {
  73. return Silverlight(HttpContext, _pathUtility, path, width, height, bgColor, initParameters, minimumVersion, autoUpgrade,
  74. options, htmlAttributes);
  75. }
  76. internal static HelperResult Flash(HttpContextBase context, VirtualPathUtilityBase pathUtility, string path,
  77. string width = null, string height = null, bool play = true, bool loop = true, bool menu = true,
  78. string bgColor = null, string quality = null, string scale = null, string windowMode = null,
  79. string baseUrl = null, string version = null, object options = null, object htmlAttributes = null, string embedName = null) {
  80. Dictionary<string, object> parameters = ObjectToDictionary(options, "options", FlashBlacklist);
  81. if (!play) {
  82. parameters["play"] = false;
  83. }
  84. if (!loop) {
  85. parameters["loop"] = false;
  86. }
  87. if (!menu) {
  88. parameters["menu"] = false;
  89. }
  90. if (!String.IsNullOrEmpty(bgColor)) {
  91. parameters["bgColor"] = bgColor;
  92. }
  93. if (!String.IsNullOrEmpty(quality)) {
  94. parameters["quality"] = quality;
  95. }
  96. if (!String.IsNullOrEmpty(scale)) {
  97. parameters["scale"] = scale;
  98. }
  99. if (!String.IsNullOrEmpty(windowMode)) {
  100. parameters["wmode"] = windowMode;
  101. }
  102. if (!String.IsNullOrEmpty(baseUrl)) {
  103. parameters["base"] = baseUrl;
  104. }
  105. string cab = FlashCab;
  106. if (!String.IsNullOrEmpty(version)) {
  107. cab += "#version=" + version.Replace('.', ',');
  108. }
  109. return GetHtml(context, pathUtility, path, width, height,
  110. OleMimeType, null, FlashClassId, cab, "movie", FlashMimeType, parameters, htmlAttributes, embedName);
  111. }
  112. internal static HelperResult MediaPlayer(HttpContextBase context, VirtualPathUtilityBase pathUtility, string path, string width = null, string height = null,
  113. bool autoStart = true, int playCount = 1, string uiMode = null, bool stretchToFit = false,
  114. bool enableContextMenu = true, bool mute = false, int volume = -1, string baseUrl = null,
  115. object options = null, object htmlAttributes = null, string embedName = null) {
  116. Dictionary<string, object> parameters = ObjectToDictionary(options, "options", MediaPlayerBlacklist);
  117. if (!autoStart) {
  118. parameters["autoStart"] = false;
  119. }
  120. if (playCount != 1) {
  121. parameters["playCount"] = playCount;
  122. }
  123. if (!String.IsNullOrEmpty(uiMode)) {
  124. parameters["uiMode"] = uiMode;
  125. }
  126. if (stretchToFit) {
  127. parameters["stretchToFit"] = true;
  128. }
  129. if (!enableContextMenu) {
  130. parameters["enableContextMenu"] = false;
  131. }
  132. if (mute) {
  133. parameters["mute"] = true;
  134. }
  135. if (volume >= 0) {
  136. parameters["volume"] = Math.Min(volume, 100);
  137. }
  138. if (!string.IsNullOrEmpty(baseUrl)) {
  139. parameters["baseURL"] = baseUrl;
  140. }
  141. return GetHtml(context, pathUtility, path, width, height,
  142. null, null, MediaPlayerClassId, null, "URL", MediaPlayerMimeType, parameters, htmlAttributes, embedName);
  143. }
  144. internal static HelperResult Silverlight(HttpContextBase context, VirtualPathUtilityBase pathUtility, string path, string width, string height,
  145. string bgColor = null, string initParameters = null, string minimumVersion = null, bool autoUpgrade = true,
  146. object options = null, object htmlAttributes = null) {
  147. if (String.IsNullOrEmpty(width)) {
  148. throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "width");
  149. }
  150. if (String.IsNullOrEmpty(height)) {
  151. throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "height");
  152. }
  153. Dictionary<string, object> parameters = ObjectToDictionary(options, "options", SilverlightBlacklist);
  154. if (!String.IsNullOrEmpty(bgColor)) {
  155. parameters["background"] = bgColor;
  156. }
  157. if (!String.IsNullOrEmpty(initParameters)) {
  158. parameters["initparams"] = initParameters;
  159. }
  160. if (!String.IsNullOrEmpty(minimumVersion)) {
  161. parameters["minruntimeversion"] = minimumVersion;
  162. }
  163. if (!autoUpgrade) {
  164. parameters["autoUpgrade"] = autoUpgrade;
  165. }
  166. return GetHtml(context, pathUtility, path, width, height,
  167. SilverlightMimeType, "data:" + SilverlightMimeType + ",", // ',' required for Opera support
  168. null, null, "source", null, parameters, htmlAttributes, null,
  169. tw => {
  170. tw.WriteLine("<a href=\"http://go.microsoft.com/fwlink/?LinkID=149156\" style=\"text-decoration:none\">");
  171. tw.WriteLine("<img src=\"http://go.microsoft.com/fwlink?LinkId=108181\" alt=\"Get Microsoft Silverlight\" style=\"border-style:none\"/>");
  172. tw.WriteLine("</a>");
  173. });
  174. }
  175. private static Dictionary<string, object> ObjectToDictionary(object o, string argName, string[] blackList) {
  176. PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(o);
  177. Dictionary<string, object> d = new Dictionary<string, object>(properties.Count + 10);
  178. foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(o)) {
  179. if (blackList.Contains(pd.Name, StringComparer.OrdinalIgnoreCase)) {
  180. throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture,
  181. HelpersToolkitResources.Video_PropertyCannotBeSet, pd.Name), argName);
  182. }
  183. d[pd.Name] = pd.GetValue(o);
  184. }
  185. return d;
  186. }
  187. private static HelperResult GetHtml(HttpContextBase context, VirtualPathUtilityBase pathUtility,
  188. string path, string width, string height, string objectType, string objectDataType,
  189. string objectClassId, string objectCodeBase, string pathParamName, string embedContentType,
  190. IDictionary<string, object> parameters = null, object htmlAttributes = null, string embedName = null,
  191. Action<TextWriter> plugin = null) {
  192. path = ValidatePath(context, pathUtility, path);
  193. Dictionary<string, object> objectAttr = ObjectToDictionary(htmlAttributes, "htmlAttributes", GlobalBlacklist);
  194. objectAttr["width"] = width;
  195. objectAttr["height"] = height;
  196. objectAttr["type"] = objectType;
  197. objectAttr["data"] = objectDataType;
  198. objectAttr["classid"] = objectClassId;
  199. objectAttr["codebase"] = objectCodeBase;
  200. return new HelperResult(tw => {
  201. tw.Write("<object ");
  202. foreach (var a in objectAttr.OrderBy(a => a.Key, StringComparer.OrdinalIgnoreCase)) {
  203. var value = (a.Value == null) ? null : a.Value.ToString();
  204. WriteIfNotNullOrEmpty(tw, a.Key, value);
  205. }
  206. tw.WriteLine(">");
  207. // object parameters
  208. if (!String.IsNullOrEmpty(pathParamName)) {
  209. tw.WriteLine("<param name=\"{0}\" value=\"{1}\" />",
  210. HttpUtility.HtmlAttributeEncode(pathParamName),
  211. HttpUtility.HtmlAttributeEncode(HttpUtility.UrlPathEncode(path)));
  212. }
  213. if (parameters != null) {
  214. foreach (var p in parameters) {
  215. tw.WriteLine("<param name=\"{0}\" value=\"{1}\" />",
  216. HttpUtility.HtmlAttributeEncode(p.Key),
  217. HttpUtility.HtmlAttributeEncode(p.Value.ToString()));
  218. }
  219. }
  220. // embed tag and parameters: used by Netscape and IE on Mac
  221. if (!String.IsNullOrEmpty(embedContentType)) {
  222. tw.Write("<embed src=\"{0}\" ", HttpUtility.HtmlAttributeEncode(HttpUtility.UrlPathEncode(path)));
  223. WriteIfNotNullOrEmpty(tw, "width", width);
  224. WriteIfNotNullOrEmpty(tw, "height", height);
  225. WriteIfNotNullOrEmpty(tw, "name", embedName);
  226. WriteIfNotNullOrEmpty(tw, "type", embedContentType);
  227. if (parameters != null) {
  228. foreach (var p in parameters) {
  229. tw.Write("{0}=\"{1}\" ", HttpUtility.HtmlEncode(p.Key), HttpUtility.HtmlAttributeEncode(p.Value.ToString()));
  230. }
  231. }
  232. tw.WriteLine("/>");
  233. }
  234. if (plugin != null) {
  235. plugin(tw);
  236. }
  237. tw.WriteLine("</object>");
  238. });
  239. }
  240. private static string ValidatePath(HttpContextBase context, VirtualPathUtilityBase pathUtility, string path) {
  241. if (String.IsNullOrEmpty(path)) {
  242. throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "path");
  243. }
  244. string _path = path;
  245. if (!path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) {
  246. // resolve relative paths
  247. path = pathUtility.Combine(context.Request.AppRelativeCurrentExecutionFilePath, path);
  248. // resolve to app absolute - SL doesn't support app relative
  249. path = pathUtility.ToAbsolute(path);
  250. if (!File.Exists(context.Server.MapPath(path))) {
  251. throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
  252. HelpersToolkitResources.Video_FileDoesNotExist, _path));
  253. }
  254. }
  255. return path;
  256. }
  257. private static void WriteIfNotNullOrEmpty(TextWriter tw, string key, string value) {
  258. Debug.Assert(!String.IsNullOrEmpty(key));
  259. if (!String.IsNullOrEmpty(value)) {
  260. tw.Write("{0}=\"{1}\" ", HttpUtility.HtmlEncode(key), HttpUtility.HtmlAttributeEncode(value));
  261. }
  262. }
  263. }
  264. }