Silverlight Twitter Widget Now on SlickThought.NET

7/23/2008 8:12:20 PM

I stumbled across this create resource and immediately had to replace my old HTML based Twitter widget with a much nice Silverlight one.  You can see it in the right sidebar of my homepage.  Though I am not sure if something that splatters my face even more on my site is a good idea.  I may have to grab the source and hack a more viewer friendly version...

Tags:

Slick Thoughts

Silverlight On Mobile: Cool Video of Real Work

7/15/2008 10:15:40 AM

Sam Chenaur has an interesting post and video on some proof of concept working going on with Silverlight Mobile.  Very cool stuff of what will be available to Silverlight developers in the mobile space in the not to distant future.

Tags: ,

Slick Thoughts

For Those of You Interested in Web Video and/or Silverlight

7/14/2008 2:23:26 PM

Ryan Stewart over on ZDNet has some interesting thoughts on this area... nothing earth-shattering but one of the few times I have seen this thought put together so succinctly.

Tags:

Slick Thoughts

Silverlight Beta 2 Due by End of Week

6/3/2008 4:39:19 PM

As reported in more than one place, Silverlight Beta 2 is due out by end of the week.

 

· UI Framework: Beta 2 includes improvements in animation support, error handling and reporting, automation and accessibility support, keyboard input support, and general performance.  This release also provides more compatibility between Silverlight and WPF.

· Rich Controls: Beta 2 includes a new templating model called Visual State Manager that allows for easier templating for controls. Other features include the introduction of TabControl, text wrapping and scrollbars for TextBox, and for DataGrid additions include Autosize, Reorder, Sort, performance increases and more.  Most controls are now in the runtime instead of packaged with the application.

· Networking Support: Beta 2 includes improved Cross Domain support and security enhancements, upload support for WebClient, and duplex communications (“push” from server to Silverlight client).

· Rich Base Class Library: Beta 2 includes improved threading abilities, LINQ-to-JSON, ADO.NET Data Services support, better support for SOAP, and various other improvements to make networking and data handling easier.

· Deep Zoom: Beta 2 introduces a new XML-based file format for Deep Zoom image tiles, as well as a new MultiScaleTileSource that enables existing tile databases to utilize Deep Zoom. Better, event driven notification for zoom/pan state is another improvement in Silverlight 2 Beta 2. 

Tags:

Headlines

Cool Silverlight Watch

5/27/2008 9:07:02 AM

This is worth a look see - cool watch.  That is done all in XAML!  Micheal used an image of the actual watch to create its XAML representation using Expression Blend, maybe a little Expression Design?  You can some of the details from Micheal's blog here.

Tags: , ,

Slick Thoughts

New Blog Postings - Silverlight for Enterprises

5/14/2008 4:08:36 PM

logo I wanted to call your attention to a series of articles that a co-worker and friend, Hanu Kommalapati's will be writing.  He just posted his first entry on "Fundamentals" and will continue on to cover things like security, architecture, deployment, and more.  Hanu is one of those people that falls into my "wicked smart" category.  Hanu does a great job of looking at things through a customer's eyes and then articulating technical information in an approachable way.  I just wish he would post more!!!

Tags: ,

Slick Thoughts

Silverlight Streaming in WPF

5/5/2008 1:23:00 PM

The MyTube project (download v0.0001 here) continues on with yet another example of getting your video your way.  Just when I think I'm done, it keeps pulling me back in!  Or something to that effect.

While at the Iowa Code Camp, I was talking to someone about the MyTube code and I casually mentioned that you could take the solution I had built and you could quickly build a WPF client to show Silverlight Streaming content.  I boastfully said I could have it up and running in about 20 minutes.  Well, it took me longer than that and I still didn't put the minimal "fit and finish" work I did on my Silverlight version, but it works.  The thing that slowed me down the most was that my web hoster does not like non-browsers pulling down resources, even something as innocuous as an ATOM feed.  Once I figured out what was going on, I had to add "browser-like" header information to the request coming out of my WPF app.  After that, I wrestled with trying to get a progress indicator working as the video played, but after 10 minutes I punted since it is not as straightforward as it is in Silverlight.  Hopefully that is something that will be fixed soon because the only solution I could find was a royal pain compared to what Silverlight provides out of the box.  WPF and Silverlight are certainly cousins, but there are a few things that are different enough to drive you a bit batty.

If you are interested in the bare bones SLS via WPF app, you can download it here.  

Tags: , ,

SpaghettiCode

Cracking the Silverlight Streaming Direct Content Access Code - Part II

5/3/2008 10:00:43 PM

So I am banging around on what I have started to call MyTube looking at different methods for accessing media stored in Silverlight Streaming. I got a question from someone that had read my original post that asked if there was anything I could do to help them out if they could not host *.ashx code on their web site but they still wanted to access SLS content and play it in their own customized browser.  I noodled on it a bit and figured that if all they needed was access to their own content, there really was nothing stopping me from letting them leverage the work I had done on my site via a redirect.  So I am happy to announce that you can now get access to your own Silverlight Streaming content by using this url:

http://www.slickthought.net/slickthoughttv/slsredirect.ashx?app=<your SLS Account ID>&app=<your SLS Application Name>&file=<content file name>

For example, if I wanted to get access to my Des Moines launch video from any site on the Internet, I would set the Source property on my Silverlight media element to:

As a matter of fact, you can click on that hyperlink and it will launch Windows Media Player for you!  The savvy among you may also realize that with a little work, it opens up another scenario for you as well - take a guess in the comments section and I will let you know if you are right.

DISCLAIMIER:  I do not make any guarantees as to the availability, reliability, accurateness, responsiveness or any other quality of service indicator for this application (slsredirect.ashx).  This application may be modified or removed at any time. It is for demonstration purposes only and should not be relied upon for anything other than a demonstration.

The code behind the SLSRedirect.ashx is shown below:

public void ProcessRequest (HttpContext context) {

        string account = context.Request.QueryString["account"];
        string app = context.Request.QueryString["app"];
        string file = context.Request.QueryString["file"];       
        string httpStream = string.Empty;

        if (account != null)
        {
            httpStream = SilverlightStreaming.GetMediaStream(account, app, file);
            context.Response.Redirect(httpStream);
        }
        else
        {
            context.Response.StatusCode = 400;
            context.Response.End();
        }
    }

What makes this even cooler is I can now publish my own Video Syndication Feed to let people see what is available and provide  them direct links to my media.  Click here to see a sample of my own feed and see how you can now click on the media links and immediately start playing content:

 

Those feeds are pretty much brute force implementations and not what I would have for a final feed format but it demonstrate how you can publish your videos to be shared and consumed by others in their own players.  If you want to have multiple videos per syndication item (something SLS would allow you to do), you pretty much have to go with an ATOM feed.  But most podcast readers seem to use RSS which only allows one enclosure per item.  If you want to use RSS, you will need to only upload one piece of media per SLS application or else the extra media will not show up in the RSS feed.

Tags: ,

SpaghettiCode

Cracking the Silverlight Streaming Direct Content Access Code

4/29/2008 12:09:00 AM

I'm working on my presentation for the Iowa Code Camp, and I once again bounced into something that has really frustrated me with Silverlight and Silverlight Streaming - getting access to SLS content directly, without having to go through one of the existing SLS options.  Basically, if I host mycoolvideo.wmv to SLS, I want to be able to get an URL to that media file and pass it to my Silverlight media element on my HTML page and have it play the video.

As it stands "out of the box", SLS provides four basic options for getting to your Silverlight application.  The first three assume you have loaded an actual Silverlight application (manifest, XAML, script, etc.) to SLS.  The first one, and the one I have used most often, is to place an iFrame in your web page.  Something along the lines of:

<iframe src="http://silverlight.services.live.com/invoke/29367/AlmostLive1/iframe.html" mce_src="http://silverlight.services.live.com/invoke/29367/AlmostLive1/iframe.html" scrolling="no" frameborder="0" style="width:500px; height:400px"></iframe>

Option 2 is using a Live Control.  I won't go over the exact steps here, but its a three step process that ends up putting a remotely hosted SLS player on your page.  The third option is to provide a download of  your application such as http://silverlight.services.live.com/invoke/29367/AlmostLive1/application.html.  This is really intended for a kind of "desktop install" sort of experience.

Of these three "application" options, iFrame is the easiest but it forces you to upload an entire Silverlight app for each video. The downside is that if you want to have a themed media player experience on your web site, you are at the mercy of the style the media player has in the uploaded application.  Sure, I could make sure I upload the same player that fits into my overall site design over and over again, but what happens if I want to change my design.  I would have to go back and update all of those applications in SLS.  A royal pain.

Recently, SLS added a fourth option.  This option allows you to upload only the media you want to host in SLS (currently limited to WMV only), and not an entire SLS application.  This, at first, sounded like the perfect solution until I realized that the only way to play that media was to use another iFrame solution, such as

<iframe src="http://silverlight.services.live.com/invoke/29367/DSMHHH/iframe.html" scrolling="no" frameborder="0" style="width:500px; height:375px"></iframe>

This iFrame will then play your video using a standard media player design as shown below:

slickthoughtproductions

Again, this is not what I want since I have no control over the style of the player.  What I really want, and based on some web searches it seems like quite a few others do as well, is a way to design my own Silverlight player, host that player directly into my web page, and then reference only media that is stored in the SLS cloud.  Essentially, I want to write:

mediaElement.Source = "streaming:/29367/DSMHHH/DSM-HHH.wmv

Now I can change the look and feel of my site without having to update SLS but I get all the other advantages of hosting my media in SLS. 

There is a partial solution to this problem already.  I will let you, dear reader, read all the gory details on your own.  Laurent Kempé has a very nice article on how to get this solution up and running and it actually served as the inspiration for the solution I have come up with.  The basic process is replacing the standard silverlight.js file that most Silverlight tools provide and use http://agappdom.net/h/silverlight.js.  This new script file provides a javascript function called createObjectEx that you use in place of the normal createObject when instantiating your Silverlight application on a given web page.  The big thing that createObjectEx provides is a way to pass in initialization parameters, most importantly one in the format of "streaming:/<acctid>/<appname>/<filename>".  This is resolved to a valid url (the actual media file url changes over time, preventing you from storing content urls and using them later) for your content and is then assigned your newly created Silverlight media element.  This works ok, but it's not as nice as being able to just ask SLS for a valid url and then assigning that url to your media element since it requires a new media element be created with each all to createObjectEx.

In what is one of the biggest oversights I can imagine, it seems that neither the Silverlight team or the SLS team thought anyone would want to be able to just get a streaming url for a piece of content directly.  The most obvious scenario would look something like 1) launch my Silverlight app, 2) query SLS for a list of applications and associated media files, 3) display that list to the user in my Silverlight control, 4) user picks an application, 5) ask SLS for a current http address for a given media file from that application, 6) assign that url to the Silverlight media player for playback.  Of course, even simpler would have been for the Silverlight media element to accept a Source property in the streaming:/<acctid>/<appname>/<filename> format and have it resolve a good url on its own.  Alas, neither option was provided.  Since SLS came out a bit after Silverlight 1.0 (IIRC), I can forgive the lack of support in the SL 1.0 media element.  I have no idea what the SLS guys were thinking.  Even more surprising, is that as of Silverlight 2 Beta 1, the media element has not been updated to support this scenario either.  Nor can I find any official statements saying it will be since folks have already started to repeat the same question but now with SL 2 as the player.

I've been thinking of and tinkering with various hacks around this problem for a while but none of them worked they way I wanted or provided the simplicity I wanted.  I had really assumed that Silverlight 2 Beta 1 would solve this problem, and that was my thinking when I submitted the session abstract for the Code Camp.  Once I sat down to start building my content, it was very disappointing to find that I was SOL as far as getting the desired functionality I was expecting from SL 2.  Needless to say, it was a) very disappointing, b) the risk you take by assuming a feature will be in a Beta, and c) meant I was probably going to have to finally settle on some nasty, clunky hack that would belittle me in the eyes of the Code Camp attendees.  Certainly not what would be expected of the world's only self-proclaimed .NET Sex Symbol!

I figured I would give the ol' Internet one more surf to see if there was anything new on the topic before I got my hack on.  That is when I stumbled on Laurent's article.  The big "AHA" moment came when Laurent talked about how the createObjectEx actually returns a piece of javascript under the covers.  The returned javascript looks like this:

SLStreaming._StartApp("bl2", null
, {}, []
, [http://msbluelight-0.agappdom.net/e1/d/4065/8.w/63325188000/0.UZcUXMfJgIK0I0HcP-SQGzhvvVE/livewriterdemo.wmv]);

Well, well, well, there is a current and valid URL to the media I so desperately crave right there!  That made the light bulb click on.  You never see that bit of code when you check out your browser's source since its all handled under the covers but the foundation was there to get at the url I wanted.  I started digging into the silverlight.js file and figured out how createObjectEx went about it's business. After that, it became pretty easy to figure out what needed to be done.

The heart of the solution starts with recognizing that createObjectEx submits the streaming :/ parameter to services hosted at http://silverlight.services.live.com/invoke.  The GET request that returns the piece of javascript looks like this:

http://silverlight.services.live.com/invoke/local/starth.js?id=bl2&u=1209235530389&p0=/29367/DSMHHH/DSM-HHH.wmv

Let's break this down real quick so we know what we are looking at:

  • id=bl2 - To be honest, I am not really sure what this is.  The initial value will always be bl2 and in the silveright.js implementation the only part of the id that may change is the integer - bl is a constant.  Leaving it as bl2 doesn't seem to break anything.
  • u=1209235530389  -  u is equal to the total number of millseconds since the Unix Epoch (Jan 1, 1970).  I assume this is a way to randomize the generated URL across various servers for load balancing and also to give some kind of lifetime to the request.  and it lets you use the term Unix Epoch with friends and family.
  • p0=/29367/DSMHHH/DSM-HHH.wmv - this is the path to the content I am looking for.  Basically, my account ID (29367), application name (DSMHHH), and the media file I am looking for (DSM-HHH.wmv)

So basically, all I had to do was construct an xmlHttpRequest (javascript) or a WebClient (.NET) and pass in the appropriate URL, take the snippet of javascript that is returned to me, and RegEx it looking for my content URL.

javascript C#
function GetMediaUrl(AcctID, AppName,FileName)
    {
        var baseAddress = "http://silverlight.services.live.com/invoke/local/";
        var url = baseAddress +
                  "starth.js?id=bl2" +
                  "&u=" + (new Date().valueOf()) +
                  "&p0=/" + AcctID + "/" + AppName + "/" + FileName;
       
        if (window.XMLHttpRequest)
        {
           var oReq = new XMLHttpRequest();
           oReq.open("GET", url,false);
           oReq.send();
        }

        var r, re;                    
        re = new RegExp("http:.+\.wmv","i"); 
        r = oReq.responseText.match(re);

}

WebClient client = new WebClient();

client.BaseAddress = "http://silverlight.services.live.com/invoke/local/";

TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
double timestamp = t.TotalMilliseconds;
string milliseconds = timestamp.ToString().Split(new char[] { '.' })[0];
string myUri = string.Format("starth.js?id=bl2&u={0}&p0=/{1}/{2}/{3}", milliseconds, acctID, appID, mediaFile);
string response = client.DownloadString(myUri);

Match mediaMatch = Regex.Match(response, @"http:.+\.wmv");
string mediaUrl = mediaMatch.Value;

You could certainly add more error checking code, make the javascript async, and other improvements, but these examples get the point across.  Of course, neither of these examples will work for a hill of beans if you try and use them in your web page or Silverlight app!!!  Why?  Cross-site scripting limitations, my friends.  Tim Heuer posted about the fact the SLS does not have a cross domain policy file (that policy file would let the above code work like a champ) and wonders why anyone would want it?  Well, Tim (who's greatness and tech wizardary far surpasses my own), I want to get my media stream!!! ;-)  Without that SLS cross domain policy file, we are forced to take our solution to the server and essentially remote proxy calls from our client to the SLS service.  Not ideal and if you don't have the ability to run your own code on your host server then this solution won't work.  All the more reason to harp on the SLS folks to get a cross domain policy file in place!

So with that in mind, I will show you what I banged out (banged being the operative word) to be that remote server proxy.  Disclaimer:  This code is totally whipped out on the fly.  It absolutely is spaghetti code.  It's a way for me to show you how to get the job done.  You could (and probably should) come up with something cleaner, more intuitive, <pick your better approach description and insert here>.  Probably the first thing I would change would be to put the output into some kind of syndication format like RSS or ATOM.  You could then publish your "TV channel" and others could consume it and play it pretty easily.  The only thing I haven't figured out, and it could certainly be because I am not a RSS/ATOM guru, is how to account for that fact that one "item" (or in our case SLS application) can have more than one media file.  It is different from a podcast RSS feed where one item equals one enclosure equals one audio file.  I'll let some one else figure it out.

Below are the two functions that are the heart and soul of my solution. Note, you can get all of the code I used to build this sample here.

string ExecuteSLSRequest(string url, string acctID, string password)

    {
        if (acctID == null || password == null)
            throw new SecurityException("Missing AccountID and/or Password");

        HttpWebRequest httpRequest =
                (HttpWebRequest)HttpWebRequest.Create(SLSSecureRoot + acctID + "/" + url);
        byte[] userPass = Encoding.Default.GetBytes(acctID + ":" + password);
        string basic = "Basic " + Convert.ToBase64String(userPass);
        httpRequest.Headers["Authorization"] = basic;

        HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
        Stream httpStream = httpResponse.GetResponseStream();
        StreamReader streamReader = new StreamReader(httpStream);

        return streamReader.ReadToEnd();
    }

and

string GetMediaStream(string appname, string filename)

{
    TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
    double timestamp = t.TotalMilliseconds;
    string milliseconds = timestamp.ToString().Split(new char[] { '.' })[0];

    string targetUri = string.Format("invoke/local/starth.js?id=bl2&u={0}&p0=/{1}/{2}/{3}", milliseconds, SilverlightStreaming.Account.AccountID, appname, filename);

    HttpWebRequest httpRequest =
            (HttpWebRequest)HttpWebRequest.Create(SLSMediaServiceRoot + targetUri);

    HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
    Stream responseStream = httpResponse.GetResponseStream();
    StreamReader streamReader = new StreamReader(responseStream);

    string scriptResponse = streamReader.ReadToEnd();

    Match mediaMatch = Regex.Match(scriptResponse, @"http:.+\.wmv");
    string mediaUrl = mediaMatch.Value;
    return mediaUrl;
}

ExcecuteSLSRequest is used to do secure communication with SLS.  This provides access to the application list and the file list per application.  It is driven by the url you pass in, of which you will only be passing in two - empty (to get a list of applications) or application name, which will get you a list of all files in the application.  There is entire SLS REST API for managing your application, but I don't care about that right now. I just exposed an Applications property off of my helper class to fetch all of the applications and their associated media files.  The property uses ExecuteSLSRequest to build a list of applications.  GetMediaStream takes an appname and a filename and talks to SLS to find a current, valid http address for the given media file.  Pretty easy and useful in it's own right. I'm already thinking about how you could use this to redirect clients to download content directly from SLS - podcasts for example.  Can you say free streaming AND free storage!!!  I think you can.

As a simple example of using my helper class, take a look at SLSApplications.ashx below:

public class SLSApplicationsHandler : IHttpHandler {
    const double expireTime = 1;  // expressed in hours
    public void ProcessRequest (HttpContext context) {
        XElement slsXml = null;
        if (context.Cache["sls"] == null)
        {  
            SilverlightStreaming.Account.AccountID = "<yourAccountID>";
            SilverlightStreaming.Account.Password = "<yourAccountKey";

            Dictionary<string, SLSApplication> apps = SilverlightStreaming.Applications;

            slsXml = new XElement("ContentList",
                    from a in apps.Values
                    select new XElement("Content",
                        new XAttribute("Name", a.Name),
                            from m in a.Media
                            select new XElement("File",
                                new XAttribute("Name", m.Name),
                                new XAttribute("Size", m.Size))));

            context.Cache.Add("sls",
                slsXml,
                null,
                DateTime.Now.AddHours(expireTime),
                System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.CacheItemPriority.Normal,
                null);

        }
        else
            slsXml = (XElement)context.Cache["sls"];

        context.Response.ContentType = "text/xml";
        context.Response.Write(slsXml.ToString());
    }
    public bool IsReusable {
        get {
            return false;
        }
    }
}

It uses my SilverlightStreaming helper class to get the apps and files as XML from SLS and then uses LINQ to shape that data into the format I want.  I use the ASP.NET cache to store the result since it is unlike to change all that often.  The results are returned as XML like this:

xml

I have another file, SLSMediaStream.ashx, that returns a valid http url when you pass in a query string containing the appname and media file you want to access - http://somehost.com/SLSMediaStream.ashx?appname=xyz&filename=abc.wmv. The result is returned as a simple string (not XML).  The code is shown below:

public class SLSMediaStream : IHttpHandler {


    public void ProcessRequest (HttpContext context) {


        string app = context.Request.QueryString["appname"];
        string file = context.Request.QueryString["filename"];


        string httpStream = SilverlightStreaming.GetMediaStream(app,file);
        context.Response.ContentType = "text/plain";
        context.Response.Write(httpStream);


    }


    public bool IsReusable {
        get {
            return false;
        }
    }
}

You can check out a live version of SLSApplicaitons.ashx here (returns all of my Silverlight apps and files) and a Silverlight 2 Beta 1 "video player" here (this one is super lame - working on a better one for SlickthoughtTV and DeveloperMinute.com.  You could also do it in Silverlight 1.0 but I like SL 2 much better <grin/>).  I'm not a javascript guy at all so I didn't put together a javascript web page to work with the "API" and since you need some kind of play back capability anyway, I didn't see the point. You can get the source here.

Hope you found it useful.

Tags:

Magenic presents: Deep Dive Building Applications Using WPF and Silverlight

4/15/2008 1:02:00 PM

logo Magenic will be hosting a great event on using WPF and Silverlight to build next generation UIs.  The event will be at the Microsoft Office in Bloomington, MN on Thursday, April 24th.  For details and registration, click here.  The official promo blurb below:

Join Rockford Lhotka, creator of the popular CSLA .NET framework, and Anthony Handley, user experience specialist at Magenic, as they walk through the process of creating a next generation user experience on top of an n-tier object oriented business layer.  Leveraging their latest project, they’ll show you what is easier and harder than expected.

Featured Products/Topics: Silverlight, Windows Presentation Foundation

Recommended Audiences: Technology Executives, IT Managers, IT Professionals, CIO, CTO, IT Directors, Solution Architects, Software Developers, Technical Decision Makers, Developers

Tags: ,

Headlines

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

About the author

Jeff Brand Jeff Brand

This is the personal web site of Jeff Brand, self-proclaimed .NET Sex Symbol and All-Around Good guy. Content from my presentations, blog, and links to other useful .NET information can all be found here.

E-mail me Send mail


Calendar

<<  June 2013  >>
MoTuWeThFrSaSu
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

View posts in large calendar

My Twitter Updates

XBOX
Live

Recent comments

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2013

Sign in