Archive for January, 2009

Dynamic Loading Expression Media Player Template and passing parameters by code

Monday, January 19th, 2009
Autor: Tiago Andrade e Silva


Following my previous post on How to pass parameters to the Expression MediaPlayer component by code, here is a solution that builds upon this post to Dynamicaly load the Media Player inside your app and pass parameters to it.

You can test loading of the player here. The source code can also be downloaded here.

The loading and costumization of the parameters is done like this:

// Download the Media Player using WebClient
private void downloadVideoPlayer()
{
    WebClient downloader = new WebClient();
    downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(onDownloadVideoPlayerCompleted);
    downloader.OpenReadAsync(new Uri("MediaPlayerTemplate.xap", UriKind.Relative));
    lblLoadPlayer.Text = "Downloading Media Player";
}

// Once the Media Player is downloaded
private void onDownloadVideoPlayerCompleted(object sender, OpenReadCompletedEventArgs args)
{
    //http://www.silverlighthack.com/post/2008/09/29/Silverlight-2-(RC0-RTM)-Dynamic-Assembly-Loading.aspx
    //http://silverlight.net/learn/learnvideo.aspx?video=65687
    try
    {

        string appManifest = new StreamReader(Application.GetResourceStream(new StreamResourceInfo(args.Result, null), new Uri("AppManifest.xaml",UriKind.Relative)).Stream).ReadToEnd();

        XElement deploymentRoot = XDocument.Parse(appManifest).Root;
        List<XElement> deploymentParts = (from assemblyParts in deploymentRoot.Elements().Elements()
                                select assemblyParts).ToList();

        Assembly asm = null;
        foreach (XElement xElement in deploymentParts)
        {
            string source = xElement.Attribute("Source").Value;
            AssemblyPart asmPart = new AssemblyPart();
            StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(args.Result, "application/binary"), new Uri(source, UriKind.Relative));
            if (source == "MediaPlayerTemplate.dll")
            {
                asm = asmPart.Load(streamInfo.Stream);
            }
            else asmPart.Load(streamInfo.Stream);
        }



        MediaPlayerTemplate.Page myPlayer = asm.CreateInstance("MediaPlayerTemplate.Page") as MediaPlayerTemplate.Page;
        Dictionary<string,string> dic = new Dictionary<string, string>();
        dic.Add("autoplay", "true");
        dic.Add("enablecaptions", "true");
        dic.Add("muted", "false");
        dic.Add("stretchmode", "0");
        dic.Add("displaytimecode", "false");
        dic.Add("playlist", "<playList><playListItems><playListItem title=\"\" description=\"\" mediaSource=\"silverlight.wmv\" adaptiveStreaming=\"False\" thumbSource=\"\" frameRate=\"23.9760431376968\" width=\"512\" height=\"284\" ><chapters><chapter  position=\"11.256\" title=\"MYMARKER01\" /><chapter  position=\"20.033\" thumbnailSource=\"silverlight_20.033.jpg\" title=\"Capitulo%201\" /><chapter  position=\"45.585\" thumbnailSource=\"silverlight_45.585.jpg\" title=\"Chapter%202\" /><chapter  position=\"58.646\" thumbnailSource=\"silverlight_58.646.jpg\" title=\"Chapter%203\" /><chapter  position=\"72.199\" thumbnailSource=\"silverlight_72.199.jpg\" title=\"Chapter%204\" /></chapters></playListItem></playListItems></playList>");
        myPlayer.StartUp(dic);

        cnvMediaPlayer.Children.Add(myPlayer);
        lblLoadPlayer.Text = "";
        LayoutRoot.UpdateLayout();

    }
    catch (Exception e)
    {
        lblLoadPlayer.Text = "Download Error: " + e.Message;
    }
}

If you download the source code you will need to create your own playlist that points to a a movie of your own and set the thumbnails and chapters as you wish. Check the following line of code inside VideoPlayerHoster, Page.xaml.cs

dic.Add(“playlist”, “<playList>…

The Dynamic loading was implemented by looking at these 2 posts:

http://www.silverlighthack.com/post/2008/09/29/Silverlight-2-(RC0-RTM)-Dynamic-Assembly-Loading.aspx

http://silverlight.net/learn/learnvideo.aspx?video=65687

Using Expression Encoder 2 MediaPlayer Templates in your application

Monday, January 19th, 2009
Autor: Tiago Andrade e Silva


Microsoft Expression Encoder 2 SP1 now includes a set of Silverlight 2 Output Templates:

 Using Expression Encoder 2 MediaPlayer Templates in your application

After installing SP1 you’ll have a some Silverlight 2 templates in “C:\Program Files\Microsoft Expression\Encoder 2\Templates\en”.

The Templates use 2 controls that implement most of the logic that we need on our media apps: MediaPlayer and ExpressionPlayer. These controls take care of all basic media handling functionalities but also Video Marker handling, Chapters and chapter thumbnails, playlists, cpations, etc.

Out-of-the-box the templates can be hosted in a html or aspx page and the parameters passed when loading the XAP. Here is the html of the page that is created when running your template:

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
            <param name="source" value="MediaPlayerTemplate.xap"/>
            <param name="onerror" value="onSilverlightError" />
            <param name="initparams" value='autoplay=&amp;lt;$=TemplateParameter.AutoPlay$>,autoload=<$=TemplateParameter.AutoLoad$>,enablecaptions=<$=TemplateParameter.EnableCaptions$>,muted=<$=TemplateParameter.Muted$>,stretchmode=<$=TemplateParameter.StretchMode$>,displaytimecode=<$=TemplateParameter.DisplayTimecode$>,playlist=<$=PlayListParam(TemplateParameter.AllowedCodecs)$>' />

All customization is made via the initparams.If you want to use the MediaPlayer inside your own Silverlight application (that happens to use a media player) you need to make same changes in order to pass the parameters by code and not by the initparams of the silverlight object command in HTML as the template does.

When Silverlight loads the XAP via HTML it calls:

public Page(object sender, StartupEventArgs e)
{
     InitializeComponent();
     myPlayer.OnStartup(sender, e);
}


Since you cannot create a StartupEventArgs class because it is marked as internal we need another way to pass our parameters from code.

Here are the changes:

1. In ExpressionPlayerControl.cs change the OnStartup method to receive a Dictionary<string, string> instead of StartupEventArgs:

public override void OnStartup(object sender, StartupEventArgs e)

replace by

public override void OnStartup(object sender, Dictionary<string, string> e)

2. Inside the OnStartup method replace “e.InitParams” for InitParams.

3. Since ExpressionPlayer derives from MediaPlayer and OnStartup is overrided we also need to update the OnStartup method in MediaPayer.cs:

public override void OnStartup(object sender, StartupEventArgs e)

replace by

public override void OnStartup(object sender, Dictionary<string, string> e)

4. Since you changed the method signature you also need to update the call to it on Page.xaml.cs and cast it to Dictionary<string, string>:

public Page(object sender, StartupEventArgs e)
{
    InitializeComponent();
    myPlayer.OnStartup(sender, (Dictionary<string, string>) e.InitParams);
}

5. Create a new method that will allow your code to costumize the player:

public void StartUp(Dictionary<string, string> InitParams)
{
    myPlayer.OnStartup(this, InitParams);
}

6. Now you are ready to costumize your mediaplayer from code:

   1:  MediaPlayerTemplate.Page myPlayer = asm.CreateInstance("MediaPlayerTemplate.Page") as MediaPlayerTemplate.Page;
   2:  Dictionary<string,string> dic = new Dictionary<string, string>();
   3:  dic.Add("autoplay", "true");
   4:  dic.Add("enablecaptions", "true");
   5:  dic.Add("muted", "false");
   6:  dic.Add("stretchmode", "0");
   7:  dic.Add("displaytimecode", "false");
   8:  dic.Add("playlist", "<playList><playListItems><playListItem title=\"\" description=\"\" mediaSource=\"silverlight.wmv\" adaptiveStreaming=\"False\" thumbSource=\"\" frameRate=\"23.9760431376968\" width=\"512\" height=\"284\" ><chapters><chapter  position=\"11.256\" title=\"MYMARKER01\" /><chapter  position=\"20.033\" thumbnailSource=\"silverlight_20.033.jpg\" title=\"Capitulo%201\" /><chapter  position=\"45.585\" thumbnailSource=\"silverlight_45.585.jpg\" title=\"Chapter%202\" /><chapter  position=\"58.646\" thumbnailSource=\"silverlight_58.646.jpg\" title=\"Chapter%203\" /><chapter  position=\"72.199\" thumbnailSource=\"silverlight_72.199.jpg\" title=\"Chapter%204\" /></chapters></playListItem></playListItems></playList>");
   9:  
  10:  myPlayer.StartUp(dic);

(assuming myPlayer was defined in your Xaml)

Ciclo de formação Scrum em Janeiro de 2009

Monday, January 5th, 2009
Autor: Tiago Andrade e Silva


A Fullsix está a organizar mais um ciclo de formação Scrum que ocorrerá no final de Janeiro de 2009. Os cursos serão:

TechEd Day 1 – Visual Studio 2010

Sunday, January 4th, 2009
Autor: ricardo.fiel


Foi o conteúdo, quase na ìntegra, da Keynote. Jason Zander, General Manager do Visual Studio, abdicou dos slides e demonstrou, hands-on, o próximo Visual Studio durante 1 hora. Há muito tempo que uma major version de um produto de desenvolvimento não me espantava tanto. Desde um novo look (UI desenvolvida em WPF), muitos melhoramentos nas ferramentas de testes (é possível, por exemplo, partilhar sessões de debugging e vídeos com as acções que um developer fez para replicar determinada falha) até à integração de sequence diagrams, estas foram as funcionalidades que mais gostei de ver:

 

Desenvolvimento para Sharepoint ( :) :):), bye bye Sharepoint Designer )

Informação detalhada sobre variávieis locais directamente no editor, durante o modo de debug.

Integração total da framework jQuery (com intellisense e tudo)

Code coverage

Code snippets para mark-up (html e asp.net)

Sequence diagrams

Partilha de contextos de execução entre developers (extremamente ùtil para resolução de bugs)

OK, a UI em WPF é gira e funcional. É possível, por exemplo, ver os comentários numa caixa toda bonita em vez de xml.

Bye bye underscore para mudança de linha em VB.NET (pessoalmente, esta não me interessa muito, mas foi bastante aplaudida :) )

 

Obviamente existiram bastantes mais assuntos durante as sessões deste dia, mas, pessoalmente, este foi o que mais me espantou. Parabéns ao Jason pelo abdicar de slides perante uma audiência tão grande e por ter arriscado a demonstrar, sem um plano muito delineado, um produto que ainda nem chegou a CTP.

Migrating from Silverlight 2 Beta 2 to RTM – some issues

Sunday, January 4th, 2009
Autor: ricardo.fiel


If you have Silverlight 2 Beta 2 apps and you want to migrate them to RTM, some things may be not-so-easy. I gathered some tips on how to deal with some of the breaking changes. Please check Nuno Godinho’s post on how to install Silverlight 2 RTM and for some great tutorials on building Silverlight apps. Also check his post on RC0 for very helpful migration guidelines.

 

1. Microsoft Expression Blend SP1 cannot open Silverlight 2 RTM projects

After installing Blend SP1, I still wasn’t able to open any Silverlight 2 RTM projects. Hmmmm… Wasn’t that what SP1 was for?! The trick is to run the SP1 installer from the browser (don’t save it to disk). Some people on silverlight.net forums were having the same problem, and this worked for us.

 

2. Opening files with File.Open

Opening files on the client with File.Open is no longer supported, for security reasons. The correct way to do it is to use OpenFileDialog’s File property. Also, this property replaces the previous SelectedFile poperty in OpenFileDialog.

Before:

OpenFileDialog dlg = new OpenFileDialog();
using(Stream s = File.OpenRead(dlg.SelectedFile.Name)  { … }

Now:

OpenFileDialog dlg = new OpenFileDialog();
using(Stream s = dlg.File.OpenRead()) { … }

 

3. Breaking Change #2. ContentPresenter: ContentPresenter now derives from FrameworkElement instead of Control.

Probably one of the hardest changes to deal with. Many of ContentPresenter’s properties were removed (fonts, colors, alignments, etc…). In many cases, you’ll have to rethink your control tree, but sometimes you may get away with replacing ContentPresenter with a TextBlock or wrapping it in a Border. There is no fits-all solution. In a recent application, I found that in most of the places, replacing it with a TextBlock did the trick. This is the change that I’ve seen more people banging their heads with (I’ve been there and was painful!). In some scenarios, you can also get away with moving some style-related things to the container.

 

One final word, the final version of Silverlight 2 is a lot less forgiving than Beta 2. Make sure you don’t reference missing media or set invalid properties. You’ll know it at runtime, but most of the times, the runtime engine won’t show the origin of the error (just some message like “Invalid property: Foreground”).

Some additional recommended readings if you’re having trouble:

http://weblogs.asp.net/cschittko/archive/2008/10/12/resolving-errors-moving-to-silverlight2-rtw.aspx

http://blogs.msdn.com/expression/archive/2008/06/19/debugging-design-time-exceptions.aspx

Hope this helps.


Better Tag Cloud