Thursday, November 10, 2011

Adding Media Player into Greenstone with jPlayer


"jPlayer" is a very nice javascript libraryto play various types of media files in browser using html 5 or flash. It can be integrated into the digital library software Greenstone (2.84) to enable it play various digital files. In this example, we enable the following types:
audio: mp3, m4a, oga
video: mp4(m4v), webmv, ogv, flv
(note: These are not all playable in every browsers due to the inconsistent media-type support across them.)

Let us assume the collection folder is {mycollection}="{greenstone folder}/collect/mycollection"

This example uses jPlayer 2.1.0, Greenstone 2.84.




  1.  Download jPlayer files and expand them into the "{mycollection}/script" folder
    ./add-on/jplayer.playlist.min.js
    ./add-on/jquery.jplayer.inspector.js
    ./Jplayer.swf
    ./jquery.jplayer.min.js
    
  2. Download one of the jPlayer skins (Blue Monday : Pink Flag) and expand all files except the *.psd file into the "{mycollection}/style" folder
    jplayer.pink.flag.css
    jplayer.pink.flag.jpg
    jplayer.pink.flag.seeking.gif
    jplayer.pink.flag.video.play.png
    
  3. Put a new player button image into "{mycollection}/images" folder.  I use this link. A small size one (48px or even 16px) is enough. One can even skip this step, if a "player" button or pure text is preferred.
  4. Create a new javascript file (playMedia.js) with the following text and put it into "{myCollection}/script" folder
    function playMedia(playerId,inspectorId,fullcontainerId,containerId,base,type,src){
    
     $("#"+fullcontainerId).show();
     $("#"+playerId).jPlayer("destroy");
          $("#"+playerId).jPlayer({
            ready: function () {
              $(this).jPlayer("pauseOthers").jPlayer("setMedia",media(type,base+"/"+src)).jPlayer("play");
            },
            errorAlerts:false,
            warnAlerts:false,
            swfPath: base+"/script/",
            supplied: type,
            cssSelectorAncestor: "#"+containerId,
            solution:"html,flash",
            ended:function(){
                
             $("#"+fullcontainerId).hide();
            }
          });
          $("#"+inspectorId).jPlayerInspector({jPlayer:$("#"+playerId)});
    }
    
    function media(type,src){
    
    switch (type.toLowerCase()){
    case "mp3":return {mp3:src}; break;
    case "oga":return {oga:src}; break;
    case "ogv":return {ogv:src}; break;
    case "m4a":return {m4a:src}; break;
    case "webmv":return {webmv:src}; break;
    case "m4v":return {m4v:src}; break;
    case "ogv":return {ogv:src}; break;
    case "flv":return {flv:src}; break;
    default:
    }
    }
    
    
  5. Start GLI of greenstone, open collection, paste the following into the "Collection Specific Macros" in "Format" tab. Alternatively, one can create a file "extra.dm" in "{myCollection}/macros" folder
    
    
    # extra.dm file
    # You can add collection specific macros in here
    # Lines starting with a '#' are comments.
    # Remember to include the package declaration
    
    package Style
    
    # will be applied to all pages 
    # add css style lines inside the style tags
    _collectionspecificstyle_ {
    <style type="text/css">
    div.jp-audio,
    div.jp-video {
      /* Edit the font-size to counteract inherited font sizing.
       * Eg. 1.25em = 1 / 0.8em
       */
      font-size:1.25em;
    \}
    </style>
    }
    
    # add any javascript functions here
    _collectionspecificscript_ { 
    $(document).ready(function(){
          $("#jquery-jplayer-1").jPlayer({
            ready: function () {
              
            \},
            errorAlerts:false,
            swfPath: "_httpcollection_/script/",
            supplied: "mp3,oga,m4a",
            cssSelectorAncestor: '#jp-container-1',
            solution:"html,flash",
            ended:function(){
            $("#jplayer-div").hide();
            \}
          \});
        $("#jplayer-inspector").jPlayerInspector({jPlayer:$("#jquery-jplayer-1")\});
    
    
    $("#jquery-jplayer-video").jPlayer({
            ready: function () {
             
            \},
            errorAlerts:false,
            swfPath: "_httpcollection_/script/",
            supplied: "webmv,ogv,m4v",
            cssSelectorAncestor: '#jp-container-video',
            solution:"html,flash",
            ended:function(){
            $("#jplayer-div-video").hide();
            \}
          \});
        $("#jplayer-inspector-video").jPlayerInspector({jPlayer:$("#jquery-jplayer-video")\});
    
        \});
    
    function play(type,src){
    type=type.toLowerCase();
    switch (type.toLowerCase()){
    case "mp3":
    case "oga":
    case "m4a":$('#jplayer-div-video').hide();
       playMedia("jquery-jplayer-1","jplayer-inspector","jplayer-div","jp-container-1","_httpcollection_",type,src);
       break;
    case "webmv":
    case "m4v":
    case "flv":
    case "ogv":$('#jplayer-div').hide();
       playMedia("jquery-jplayer-video","jplayer-inspector-video","jplayer-div-video","jp-container-video","_httpcollection_",type,src);
       break;
    default:
    \}
    \}
    
    }
    
    
    _pagescriptfileextra_{
    <link href="_httpcollection_/style/jplayer.pink.flag.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
    <script type="text/javascript" src="_httpcollection_/script/jquery.jplayer.min.js"></script>
    <script type="text/javascript" src="_httpcollection_/script/add-on/jquery.jplayer.inspector.js"></script>
    <script type="text/javascript" src="_httpcollection_/script/playMedia.js"></script>
    
    }
    
    
    
    _document:footer_ {
     _jplayer_
    </div> <!-- document:footer -->
    
    <div class="navarrowsbottom">
    _navarrowsbottom_
    </div>
    _endspacer__htmlfooter_
    }
    
    _jplayer_{
    
      <div id="jplayer-div" style="display:none;">
      <div id="jp-container-1" class="jp-audio" ">
    <div id="jquery-jplayer-1" class="jp-jplayer"></div>
      
    <div class="jp-type-single">
          <div class="jp-gui jp-interface">
            <ul class="jp-controls">
              <li><a href="javascript:;" class="jp-play" tabindex="1">play</a></li>
              <li><a href="javascript:;" class="jp-pause" tabindex="1">pause</a></li>
              <li><a href="javascript:;" class="jp-stop" tabindex="1">stop</a></li>
              <li><a href="javascript:;" class="jp-mute" tabindex="1" title="mute">mute</a></li>
              <li><a href="javascript:;" class="jp-unmute" tabindex="1" title="unmute">unmute</a></li>
              <li><a href="javascript:;" class="jp-volume-max" tabindex="1" title="max volume">max volume</a></li>
            </ul>
            <div class="jp-progress">
              <div class="jp-seek-bar">
                <div class="jp-play-bar"></div>
              </div>
            </div>
            <div class="jp-volume-bar">
              <div class="jp-volume-bar-value"></div>
            </div>
            <div class="jp-time-holder">
              <div class="jp-current-time"></div>
              <div class="jp-duration"></div>
              <ul class="jp-toggles">
                <li><a href="javascript:;" class="jp-repeat" tabindex="1" title="repeat">repeat</a></li>
                <li><a href="javascript:;" class="jp-repeat-off" tabindex="1" title="repeat off">repeat off</a></li>
              </ul>
            </div>
          </div>
          
          <div class="jp-no-solution">
            <span>Update Required</span>
            To play the media you will need to either update your browser to a recent version or update your <a href="http://get.adobe.com/flashplayer/" target="\_blank">Flash plugin</a>.
          </div>
        </div>
     
      </div>
      <div id="jplayer-inspector"></div>
    </div>
    
    <div id="jplayer-div-video" style="display:none;">
    <div id="jp-container-video" class="jp-video ">
        <div class="jp-type-single">
          <div id="jquery-jplayer-video" class="jp-jplayer"></div>
          <div class="jp-gui">
            <div class="jp-video-play">
              <a href="javascript:;" class="jp-video-play-icon" tabindex="1">play</a>
            </div>
            <div class="jp-interface">
              <div class="jp-progress">
                <div class="jp-seek-bar">
                  <div class="jp-play-bar"></div>
                </div>
              </div>
              <div class="jp-current-time"></div>
              <div class="jp-duration"></div>
              <div class="jp-controls-holder">
                <ul class="jp-controls">
                  <li><a href="javascript:;" class="jp-play" tabindex="1">play</a></li>
                  <li><a href="javascript:;" class="jp-pause" tabindex="1">pause</a></li>
                  <li><a href="javascript:;" class="jp-stop" tabindex="1">stop</a></li>
                  <li><a href="javascript:;" class="jp-mute" tabindex="1" title="mute">mute</a></li>
                  <li><a href="javascript:;" class="jp-unmute" tabindex="1" title="unmute">unmute</a></li>
                  <li><a href="javascript:;" class="jp-volume-max" tabindex="1" title="max volume">max volume</a></li>
                </ul>
                <div class="jp-volume-bar">
                  <div class="jp-volume-bar-value"></div>
                </div>
                <ul class="jp-toggles">
                  <li><a href="javascript:;" class="jp-full-screen" tabindex="1" title="full screen">full screen</a></li>
                  <li><a href="javascript:;" class="jp-restore-screen" tabindex="1" title="restore screen">restore screen</a></li>
                  <li><a href="javascript:;" class="jp-repeat" tabindex="1" title="repeat">repeat</a></li>
                  <li><a href="javascript:;" class="jp-repeat-off" tabindex="1" title="repeat off">repeat off</a></li>
                </ul>
              </div>
              
            </div>
          </div>
          <div class="jp-no-solution">
            <span>Update Required</span>
            To play the media you will need to either update your browser to a recent version or update your <a href="http://get.adobe.com/flashplayer/" target="\_blank">Flash plugin</a>.
          </div>
        </div>
        
      </div>
      <div id="jplayer-inspector-video"></div>
      </div>
    }
    
    
    
    
    A few notes for macro
    • "}" and "_" have to be escaped as "\_", "\}"
    • Two jPlayer instances and containers are created. One for audio and one for video.
    • A new macro "_jplayer_" is created.
    • One javascript function "play(type,scr)" is created. It plays media files (scr) with jPlayer.
  6. Import media files into Greenstone.  We need to preserve the file format of the media file to call the play(type,scr) function.  Therefore, we need to either extract file format automatically or enter the metadata manually.  "MP3 plugin" can handle mp3 file and create "ex.fileformat" metadata automatically.
     To extract other format automatically, a simple way is to config a new "UnknownPlugin", tick the "file_format" and enter the desired format for play function. Tick the "process_extension" and enter the real file extension (e.g. ogv) . Alternatively, tick "process_exp" and enter the regular express for the filename.  (e.g. m4v)  
    Process_extension File Format
    mp4(video)m4v
    mp4(audio)m4a
    m4vm4v
    m4am4a
    ogg(video)ogv
    ogg(audio)oga
    ogaoga
    ogvogv
    flvflv
    webmwebmv

    One can add some new process_extension if unconventional extensions are used. Due to the above limitation, for "*.mp4" or "*.ogg", one can use either all as video or audio. A mixture does not work.
  7. After all these, the folder structure looks like the following picture.
  8. Adding an image which invokes "play" function in the "onclick" event. For example, we change the "VList" in the "Format Features" at "Format" tab of GLI into (red part is added)
    <td valign="top">[link][icon][/link]</td>
    <td valign="top"">[ex.srclink]{Or}{[ex.thumbicon],[ex.srcicon]}[ex./srclink]</td>
    <td valign="top">[highlight]
    {Or}{[dc.Title],[exp.Title],[ex.Title],Untitled}
    [/highlight]{If}{[ex.Source],<br><i>([ex.Source])</i>}
    <img onclick='play("mp3"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/></td>
    


    Alternatively, one can do things for only certain format,
    {If} { [ex.FileFormat] eq MP3,  <img onclick='play("mp3"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
     {If}{[ex.FileFormat] eq m4v,  <img onclick='play("m4v"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
     {If}{[ex.FileFormat] eq flv,  <img onclick='play("flv"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
     {If}{[ex.FileFormat] eq m4a,  <img onclick='play("m4a"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
     {If}{[ex.FileFormat] eq oga,  <img onclick='play("oga"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
     {If}{[ex.FileFormat] eq ogv,  <img onclick='play("ogv"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
     {If}{[ex.FileFormat] eq webmv,  <img onclick='play("webmv"\,"archives/[ex.assocfilepath]/[ex.srclink_file]"); ' src='_httpcollection_/images/PlayIcon.png' height='16'/>}
Note that "," in the " play (... , ...)" function call has to be escaped for macro.  


No comments :