Wednesday, January 30, 2008

Anatomy of a Silverlight Animation

For the most part we should be using Storyboards to do animations. Though it is possible to do programmatic animation and we do sometimes programmatically set properties the Storyboard infrastructure in Silverlight provides a standard easy to use and optimized way to-do animation and is a key tenet of the Silverlight technology especially around performance.

Storyboards like other elements in Xaml are defined with tags. The Storyboard element then can be a resource or in a trigger. We can also point a Storyboard at a specific element where each animation can target a different property and we can also target each specific animation at a given element and property separately. Let us start with a Storyboard then like this example:

<Storyboard x:Name="MyFirstStoryBoard"></Storyboard>

From this Storyboard we will build out our animations. The individual animations go in the story board. There are several kinds of animations such as color, point, key frame and key spline animations but we will start with point and color animations. Now look at this simple double animation.

<DoubleAnimation Storyboard.TargetName="PolygonElement"
Storyboard.TargetProperty="(Canvas.Left)"
To="48" Duration="0:0:3" />

This is a DoubleAnimation that, when the Storyboard is triggers changes one property value to another over the course of the duration. In this case the animation is targeted on the PolygonElement at the Left value. This animation does not have a ‘From’ setting so the property goes from whatever value it at to the ‘To’ setting and then over the duration of the ‘Duration’ setting in this case 3 seconds. We could also set a ‘BeginTime’ using the same time format as that of the Duration like this code sample:

<DoubleAnimation Storyboard.TargetName="PolygonElement"
Storyboard.TargetProperty="(Canvas.Left)" From="5"
To="48" Duration="0:0:3" BeginTime="00:00:02" />

This animation then targets the Canvas.Left property of the element named ‘PolygonElement’. At 2 seconds past the trigger of the animation it will change the left value from 5 to 48 over the course of 3 seconds. This was a double animation and you can have any number of these in a given story board. You can also use color animations in the same way with double animations. Take this code example:


<ColorAnimation
Storyboard.TargetName="PolygonElement"
Storyboard.TargetProperty="(Fill).(Color)"
From="#3c5f0c" To="#728f4a" Duration="0:0:5" />

Like the double animation earlier this ‘ColorAnimation’ is targeted at the same element but on a different property namely one that is a color ‘Fill.Color’. When this animation is triggered the ‘Fill.Color starts at one color and transforms to the other over the course of 5 seconds.

Tuesday, January 29, 2008

Silverlight Applications Taking All the Available Realestate

Karim sent me this. It is a simple way make sure you Silverlight Application uses all the available realestate using just CSS:


/* hide from ie on mac \*/
html
{
height: 100%;
overflow: hidden;
}
.silverlightHost
{
height: 100%;
width: 100%;
}
/* end hide */

body
{
height: 100%;
margin-left: 1px;
margin-top: 1px;
margin-right: 0px;
margin-bottom: 0px;
padding: 0;
}


Now there are other ways todo this such as from the HTML body onload event and also the resize event on the window together or other programatic ways but this is just nice and simple and I say keep it simple unless you have to.

Lunch at MIX

Anyone going to MIX that wants todo lunch let me know... I know at MIX there will be alot of 'new' stuff and I will probably have 1000 posts on SL 2.0 at MIX... all stuff that is super secret now...

Wednesday, January 23, 2008

Drinking the Kolaide

I spend a lot of time on campus at MS and some one made a comment about it something todo with singing songs and drinking coolaide etc and I wanted to set the record straight...



We do not in fact come and sit in a circle, hold hands, sing songs and drink coolaide while having stories read to us.

Silverlight and Volta

Now here is a new Silverlight related technology:

http://labs.live.com/volta/blog/Volta+Secrets+Part+5++Silverlight.aspx

Its on a public site so I guess I can blog about it. They idea is simple, you write your application all in C# like a win form and this thing generates it as part web page part serverside script in now using Silverlight. I'm sure I'll talk about this more after I play with it some more.

Tuesday, January 22, 2008

Silverlight Browser Windows Communcation

I got this email some time ago but it was in my junk email box. Anyway I finally found it and thought it might be of use to everyone.

Hi DavidThanks for your posting on SilverLight. It helps me a lot.Now I have a challenge technical problem:I have a HTML page as parent window that plays some video clip. Also people can click a link from that page to create some popup windows (child windows). In the child windows, the same video clip from the parent window should be played (content sync).I can do this using a common XAML file that shared among these windows.Now the challenge for me is: the parent window has video control buttons (like play, pause, stop, ...). How to sync the action controls? For example, if the video is stopped in the parent window, the stop should also apply to all child windows. In other words, how to achieve the action sync?I am thinking if it is possible to change the XAML by the parent window on the fly so that child windows can be updated accordingly. I am not sure if this is possible in Silverlight since it seems to me the XAML is a static object. Can you think of a way to accomplish that or shed some light on the issue?
Thanks! Jay
my response:

you would need hold a reference to the child window and call into it from script so basically when you click a button in the parent it would also go call out to script and the child window. For doing this in IE MSDN has a good reference on working with the IE object model to do this. Start by finding window.open and how to keep a reference and make calls. This however I don't think is very cross browser...

Video Brush in 5 minutes or less

The Video brush is a great way to do some cool special effects. To make a video brush work on you have to have a named media element that you can bind to. That has a bound source. In the sample below we have a source. We have set the element to be muted but play and its opacity is 0 so no one sees it on screen. Then we add some text in a text block app and add a foreground element with a ‘video’ brush. The video brush element is bound to the media element by using the media element name. Using a video brush you can basically make just about anything play video.

<MediaElement Name="MediaElementElement" Source="ImenSample.2.wmv" Canvas.Left="20" Canvas.Top="20" Width="100" Height="100" IsMuted="True" AutoPlay="True" Opacity="0" />

<TextBlock Name="Sample Text" FontSize="20" FontFamily="Verdana" FontWeight="Bold" Canvas.Left="10" Canvas.Top="50" Opacity="1" >PAINT WITH VIDEO <TextBlock.Foreground> <VideoBrush SourceName="MediaElementElement" /> </TextBlock.Foreground> </TextBlock>


When this Xaml is rendered we get the text ‘Paint with video’ that is actually playing the video in the background of the text.

Saturday, January 19, 2008

Uploading/Hosting Encoder Output and other Silverlight Apps into Silverlight Streaming

Now that we have a streaming account and we created our content with Expression Encoder now lets get it hosted. First we need to find the output which generally is under your documents folder then ‘Expression/Output/’ you will need to remove the .csprog, and .html files and the Silverlight.js and then create a manifest.xml file. With the default your manifest.xml file should look like this:

<SilverlightApp> <version>1.0</version> <loadFunction>StartWithParent</loadFunction> <jsOrder> <js>MicrosoftAjax.js</js> <js>BasePlayer.js</js> <js>PlayerStrings.js</js> <js>player.js</js> <js>StartPlayer.js</js> </jsOrder></SilverlightApp>

Now combine this into a zip at the root of the zip and not in a directory. Once you do that log into the Silverlight streaming site and click ‘Manage Application’ and then click ‘Upload a Silverlight Application’.

Give the application and name and browse to your zip. If anything is missing such as a manifest.xml or you have left the html file or something in the file you will get an error.

This window gives you all the information you need to actually link to your uploaded Silverlight Streaming hosted application.

Wednesday, January 16, 2008

Microsoft® Media Encoder™ in 5 minutes or less

Expression Media Encoder is a Microsoft tool in the Microsoft Expression Suite of tools specifically designed to take media content and either tanscode/encode it or produce in a form that can be consumed online in the form of some kind of Silverlight media player and WMV and to integration with Silverlight Streaming services. Expression media encoder has a number of built in templates for use in quickly building Silverlight media players. Once you get the application up and running, and you stare at it for a few minutes to get oriented it is pretty straight forward.

From the initial screen we need to import our media file. Go to the file menu and select import, navigate to the video file you want and selection ‘open’. Next we need to select a template which you can do by selecting output and then under the section ‘Job Output’ select one of the templates. You should see a shot from your video in the main area.

Now just click the button in the middle on the bottom and Encoder will go to town. Now this is all good and Media encoder has a bunch of other features around setting up markers and the like but the really key thing is that it gets video content into a nice format that Silverlight can consume.

http://www.microsoft.com/expression/products/overview.aspx?key=media

Silverlight Streaming in 5 minutes or less

Microsoft as part of the whole Silverlight ‘thing’ has provided a service to allow people to upload videos and get those video streamed along with providing other video streaming services. At the time of me writing this book it is a free service up to 4 gigs of space/video and streams video up to 700kpbs but as it goes into beta and is released you get advertising or you pay a ‘nominal’ fee but for developer’s and designers this is really cool and for companies this makes live a bit easier if you want to stream video content from you web site but don’t have a streaming media service.

A couple of key points of the streaming media service is to enable rapid application development, to be able to deliver quickly streaming media solutions and to be able to provide unlimited scaling should the need arise of your streaming content. The provide admin tools, a REST API, documentation and other tools online for your application development. Currently there are issues with Silverlight all living in the same domain so your bits out on Silverlight streaming need to be ‘all’ your bits but you can embed them in an iframe or separate window and pass in query string values etc. You can check out the service at :

http://silverlight.live.com/ or

http://www.microsoft.com/silverlight/streaming.aspx#1_4

So let us set up an account, starting from Silverligth.live.com.

Next we click on ‘get it free’. At some point a paid service will be available. But for now it is not.

Click the ‘click here’ link to go onto creating our streaming account.

If you don’t have a live id you will have to go through the registration process if you do then you can just login to create your account. In this case I do have such an id and I login and created my Streaming account and then the screen should look like this after logging in.
So when you click ‘I Accept, Create Account’ you then have your account.

This screen show your public account id and account key. You will want to know these later when we upload some content using the Microsoft Media Encoder. You can learn more about Silverlight Streaming at:

http://dev.live.com/silverlight/

So From here we are ready to for my next post on media encoder.

Tuesday, January 15, 2008

Childrens Book...

So this isn't exactly Silverlight but it is extremely funny...

http://gizmodo.com/photogallery/microserveces08/1000446145

I would love to turn this into a online 'silverlight' app.

Monday, January 14, 2008

Sidebar Gadgets and Email

here is an interesting thing I ran into when emailing a sidebar gadget as a gadget file... it seems that some email systems will go into the compiled gadget file and replace all the script files with .txt files and this:

FILE QUARANTINED
[COMPANY NAME HERE] has removed App.Gadget->App.Gadget.html.js since ithas been found to match the FILE FILTER= unnamed: *.js file filter.

I find if I change the file extention to something like .virus then you can get through email filters much better...

Thursday, January 10, 2008

Silverlight Firestarter on MIX Silverlight University

I posted about firestarter when they held this up on the Microsoft campus. it was very cool. If you go you get to meet some of the cool silverlight guys like Laurence, Adam and Arturo. Anyway their are doing a MIX silverlight university with the firestarted content. very cool stuff.
http://www.visitmix.com/University/silverlight/firestarter/

I'm setting in the front row and a couple times you can see the top/back of my head for a second in at least in some of the videos. :) Gotta love Laurence's shameless plug for his book. :)

Vista Sidebar Gadgets, Silverlight and JSON

ok, so I've posted about JSON in sidebar gadgets before and using Silverlight... when it comes to JSON (in vista side bar gadgets) just say no. at least directly, there are soooo many issues with this that it is unbelievable not to mention I'm running on a 64bit box that shouldn't even run silverlight to begin with the issues are not even consistent across different variations of vista and silverlight... really this is killing me. I found that it is eaiser to just make xml calls which is what I normalled used todo before some one came up with this brillant JSON thing... not that it is a real protocol and all but it is slick, anyway don't use JSON directly in a side bar gadget especially with Silverlight.

That being said, there are a number of ways doing old fashioned xml posting to get what you need and you can just parse and do the old fashioned xml thing and if your extra Industrious or need to write out something and the JSON eval thing solves some problems for you (namely less work) then add some begin and end tags and a nice CDATA section and your good...

But if you find a pratical way todo this let me know (JSON, sidebar gadget, vista, silverlight...), I'd love to see a code sample.

Why You Need An Architect

very good entraining post...

http://blogs.msdn.com/dseven/archive/2008/01/09/why-you-need-an-architect.aspx

Wednesday, January 9, 2008

Silverlight Related Videos

here is bills key note which on a side note besides talking about Silverlight also shows this cool surface application that Identitymine did, hot sexy UI...

http://video.msn.com/video.aspx/?mkt=en-us&fg=rss&vid=e75f8529-b835-4282-81dc-37e0fa9da251&from=im_default&wa=wsignin1.0

also here is a video of Dan Fernandez talking about Popfly.

http://www.youtube.com/watch?v=xW-EXufLoJg&feature=related

Tuesday, January 8, 2008

Silverlight Propaganda Video...

this has been out for a while but just in case no one has seen it.

http://www.youtube.com/watch?v=L-CVlA_-Ogk&NR=1

Tools and the Silverlight Tool-ability Story

Yea, yea enough with the corporate marketing ‘fu fu’, just remember I learned real manly man programming on a Mac in ANSI C that happened to be a 68k series Mac in code warrior using the mac tool box in the 80’s and if you even know what that means then you might really ask why all the devotion to Microsoft and Silverlight. And for that matter why write a book for developers AND designers? So here is my case.

I have built some cool things in tools like flash, and by all means this is cool stuff. One of my favorite things about flash in particular is that it runs anywhere on any reasonable browser even my current old fashion PPC phone or my friends Mac or my other friends Linux box. It’s just cool what you can do. But have done my share of action script it really reminds me of a comparison between ‘classic’ ASP and ASP.NET. It is a fundamental shift. Take the Emmy site we did at IdentityMine, this web app had to mix and match video, allow users to play producer suck up numerous feeds running off of Linux box’s using Perl scripts to build out UI elements in Xaml and do drag and drop different kinds of video scrubbing depending on the state of the application and the mode it was in and really provide a rich Web 2.0 experience and by all means there are some things that flash does that Silverlight doesn’t but building this complicated system in 8 days would have been just impossible at least for any dev team I have dealt with in Flash. The tools just are not there.

Granted I probably would not even considered doing it and it really was laughable when first presented to me but hey the money was in line with what it would take to give up 8 days of my life and we had a reputation for doing the impossible so what the heck we would try to do it. And 8 agonizing days later I’ve changed religions as it were and now I’m writing a book and live a breath Silverlight.

Getting back to this tool ability story around Silverlight when I first went to collage I studied photography and computer science for a year and a half. In high school I loved computers but having been music and art I loved beautiful things. I would spend hours rearranging this at my apartment to the point that they would look out of a magazine and I would make my own deco to get the right look and would obsess of design. Photography as opposed to other art allowed me to get to the level or precision in my art that I loved. I’m not Michelangelo so hand drawings and the like I could never get to the level of perfection that my OCD (obsessive compulsive disorder) needed to not send me into some kind of break down.

So in photography I found a home, I loved the idea of lines of composition and building form and contrast and the like but when it came to deciding I felt that my best path was to focus on one, namely computer science and programming in particular. In this case my code became my art but I kept this obsession for perfection in design and when my designer friends got me hooked on using Expression blend on one side and Visual Studio on the other… I was hooked. Truly Zen has been achieved in a superior design tool and Visual Studio at the same time. What more could I want from a toolability story.

Monday, January 7, 2008

Dr. WPF and Silverlight

So I know of this guy, 'Dr. WPF' and he is a 'huge'... Silverlight fan [insert sarcasm here]. well anyway he has done some Silverlight. He has a little 'test' app that is really cool. So just so you guys can check it out here is a link:

http://drwpf.com/blog/Home/tabid/36/EntryID/15/Default.aspx

Hacking Jackass Site

Hmm... I saw this recently...

http://tkhere.blogspot.com/2007/12/howto-be-real-jackass-and-download.html

Don't get my wrong I still find the 'content' offesive but this is the reason companies have to make things hard for people... case in point now NO ONE with firefox got to see the movie after Movielink found out and good for Movielink for stoping this hack.

Silverlight Golden Globes and Entertainment Tonight

Another hot Silverlight application based for ET that we (IdentityMine) built.

http://www.etonline.com/silverlight/globes65/

Even girls will like it :)

Expression Blend in 5 minutes or less

Using Expression Blend is pretty straight forward. It is ideal to do our Xaml in code. When you open a project and select the type you want, Whether you create your project in Blend, or some other program, your project is shown in the upper right. For the most part, we will only be concerned about ‘.xaml’ files in Blend. In the center, we have our design surface and below is our code view. When you manipulate your Xaml in the design view, Blend changes the code in the code view below.
On the very left hand side is our drawing toolbar for manipulating or creating design in Xaml. When you select an item it will open with a drop-down like menu that you select and then you can do something with it or, like the two arrows at the top, you just select it and go. If you hover over the tool a tool tip word bubble will tell you what it is. Also note for most things, the key board short cuts are the same in Blend as other popular designer environments. You also can select the ‘properties’ tab on the right hand side and you can then see exactly what you can do with Expression Blend. Blend also does a lot of cool stuff that we will talk about later.
And thats pretty much it. :) Oh you can also do animations too but that will be another post.

Friday, January 4, 2008

Silverlight 2.0 Asset Enumeration

I did a post a while back about a cool trick to download bits in a zip file and save it all in an enumeration in the base application class that is built dynamically without knowing exactly what is in the zip. The earlier post was strickly Silverlight 1.0 javascript so here it is in Silverlight 2.0 C#.

So first I created some private properties in the base class:


private Downloader _DL = new Downloader();
private string _AssetEnumerationPath = "http://localhost:58377/TestSite/Assets.zip";
private AssetItem[] _AssetSourceEnum = null;
private string _Errors = string.Empty;
private Canvas _Item1 = null;
public Downloader AssetEnum = null;

So also instead of being industries and using JSON the index file is a CSV in the sample. So bascially I put a CSV file and three bits of xaml for the test project. Then in Page_Loaded we use a downloader, associate a few events and fire off the event at our zip file like this:


_DL.Open("GET", new Uri(_AssetEnumerationPath));
_DL.Completed += new EventHandler(_DL_Completed);
_DL.DownloadFailed += new ErrorEventHandler(_DL_DownloadFailed);
_DL.Send();

in our _DL_Completed then we pull out the index and we know what todo with whats in the file. In this case we save it at the root so it can be used or bound to things and we also can muck around with it in this case we pull out all the Xaml source and put it into an array. Anyway the entire mess can be downloaded as one zip and we don't have to muck with it. Each control we build can go grab what it needs out of the zip or out of some other array we cached at the root.


try
{
Downloader TempDL = sender as Downloader;
string[] NameArray = TempDL.GetResponseText("Assets/index.csv").Split(',');
_AssetSourceEnum = new AssetItem[NameArray.Length];
for (int x = 0; x < NameArray.Length; x++)
{
_AssetSourceEnum[x] = new AssetItem();
_AssetSourceEnum[x].Name = NameArray[x];
_AssetSourceEnum[x].Xaml = TempDL.GetResponseText("Assets/" + NameArray[x].ToString());
}
AssetEnum = TempDL;
}
catch (Exception E)
{
_Errors = E.Message;
}

simple nice and dirty.

Thursday, January 3, 2008

Silverlight on the iPhone

don't get to excited Silverlight wasn't running ON the iphone but we did manage to get a silverlight app servered up from an iphone... So we thought we would have some fun and install an entire web site on an iphone, install it on our network in the data center and for extra special fun we pointed a high end web stress tool at the phone...

I was surprised to see that the phone for the first 3 minutes of the test was doing well with well over 163 concurrent users at a time on the site but at 16971 hits it melted...

http://www.hackingsilverlight.net/samples/iPhone/iphone.JPG
http://www.hackingsilverlight.net/samples/iPhone/IPhoneWebServer.jpg
http://www.hackingsilverlight.net/samples/iPhone/MVI_8003.AVI
http://www.hackingsilverlight.net/samples/iPhone/Site.jpg

as cool as this is Devin did manage to get his iphone recovered but it took some doing. currently though apache is dead and Devin is trying to get it running again...

Wednesday, January 2, 2008

64bit Vista Sidebar Gadget Video Screen Capture Technology...

So um... check out my 'new' technology for 64bit Vista Sidebar Gadget Video Screen Capture

let me caviate this with the fact that I needed this now to show some one that animation in the side bar of a running gadget using Silverlight.

Camtasia didn't work and shows always always what is underneath and its like the sidebar is not even there...

and yes I googled it but I didn't have more then 10 minutes to make this work.

But since it is sooo funny I thought I would post this...

http://www.HackingSilverlight.net/img/001.JPG

I figure if all else fails and I don't have time, brute force is always good...

:)

Video Scrubbing

A common feature of most video players is the ability to ‘scrub’ video or to ‘scrub’ the time line of a video. When we say ‘scrub’ we basically mean being able to change the position of the video by clicking on a line or icon and dragging it along a line that represents the video and the video changes in real time. That leads us into how we make the time line visually and then making it so we can ‘scrub’ it. The first thing we do is then is to create our Xaml. Check out our Xaml:

<Rectangle x:Name="TBStatusBarBg" Opacity="0.5" Width="327.167" Height="2" Fill="#FF8C8989" RadiusX="0" RadiusY="0" Canvas.Left="15" Canvas.Top="7.667" /><Rectangle x:Name="TBStatusBarDownloadProg" Opacity="0.5" Width="0" Height="2" Fill="#FF6C6B6B" RadiusX="0" RadiusY="0" Canvas.Left="15.333" Canvas.Top="8" /><Rectangle x:Name="TBStatusBarPlayProgress" Opacity="0.5" Width="0" Height="2" Fill="#FF353434" RadiusX="0" RadiusY="0" Canvas.Left="15" Canvas.Top="8.333" /><Rectangle x:Name="ScrubIcon" Opacity="1" Width="3" Height="8" Fill="#999999" RadiusX="5" RadiusY="5" Canvas.Left="15" Canvas.Top="6" Cursor="Hand" /><Rectangle x:Name="ScrubMask" Width="327.167" Opacity="0" Height="10" Fill="#FFF0E8E8" Canvas.Left="15" Canvas.Top="5" Cursor="Hand" />

You can make your time line any way you want but we will use 5 simple rectangles. So using our time line we will show how much the current video is downloaded and the current position in the play back. So with that our first rectangle is the background. This is the core visual representation of the video length. This doesn’t actually do anything and is static regardless of the video source but contrast of the progress and position indicator are relative to this on a percentage basis.

The next rectangle is used to show how much the video is downloaded. This rectangle is animated by an event off of the media element. The third rectangle is our position indicator that will show where the video is in playback and will in fact be the key thing that changes when we actually ‘scrub’ the video. Following that we have a rectangle that is used to as our indicators icon. It is rendered perpendicular to the others and is generally what a user will click on to scrub the time line. The last rectangle is actually an invisible mask we place over the whole sets that is actually what we bind mouse events to so that things are not so hard to click on.

The next two Xaml components are what we need to make the time line work. A media element and some story boards for animation. There are two story boards. One is a timer and the other is the position play back animation to smooth out the position change. Together this smoothes out the changes in position when scrubbing and during playback.

<Canvas.Resources> <Storyboard x:Name="Timer" Storyboard.TargetName="MediaPlayer" > <DoubleAnimation x:Name="TimerWidth" Storyboard.TargetProperty="Width" Duration="0:0:.1" /> </Storyboard> <Storyboard x:Name="PositionPlayBack" Storyboard.TargetName="TBStatusBarPlayProgress" > <DoubleAnimation x:Name="PositionPlayBackWidth" Storyboard.TargetProperty="Width" To="0" Duration="0:0:.1" /> <DoubleAnimation x:Name="PositionIconLeft" Storyboard.TargetName="ScrubIcon" Storyboard.TargetProperty="(Canvas.Left)" To="0" Duration="0:0:.1" /> </Storyboard> </Canvas.Resources> <MediaElement x:Name="MediaElement" Canvas.Left="0" Canvas.Top="0" Width="361" Height="280" ></MediaElement>


Now the hard part is actually in to wire things up. All the eventing we are doing programmatically but you could do it in Xaml as well. In our application object on load we create references to all the Xaml bits we will need to muck up. Then we bind events to the media element, to our animations and to the ‘scrub’ mask and then we set up the media element and we are complete in the onload. That key thing we want to keep in mind here is that we are starting up the timer animation. We could have this in a canvas trigger but doing it in code like this ensures that the time doesn’t start until everything is initialized and it does us some good.

this.TBStatusBarBg = rootElement.findName("TBStatusBarBg");
this.PositionPlayBackWidth = rootElement.findName("PositionPlayBackWidth");
this.PositionPlayBack = rootElement.findName("PositionPlayBack");
this.PositionIconLeft = rootElement.findName("PositionIconLeft");
this.Timer = rootElement.findName("Timer");
this.TBStatusBarPlayProgress = rootElement.findName("TBStatusBarPlayProgress");
this.ScrubIcon = rootElement.findName("ScrubIcon");
this.ScrubMask = rootElement.findName("ScrubMask");

this.MediaElement.addEventListener("DownloadProgressChanged", Silverlight.createDelegate(this, this.MediaElement_DownloadProgressChanged));
this.MediaElement.addEventListener("MediaOpened", Silverlight.createDelegate(this, this.MediaElement_MediaOpened));
this.Timer.addEventListener("Completed", Silverlight.createDelegate(this, this.Timer_Completed));
this.ScrubMask.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.ScrubMask_MouseLeftButtonDown));
this.ScrubMask.addEventListener("MouseMove", Silverlight.createDelegate(this, this.ScrubMask_MouseMove));
this.ScrubMask.addEventListener("MouseLeftButtonUp", Silverlight.createDelegate(this, this.ScrubMask_MouseLeftButtonUp));

this.MediaElement.SetValue( "AutoPlay", false );
this.MediaElement.SetValue( "Volume", this.DefaultVolume );
this.MediaElement.Source = this.Source;
this.Timer.begin();

The Timer then is only .1 seconds and then fires the completed event that we bound to it. In this event we check that the MediaOpened flag has been set and that that mouse is captured or not and starts the timer again. The media opened event that is bound to the media element sets the media opened flag when the video can start playing. Now if the media opened flag is set and the mouse is not captured then it calculates the width based on the width of the background of the time line vs the length of the video taken from the natural direction based on seconds and then the current position. Then we pause the current position animation and set the two values, one for the position bar and the other for the ‘icon’ or fourth rectangle we use as our scrub icon. After we set the critical values we then start the animation again so the change is smooth.

if( this.MediaOpened && !this.ScrubIconMouseCapture )
{
var Width = ( this.TBStatusBarBg.Width / this.MediaElement.NaturalDuration.Seconds ) * this.MediaElement.position.seconds;

this.PositionPlayBack.pause();

this.PositionPlayBackWidth.To = Width;
this.PositionIconLeft.To = Width + 15;

this.PositionPlayBack.begin();
}
this.Timer.begin();

So now we are ready to setup our scrub the time line. But first lets go over the download progress changed event. We bound this to show on our time line how much of the video is downloaded. So this event then sets the width of the download progress bar on our time line and then once it is downloaded it starts the media element playing if our property auto play we created in our class is set to true.

sender.findName("TBStatusBarDownloadProg").SetValue("Width", this.MediaElement.GetValue("DownloadProgress") * this.TBStatusBarBg.Width );

if( this.MediaElement.GetValue("DownloadProgress") == 1 )
{
if( this.AutoPlay )
{
this.Play();
}
}

A scrub operation then starts when a user clicks on our mask rectangle. This fires off the event Mouse Left Button Down. Here we first set the mouse capture flag, we call the pause method we created on the application class. We could just ‘pause’ the video our selves but since we might want to call this method in a number of places and in our application we want to change the play icon too we just wrap it in a method called pause which we call here. Once the flag is set and pause is executed we then actually ‘capture’ the mouse. Remembver on this method we loose the capture without being able to track it if the user moves off the Silverlight control. If we do nothing else if the user clicks some where on the time line to scrub then position will stay some where else until the move the mouse. So to make sure this weird effect doesn’t happy we also fire our mouse move event so that the position immediately goes to the correct position on the time line and the video play back.

ScrubMask_MouseLeftButtonDown: function(sender, eventArgs)
{
this.ScrubIconMouseCapture = true;
this.Pause();
sender.captureMouse();
this.ScrubMask_MouseMove(sender, eventArgs);
},

ScrubMask_MouseMove: function(sender, eventArgs)
{
if( this.ScrubIconMouseCapture )
{
var x = eventArgs.getPosition(null).x - 40

if( x > this.TBStatusBarBg.Width )
{
x = this.TBStatusBarBg.Width + 15;
}
else if( x < x =" 15;" to =" x" to =" x;" newtime =" x"> this.MediaElement.NaturalDuration.Seconds )
{
NewTime = this.MediaElement.NaturalDuration.Seconds;
}

try
{
this.MediaElement.position = "00:" + this.formatTime(NewTime);
}
catch(Exception)
{

}
}
},

The mouse move event as the user holds down the mouse button then actually mucks up our time line and video and is actually ‘scrubbing’ the video. First this method fires any time the mouse moves over the mask so as to not mess with the user too much we want to make sure we have the mouse capture before doing anything. If we do we then grab the x value of the mouse and change it by our offset of the control. Next we need to make sure the value is not to big or to small, for example if the user moves the mouse way past either end of the time line we would effectively be past the end or before the beginning so we reset our ‘x’ value that we will use accordingly using an if else if statement based on the bounds of the time line. Since the position change animation is current paused during the capture event because we called pause on mouse down we just set the two double animation values. Then we restart the animation. Also on regular mouse moves we just set the values and call the begin method. After this we then create a new time value conversion for what the new play back position will be. This is based on our x value divided by the line width divided by natural duration of the video. Then if the new time is greater then the natural duration we set it to the end of the media. Otherwise we go ahead and set the new position and use some error handling to make sure this operation doesn’t blow up.
When the user is done with scrubbing the video with our mouse move event and they lift the mouse button up we call our mouse up button to let the video continue playing. In this event we set our mouse capture flag back to false, call the play method which we wrapped so we could change icons etc like our pause we implemented and then we can release our mouse capture.

ScrubMask_MouseLeftButtonUp: function(sender, eventArgs)
{
this.ScrubIconMouseCapture = false;
this.Play();
sender.releaseMouseCapture();
},

You can implement this a number of ways but this is how I hacked it together and it works well. Now that you can scrub the video time line and your dangerous to yourself and others

Tuesday, January 1, 2008

http://www.microsoft.com/SILVERLIGHT/

I'm going through my goals for the year... mostly about Silverlight and I was reviewing the ms silverlight site and noticed that 3 of the ones listed in the caresel I wrote or contributed to. So far so good. So my goal for the year is to finish my book and have my life revolve around Silverlight at least before it gets outdated. ;) not that it will but at least I might become and expert at something...

Anyway I hope everyones holiday season went well and happy new year.

http://www.microsoft.com/SILVERLIGHT/