Silverlight-spelare i Sharepoint Field Control

Igår körde jag ett pass på Sharepoint-utvecklardagen på Sommarkollo som handlade om hur du kan integrera Silverlight i din Sharepoint-lösning. Min ppt-presentation från passet hittar du här.

Ett Visual Studio 2005-projekt med koden för den Field Control som jag visade samt en katalog med den Javascript/XAML-kod som användes hittar du här (i lösningen har jag använd en projektmall från VS2005 Sharepoint Extensions 1.0).

I min demo skapade jag först en en Silverlight-videospelare utifrån en befintlig videofil med hjälp av verktyget Expression Encoder.

När du skapar en Silverlight-spelare med Expression Encoder så får du föjande filer genererade:

EMEFiler

Default.html är en testsida som visar hur du refererar de Javascript och skapar det funktionsanrop som krävs för att instansiera Silverlight-spelaren i en webbsida. Koden från den anpassar jag och använder i min Sharepoint Field-kontroll för att instansiera spelaren i min Sharepoint-sajt.

De olika Javascript-filerna innehåller funktionalitet som används av spelaren (BasePlayer.js, MicrosoftAjax.js, player.js, PlayerStrings.js,  StartPlayer.js) samt funktionalitet för att känna av vilken webbläsare som användaren kör och rendera motsvarande <OBJECT> -taggar (Silverlight.js).

Expression Encoder spottar även ut en project.csproj vilket gör att du direkt kan öppna spelaren i Visual Studio eller Expression Blend om du vill göra anpassningar av den.

Den enda fil vi är intresserade av att editera i detta fallet är StartPlayer.js - d.v.s. den fil som innehåller funktioner för att initialisera spelaren, bestämma vilken videofil som ska spelas och vilken gränssnittsdefinition (XAML-fil) som ska användas. 

I StartPlayer.js byter vi ut den hårdkodade referensen till mediafilen (DieHard_320x180.wmv) till ett Javascript-funktionsanrop, ett funktionsanrop som vi senare ska generera i runtime i vår Field Control -  alltså:

function get_mediainfo(mediainfoIndex) {

    switch (mediainfoIndex) {

        case 0:

            return { "mediaUrl": "DieHard_320x180.wmv",

                      "placeholderImage": "",

                      "chapters": [

                                  ] };

                         

        default:

             throw Error.invalidOperation("No such mediainfo");

     }

}

Ändras till:

function get_mediainfo(mediainfoIndex) {

    switch (mediainfoIndex) {

        case 0:

            return { "mediaUrl": get_mediaurl(),

                      "placeholderImage": "",

                      "chapters": [

                                  ] };

                         

        default:

             throw Error.invalidOperation("No such mediainfo");

     }

}

För att sökvägen till vår XAML-fil att stämma i SharePoint måste även referensen till den ändras. Jag satte även en fast höjd och bredd på spelaren för att förhindra att den "trycktes ihop" i min Sharepoint-layout.

Alltså:

function StartPlayer_0(parentId) {

    this._hostname = EmePlayer.Player._getUniqueName("xamlHost");

    Silverlight.createObjectEx( { source: 'player.xaml',

                                        parentElement: $get(parentId ||"divPlayer_0"),

                                        id:this._hostname,

                                        properties:{ width:'100%', height:'100%', version:'1.0', background:'transparent', isWindowless:'true' },

                                 events:{ onLoad:Function.createDelegate(this, this._handleLoad) } } );

    this._currentMediainfo = 0;

}

Ändras till:

function StartPlayer_0(parentId) {

  this._hostname = EmePlayer.Player._getUniqueName("xamlHost");

    Silverlight.createObjectEx( { source: 'https://www.dinsajt/SLPlayer/player.xaml',

                                        parentElement: $get(parentId ||"divPlayer_0"),

                                        id:this._hostname,

                                        properties:{ width:'640', height:'480', version:'1.0', background:'transparent', isWindowless:'true' },

                                        events:{ onLoad:Function.createDelegate(this, this._handleLoad) } } );

    this._currentMediainfo = 0;

}

Dessa är de enda ändringar du behöver göra i filerna från Expression Encoder. Jag skapade därefter ett virtuellt directory, SLPlayer, i den Sharepoint-sajt som skulle innehålla spelaren och kopierade dit alla filer utom project.csproj, default.html och mediafilen.

Här har vår Sharepoint-guru Pontus Haglund föreslagit ett alternativ: i Sharepoints 12 Hive (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12) finns en katalog som heter template\layouts. Allt som läggs i layouts kan användas av alla Sharepoint-sajter på din server eftersom alla Sharepoint IIS-sajter mappar upp denna katalog som ett virtual directory kallat _layouts. Detta kan vara en fördel om du t.ex. vill återanvända din spelare i flera olika sajter).

Mediafilen - DieHard_320x180.wmv - laddade jag upp till till ett dokumentbibliotek i Sharepoint så att jag sedan kunde välja den från biblioteket via min Field Control när jag editerade en sida som innehåller kontrollen.

För att Sharepoint ska kunna spara sökvägen till den mediafil som väljs i gränssnittet krävs att vi lägger till ett nytt fält i Sharepoint av typen "Hyperlink with formatting and constraints for publishing"

field

Om du väljer den kanske lite mer frekvent använda typen "Hyperlink or Picture" kommer du få felet: "Failed to get value of the "MediaFileURL" column from the "Hyperlink or Picture" field type control. Value cannot be null" när du försöker testa demo-koden, så försäkra dig om att fälttypen blir korrekt. ECM-teamet har skrivit en mycket bra blog-post om hur Field Controls, kolumner och bibliotek i Sharepoint hänger ihop.

För att testa spelaren krävs följande steg:

  • Kompilera Visual Studio-projektet och lägg SLFieldControl.dll i WSS-sajtens bin-katalog

  • Editera den aspx-sida (förslagsvis med Sharepoint Designer) som ska innehålla kontrollen. Lägg först till ett "Register prefix" till sidan för att registrera kontrollens tag-prefix -

    <%@ Register Tagprefix="MyFieldControl" Namespace="Microsoft.SharePointServer.SLSamples" Assembly="SLFieldControl, Version=0.0.0.0, Culture=neutral, PublicKeyToken=02eca1c16b8ae488" %>

    Koden för att sätta in kontrollen där du vill placera den i din aspx ser ut så här:
     

    <MyFieldControl:SLFieldControl id="SampleSLFieldControl" runat="server" FieldName="MediaFileURL"></MyFieldControl:SLFieldControl>

    Lägg till kontroll till Safe Controls i web.config:

    <SafeControl Assembly="SLFieldControl, Version=0.0.0.0, Culture=neutral, PublicKeyToken=02eca1c16b8ae488" Namespace="Microsoft.SharePointServer.SLSamples" TypeName="*"/>

  • För att Silverlight-spelaren ska kunna ladda gränssnittsdefinitionen (XAML-filen) måste även en konfiguration göras i IIS - du måste lägga till en ny mimetype för XAML genom att

    • Öppna IIS Manager -> Properties på din webbsajt -> Under fliken HTTP Headers väljer du MIME Types och New. Extension ska vara .xaml och MIME Type ska vara application/xaml+xml

Nu ska det gå att testa din sida genom att gå in på sajten och din sida, välja editeringsläge och sedan välja en mediafil från ditt bibliotek genom "Select a media file":

picker

Om allt fungerar som det ska laddas sidan om när du valt din medafil och Silverlight-spelaren renderas och startas.