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:
- OpenSuse 12.1 as our server OS
- Lighttpd and its flv module
- FLV-Scrubber
- yamdi
- DSpace
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 < 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 < 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.
Dear Evelthon,
Hope this mail finds you well,
We are working on Video Streaming at Dspace 3.2 for Indian Knowledge Corporation,Pune. In earlier version it supports video-downloading through plugin,this new feature to be incorporated.Please let me know how to reduce downloading time at the time of streaming that would be independent from any thing like hardware.software,bandwidth.
Kind regards,
Rajesh Parashar
IKC-Pune
Hello Rajesh,
I have not tried moving to 3.2. I suggest looking into Flowplayer, Flowplay documentation refers to seek() function. As stated, it “Seeks to the specified time of the current clip, in seconds. If using default URL-based streaming provider then the buffer must have loaded to the point of seeking. When using streaming server this is not required.”