Streaming video in dspace might seem like a daunting task, but if you spend some time researching your options, it might not be as difficult as it sounds.Our goal is to have a working flash video player in a record’s summary-view (XML UI – Mirage theme 1.7.0).  The ingredients we will be using in today’s recipe are:

This tutorial assumes that the flash “streaming” server is on a different box than DSpace. Do note that this tutorial does not describe RTMP streaming, as that requires a flash server. Here, we investigate the steps needed for pseudo streaming with seeking ability.

 

Video server

Start-up yast and install lighttpd. The flv module is installed by default. All you need to do is enable it in lighttpd’s configuration file. Add a reference for the flv conf file in /etc/lighttpd/modules.conf

##
## mod_flv_streaming
##
include "conf.d/flvstreaming.conf"

You then need to create /etc/lighttpd/conf.d/flvstreaming.conf and place the following inside:

server.modules += ( "mod_flv_streaming" )
flv-streaming.extensions = (".flv")

So far, we ‘ve prepared our video server. We now need to prepare our dspace instance to consume a flash video.  This requires an embedded player. We will be using FLVScrubber.  Alternatively, one could use Flowplayer, though I have not tested it.

 

Adding a video player to dspace

Copy FLVScrubber.swf in /[dspace-src]/dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/themes/Mirage/lib/FLVScrubber.swf.  We then need to do some changes in item-view.xsl. (located in /[dspace-source]/dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/themes/Mirage/lib/xsl/aspect/artifactbrowser) Locate the section seen below

<xsl:when test="$clause = 7 and $ds_item_view_toggle_url != ''">
 <p class="ds-paragraph item-view-toggle item-view-toggle-bottom">
 <a>
 <xsl:attribute name="href"><xsl:value-of select="$ds_item_view_toggle_url"/></xsl:attribute>
 <i18n:text>xmlui.ArtifactBrowser.ItemViewer.show_full</i18n:text>
 </a>
 </p>
 </xsl:when>
<!-- recurse without changing phase if we didn't output anything -->
 <xsl:otherwise>
 <!-- IMPORTANT: This test should be updated if clauses are added! -->
 <xsl:if test="$clause &lt; 8">
 <xsl:call-template name="itemSummaryView-DIM-fields">
 <xsl:with-param name="clause" select="($clause + 1)"/>
 <xsl:with-param name="phase" select="$phase"/>
 </xsl:call-template>
 </xsl:if>
 </xsl:otherwise>
 </xsl:choose>

and change that to read

<!-- Video player row -->
            <xsl:when test="$clause = 7 and (dim:field[@element='relation' and @qualifier='uri'])">
                <xsl:variable name="fileURL" select="./dim:field[@element='relation' and @qualifier='uri']"/>
                <div>
                  <!-- <h3>
                            <i18n:text>xmlui.dri2xhtml.METS-1.0.item-description</i18n:text>:
                        VIDEO GOES HERE2
                    </h3>-->
                    <object id="FLVScrubber" width="675" height="432" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0">
                        <param name="movie" value="/themes/Mirage/lib/FLVScrubber.swf"/>
                        <param name="bgcolor" value="#000000"/>
                        <param name="allowScriptAccess" value="sameDomain"/>
                        <param name="allowFullScreen" value="true"/>
                        <param name="flashVars" value="file=http://<FQDN>/{$fileURL}.flv"/>
                        <embed src="/themes/Mirage/lib/FLVScrubber.swf" bgcolor="#000000" width="675" height="432" name="FLVScrubber"
                               allowScriptAccess="sameDomain"
                               allowFullScreen="true"
                               flashVars="file=http://<FQDN>/{$fileURL}.flv"
                               type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"/>
                    </object>
                </div>
                <xsl:call-template name="itemSummaryView-DIM-fields">
                    <xsl:with-param name="clause" select="($clause + 1)"/>
                    <xsl:with-param name="phase" select="$otherPhase"/>
                </xsl:call-template>
            </xsl:when>

            <xsl:when test="$clause = 8 and $ds_item_view_toggle_url != ''">
                <p>
                    <a>
                        <xsl:attribute name="href">
                            <xsl:value-of select="$ds_item_view_toggle_url"/>
                        </xsl:attribute>
                        <i18n:text>xmlui.ArtifactBrowser.ItemViewer.show_full</i18n:text>
                    </a>
                </p>
            </xsl:when>

          <!-- recurse without changing phase if we didn't output anything -->
            <xsl:otherwise>
            <!-- IMPORTANT: This test should be updated if clauses are added! -->
                <xsl:if test="$clause &lt; 9">
                    <xsl:call-template name="itemSummaryView-DIM-fields">
                        <xsl:with-param name="clause" select="($clause + 1)"/>
                        <xsl:with-param name="phase" select="$phase"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:otherwise>

What did I just do by changing the XSL file? Well, basically we are looking for the metadata dc.relation.uri (hence dim:field[@element='relation' and @qualifier='uri'). You could use another metadata field if that does not suit you. Notice two lines mentioning file=http://<FQDN>/{$fileURL}.flv in our new XSL part above:

  • FQDN is the fully qualified domain name of the lighttpd server and should be set accordingly.
  • $fileURL is the data read drom dc.relation.uri. That is the location of the video file, withoud the file extension. This would be something like folder/any-sub-folder/filename

You now need to push your changes to tomcat. Switch to /[dspace-source] and do an mvn package. Then, move to /[dspace-source] /dspace/target/dspace-<version>-build.dir and do an ant update.

Stop your Web servlet container, copy any web applications from /dspace/webapps/ to the appropriate place for your servlet (if needed) and Start up your Web servlet container again.

 

Preparing a video file

 

Converting video to flv format

In my case I had a bunch of Windows Media Videos. They had to be converted to flv format. You will need to install ffmpeg and yamdi.  Start by using  ffmpeg, like below:

 ffmpeg -i <filename>.wmv video.flv

Ffmpeg can receive a multitude of parameters, but default settings work well enough in my case. To install ffmpef, add the Packman Essentials repository.

Adding meta data to the flv file

For our flv file to be seek-able, we need to add metadata to it. This is done with the usage of yamdi.

  yamdi -i video.flv -o video_md.flv -c "<text>"

<text> is a string (optional) that will be written into the creator tag.

Edit a record, add a dc.relation.uri field with the necessary folder/filename structure (remember, no file extension needed). Upload the relevant flv file to your lighttpd server and give it a try. If everything went as planned you should have a flash video player and the ability to seek through your video.