Flash and Flash Video EPiServer Dynamic Content
I’ve extended Allan Thræn’s Insert Flash elements in the Editor as Dynamic Content, to now use swfobject for a more standards-friendly way of embedding Flash. I’ve also added support for videos, by using Flowplayer, which is a popular Flash Video Player.
Flowplayer

Edit mode
Solution
Update 18.11.2009
I’ve updated the code to now also use fallback content for users that do not have Flash or JavaScript installed/enabled. When using the fallback content with regular Flash files (.swf), whenever someone who doesn’t have Flash or JavaScript installed/enabled it will display.
For Flowplayer it behaves a bit differently, the fallback content will be displayed when the page loads, when someone clicks it, the video will start. So with no fallback content, the video plays automatically when the page loads. With fallback content (could be an image for instance), the user has to click the image (in this case), to start the video. Here’s an example.
The code is almost identical to Allan’s, the only thing I’ve changed is the Render method and I’ve added an extra text field for the id (must be unique for the page).
Since the fallback content contains HTML code I had to update the code for getting and setting the State. Previously I just used Allan’s code, which used | to separate the different values. But now I had to use XML and Serialization. It was a little tricky at first, but thankfully I came across Anders’ post Dynamic content and State attribute.
using System; using System.Globalization; using System.Xml.Linq; using EPiServer; using EPiServer.Core; using EPiServer.DynamicContent; using EPiServer.Editor; using EPiServer.SpecializedProperties; namespace FlashDynamicContent { public class FlashDynamicContent : IDynamicContent { protected PropertyDocumentUrl flash; protected PropertyNumber width; protected PropertyNumber height; protected PropertyXhtmlString fallbackContent; /// <summary> /// Setup properties /// </summary> public FlashDynamicContent() { flash = new PropertyDocumentUrl { Name = "Flash file " }; width = new PropertyNumber(300) { Name = "Width" }; height = new PropertyNumber(300) { Name = "Height" }; fallbackContent = new PropertyXhtmlString { Name = "Fallback content", EditorToolOptions = EditorToolOption.All ^ EditorToolOption.Font ^ EditorToolOption.DynamicContent }; } public System.Web.UI.Control GetControl(PageBase hostPage) { throw new NotImplementedException(); } public PropertyDataCollection Properties { get { return new PropertyDataCollection { flash, width, height, fallbackContent }; } } public string Render(PageBase hostPage) { if (flash.ToString().EndsWith(".swf", true, CultureInfo.InvariantCulture)) { if (!hostPage.ClientScript.IsClientScriptIncludeRegistered("swfobject")) { hostPage.ClientScript.RegisterClientScriptInclude("swfobject", "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"); } hostPage.ClientScript.RegisterStartupScript(GetType(), "swfobject" + this.GetHashCode(), string.Format("swfobject.embedSWF(\"{0}\", \"flash{3}\", \"{1}\", \"{2}\", \"9.0.0\", false);", flash, width, height, this.GetHashCode()), true); return string.Format("<div id=\"flash{0}\">{1}</div>", this.GetHashCode(), fallbackContent); } if (!hostPage.ClientScript.IsClientScriptIncludeRegistered("flowplayer")) { hostPage.ClientScript.RegisterClientScriptInclude("flowplayer", "/Flowplayer/flowplayer-3.1.4.min.js"); } hostPage.ClientScript.RegisterStartupScript(GetType(), "flowplayer" + this.GetHashCode(), string.Format("flowplayer(\"flash{0}\", \"/Flowplayer/flowplayer-3.1.5.swf\", \"{1}\");", this.GetHashCode(), flash), true); return string.Format("<div style=\"width:{0}px;height:{1}px\" id=\"flash{2}\">{3}</div>", width, height, this.GetHashCode(), fallbackContent); } public bool RendersWithControl { get { return false; } } public string State { get { return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(new XElement("flashcontent", new XElement("flash", flash), new XElement("width", width), new XElement("height", height), new XElement("fallbackcontent", new XCData(fallbackContent.ToString()))).ToString(SaveOptions.DisableFormatting))); } set { if (value == null) { return; } byte[] toDecodeByte = Convert.FromBase64String(value); var encoder = new System.Text.UTF8Encoding(); System.Text.Decoder utf8Decode = encoder.GetDecoder(); int charCount = utf8Decode.GetCharCount(toDecodeByte, 0, toDecodeByte.Length); var decodedChar = new char[charCount]; utf8Decode.GetChars(toDecodeByte, 0, toDecodeByte.Length, decodedChar, 0); var flashContent = XElement.Parse(new string(decodedChar)); flash.ParseToSelf((string)flashContent.Element("flash")); width.ParseToSelf((string)flashContent.Element("width")); height.ParseToSelf((string)flashContent.Element("height")); fallbackContent.ParseToSelf((string)flashContent.Element("fallbackcontent")); } } } }
In the Render method I check if the file ends with .swf, depending on that I either add the code for swfobject, or for flowplayer.
Update 19.11.2009
Thanks to Martins comment, I’ve removed the id field and replaced it with the HashCode and a prefix of flash (HTML id have to start with a letter in the roman alphabet). One less thing for the editor to worry about
.
Installation
- Download the code
- Unzip, and copy the FlashDynamicContent.dll into your sites bin folder, and the Flowplayer folder into your sites root folder
- Register it in your web.config file
<dynamicContent> <controls> ... <add description="Insert Flash or Flash Video" name="FlashDynamicContent" type="FlashDynamicContent.FlashDynamicContent, FlashDynamicContent"/> </controls> </dynamicContent>

Hello Frederik,
Good improvements to Allan’s dynamic content. Just wanted to give a suggestion regarding the id that you add manually here. We’ve done similar updates to Allan’s code, without the flash video option but with for instance swfobject, like you have, and also the possibility to feed xml to the flash for localization and such things. But regarding the id, we’ve solved this by adding the following code to the places where this has to be unique:
this.GetHashCode().ToString()
This way the editor doesn’t have to add id manually but instead this is handled automatically for them, just a suggestion
Best regards
Martin
Hi Martin!
Good suggestion on the GetHashCode method. I’ve updated the code now, and removed the id field. One thing to remember though is that HTML id attributes cannot start with a digit, they have to start with a letter in the roman alphabet (I just added the flash prefix for this).
Frederik
Hello, Fredrik!
I found your player compilation very useful but got two major ‘bugs’:
1. Player is unable to play anything except SWF-files. I followed your steps in ‘Installation’ section but it seems that more verbose installation procedure is required for me
2. I can’t see any controls at all for the movie. Is it normal?
Hi Andrey!
Make sure that you copied the Flowplayer folder, and placed it in your sites root folder (http://example.com/Flowplayer). I’ve been testing with this file http://flowplayer.org/video/flowplayer-700.flv, though I know Flowplayer supports other formats as well (see http://flowplayer.org/documentation/technical-facts.html) – your best bet is to convert your movies to .flv.
Hope this helps.
Frederik
You shouldn’t use the GetHashCode value for building the id, since it doesn’t guarantee uniqueness; it only aims to distribute its values uniformly. A lot of developers get this wrong.
It would be better to allow the user to optionally enter a specific id, should she want to (like you first did). Who knows, perhaps it’s needed by some custom JavaScript code the user also adds to the page. When it’s not filled in, you could automatically generate a request unique id by utilizing a counter in Context.Items.
Better yet is to replace the fugly built-in editor with some decent alternative, such as TinyMCE that already has a media plug-in.
////////////////////////////////
Hi Andrey!
Make sure that you copied the Flowplayer folder, and placed it in your sites root folder (http://example.com/Flowplayer). I’ve been testing with this file http://flowplayer.org/video/flowplayer-700.flv, though I know Flowplayer supports other formats as well (see http://flowplayer.org/documentation/technical-facts.html) – your best bet is to convert your movies to .flv.
Hope this helps.
Frederik
////////////////////////////////
Sorry, but – no luck
It’s not working. I’ve tried different ways to provide the path to FLV-file in plugin interface, but got only the black square with “Movie not loaded” in the context menu. Are you sure it’s wotking with the EPiServer CMS of 5 version? Maybe there should be some pre-requisites or some web.config-tuning for the application?
Should work fine with EPiServer CMS 5 R2 and later. Have you tried using the test movie I linked to in my comment above?
Works great, thanks for the post.