Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
SilverLight Interop with Flash/Flex (flashlight?)

imageWhile the marketers and academics focus on the battle between silverlight and flash/flex, here in Mike's Mad Scientist Labs we've been focused on making the two work together.  Like our founder (Dr. Frankenstein) the implementation is a bit rough, but we can proudly proclaim, "It's Alive!"

Before I get into my lab notes, let's talk about the basic approach and why.  Silverlight is awesome, but it's the new kid and developers won't always be able to replace existing flash apps with silverlight, so a migration path is needed.  Also, sliverlight isn't going to play FLV - flash's proprietary video codec - anytime soon, and there is a multi-ton of video in this format.  If silverlight supported the WPF Frame element, which can render any HTML, things would be better, but as of today Frame isn't supported.

The goal: a silverlight control list a choice of FLV videos, let the user choose one, and play that video in a flash control.  To communicate between the controls we'll use javascript. This approach is very similar to Jeff Prosise's post on silverlight interop, in which javascript allowed two silverlight controls to communicate.

The code and XAML to the Silverlight control is very simple:

<UserControl x:Class="MyVideos.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <ListBox x:Name="lbVideos" SelectionChanged="lbVideos_SelectionChanged">
        <TextBlock>Loading...</TextBlock>
    </ListBox>
</UserControl>
public partial class Page : UserControl {
    public List<String> OnPlayHandlers { get; set; }

    [ScriptableMember]
    public void addOnPlayHandler(String functionName) {
        OnPlayHandlers.Add(functionName);
    }

    protected void OnPlay(String video) {
        foreach (String h in OnPlayHandlers)
            HtmlPage.Window.Invoke(h, video);
    }

    public Page() {
        InitializeComponent();
        OnPlayHandlers = new List<string>();

        HtmlPage.RegisterScriptableObject("Page", this);

        lbVideos.Items.Clear();
        String[] items = new String[] { "hampster.flv", 
                                        "smb_flute.flv", 
                                        "starwarskid.flv" };
        foreach (String s in items)
            lbVideos.Items.Add(s);
    }

    private void lbVideos_SelectionChanged(object sender, SelectionChangedEventArgs e) {
        OnPlay(lbVideos.SelectedItem.ToString().Replace("Video: ",String.Empty));
    }
}

The [ScriptableMember] attribute exposes this method to javascipt, and  HtmlPage.RegisterScriptableObject maps the method name, which will end up being SilverlightControl.Page.addOnPlayHandler.  I borrowed the common event handler pattern so it's easy to have multiple javascript methods fire when the user clicks a video - I also didn't want to make any assumptions about the flash control that would play the video.  HtmlPage.Window.Invoke is the real magic, which invokes the actual javascript function when a video is clicked.

The ASPX/HTML is also pretty light:

<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<asp:Silverlight ID="slMyVideos" runat="server" Source="~/ClientBin/MyVideos.xap"
    Version="2.0" Width="400px" Height="300px" OnPluginLoaded="slMyVideos_Loaded">
</asp:Silverlight>
<OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
        WIDTH='320' HEIGHT='260' id='FLVplayer'>
    <PARAM NAME=movie VALUE='flvplayer.swf'>
    <PARAM NAME=allowScriptAccess VALUE=sameDomain>
    <PARAM NAME=flashvars VALUE='file=dummy.flv&autostart=true&enablejs=true'>
    <EMBED src='flvplayer.swf' NAME='FLVplayer' 
           swliveconnect='true' WIDTH='320' HEIGHT='260'
           TYPE='application/x-shockwave-flash'
           FLASHVARS='file=dummy.flv&autostart=true&enablejs=true'>
    </EMBED>
</OBJECT>

I'm using the asp:Silverlight tag included with the silverlight 2.0 beta 1 tools to handle generating the object tags for the silverlight control.  I wrote out the object and embed tags for the flash player to show exactly what's going on (since I assume most of my reader are not Flash developers), but in a production app I recommend using the open source SWFObject project for better cross browser support.

The critical lines for flash are allowScriptAccess and swliveconnect which enable javascript control of the flash.  I'm using the open source FLVplayer by Jeroen Wijering, which requires a flashvar of enablejs=true in addition to the above.  The FLVplayer has a rich Javascript API for controlling the play, so the last step is to add some javascript to connect the OnPlay event of the silverlight control to load and play the video in the flash control.

<script type="text/javascript">

    function slMyVideos_Loaded() {
        var sl = $get('<%= slMyVideos.ClientID %>');
        sl.Content.Page.addOnPlayHandler('OnPlay');
    }

    function getFlashMovieObject(movieName) {
        if (document.embeds && document.embeds[movieName])
            return document.embeds[movieName]; 
        else
            return $get(movieName);
    }    

    function OnPlay(video) {
        flvplayer = getFlashMovieObject('FLVplayer');
        try {
            flvplayer.loadFile({file: video});
            flvplayer.sendEvent('playitem', 0);   
        }
        catch(e) {
            alert(e.description);                
        }
    }

</script>

The slMyVideos_Loaded function is called when the silverlight control has fully loaded (by the OnPluginLoaded="slMyVideos_Loaded" set in the silverlight tag).  The getFlashMovieObject function determines if the browser is using the embed version or the object version of the flash control, and returns the correct reference.  The OnPlay function is called by silverlight when the user clicks an item in the list and uses the FLVPlayer's API to load and play the video.

It is possible to run Javascript right from flash and silverlight to talk directly to one another without the need for this glue code on the page.  This would tightly couple the two controls, and isn't my cup of tea, but I can see some instances where that would be a desired behavior.

Now back to the lab to see what else we can bring to life...


Posted 04-21-2008 2:42 PM by Michael C. Neel

[Advertisement]

Comments

Scott Barnes wrote re: SilverLight Interop with Flash/Flex (flashlight?)
on 04-21-2008 8:14 PM

LOVE IT..  I did a project a while back called "Project Harmony" where I showed both being used. It can be found at my blog:

blogs.msdn.com/msmossyblog

-

Scott Barnes

Product Manager

Microsoft.

Dew Drop - April 22, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - April 22, 2008 | Alvin Ashcraft's Morning Dew
on 04-22-2008 10:15 AM

Pingback from  Dew Drop - April 22, 2008 | Alvin Ashcraft's Morning Dew

Marcus wrote re: SilverLight Interop with Flash/Flex (flashlight?)
on 04-22-2008 3:44 PM

Nice! Jason over at BLITZ ran a similar experiment a few weeks back entitled "<a href="labs.blitzagency.com YouTube FLV Videos with Silverlight 2.0</a>"

That YouTube API sure opened up a lot of doors. And I think Silverlight really got it right in the programming model how XAML is an extension of the DOM

webdesign wrote re: SilverLight Interop with Flash/Flex (flashlight?)
on 11-26-2008 10:14 AM

Nice flash code! Thanks

Web video player wrote re: SilverLight Interop with Flash/Flex (flashlight?)
on 02-28-2011 2:37 AM

Code reference was really helpful for me, i got the exact stuff i was searching for...... Thanks for the share! You are a time saver :)

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)