[Koha-patches] [PATCH] Bug 8377 [ENH] Show HTML5 video/ audio in OPAC for media files in 856

Mirko Tietgen 5p4m at gmx.de
Thu Jul 12 01:02:31 CEST 2012


This enhancement uses information from MARC field 856 to generate the appropriate HTML5 code to embed am media player for the file(s) in a tab in the opac-detail view. This patch supports the HTML5 <audio> and <video> element. Additionally it gives basic support for the <track> element. This element is not supported very well by recent browsers. Please consider the patch working when you get working video or audio. Fixed a typo in this second patch.
---
 installer/data/mysql/sysprefs.sql                  |    2 +
 installer/data/mysql/updatedatabase.pl             |    8 +
 .../admin/preferences/enhanced_content.pref        |   12 ++
 koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt |   23 +++
 opac/opac-detail.pl                                |  185 ++++++++++++++++++++
 5 files changed, 230 insertions(+), 0 deletions(-)

diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql
index 7009155..268f85d 100644
--- a/installer/data/mysql/sysprefs.sql
+++ b/installer/data/mysql/sysprefs.sql
@@ -375,3 +375,5 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES (
 INSERT INTO systempreferences (variable,value,explanation,type) VALUES('EnableBorrowerFiles','0','If enabled, allows librarians to upload and attach arbitrary files to a borrower record.','YesNo');
 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UpdateTotalIssuesOnCirc','0','Whether to update the totalissues field in the biblio on each circ.',NULL,'YesNo');
 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('IntranetSlipPrinterJS','','Use this JavaScript for printing slips. Define at least function printThenClose(). For use e.g. with Firefox PlugIn jsPrintSetup, see http://jsprintsetup.mozdev.org/','','Free');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaEnabled','0','Show a HTML5 media player in a tab on opac-detail.pl for media files catalogued in field 856.','','YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','Media file extensions','','free');
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index bb96644..9fc79a7 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -5536,6 +5536,14 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     SetVersion($DBversion);
 }
 
+$DBversion = 'XXX';
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+   $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaEnabled','0','Show a HTML5 media player in a tab on opac-detail.pl for media files catalogued in field 856.','','YesNo');");
+   $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','Media file extensions','','free');");
+   print "Upgrade to $DBversion done (Add HTML5MediaEnabled and HTML5MediaExtensions sysprefs)\n";
+   SetVersion ($DBversion);
+}
+
 =head1 FUNCTIONS
 
 =head2 TableExists($table)
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref
index bb3bc2d..569e393 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref
@@ -336,3 +336,15 @@ Enhanced Content:
                   yes: Allow
                   no: "Don't allow"
             - multiple images to be attached to each bibliographic record.
+    HTML5 Media:
+        -
+            - pref: HTML5MediaEnabled
+              choices:
+                  yes: Show
+                  no: "Don't show"
+            - a HTML5 media player in a tab on opac-detail.pl for media files catalogued in field 856.
+        -
+            - Media file extensions
+            - pref: HTML5MediaExtensions
+              class: multi
+            - (separated with |).
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
index 5e2b55e..3f0b69d 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
@@ -12,6 +12,7 @@
 [% IF ( OpacStarRatings != 'disable' ) %]<script type="text/javascript" src="/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js"></script>
 <link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />[% END %]
 
+
 <script type="text/JavaScript" language="JavaScript">
 //<![CDATA[
 
@@ -678,6 +679,14 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 [% IF ( OPACLocalCoverImages ) %][% IF ( localimages ) %]
     <li id="tab_images"><a href="#images">Images</a></li>
 [% END %][% END %]
+
+
+[% IF ( HTML5MediaEnabled ) %][% IF ( HTML5MediaSets ) %]
+    [% IF ( defaulttab == 'html5media' ) %]<li id="tab_html5media" class="ui-tabs-selected">[% ELSE %]<li id="tab_html5media">[% END %]
+        <a href="#html5media">HTML5 Media</a>
+    </li>
+[% END %][% END %]
+
 </ul>
 
 [% IF ( serialcollection ) %]
@@ -1165,6 +1174,20 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 [% END %]
 
 
+[% IF ( HTML5MediaEnabled ) %]
+<div id="html5media">
+        <p>
+        <[% HTML5MediaParent %][% HTML5MediaWidth %] controls preload=none>
+          [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
+            <[% HTML5MediaSet.child  %] src="[% HTML5MediaSet.srcblock %]"[% HTML5MediaSet.typeblock %] />
+          [% END %]
+            [[% HTML5MediaParent %] tag not supported by your browser.]
+        </[% HTML5MediaParent %]>
+        </p>
+</div>
+[% END %]
+
+
 [% IF ( OPACLocalCoverImages ) %]
 <div id="images">
 <p>Click on an image to view it in the image viewer</p>
diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl
index 0bafabd..ab702a1 100755
--- a/opac/opac-detail.pl
+++ b/opac/opac-detail.pl
@@ -747,6 +747,188 @@ if (C4::Context->preference("OPACLocalCoverImages")){
 		$template->param(OPACLocalCoverImages => 1);
 }
 
+# HTML5 Media
+
+my @HTML5Media_sets = ();
+my $HTML5MediaParent;
+my $HTML5MediaWidth;
+my @HTML5MediaExtensions = split /\|/, C4::Context->preference("HTML5MediaExtensions");
+
+if ( C4::Context->preference("HTML5MediaEnabled") ) {
+    my @HTML5Media_fields = $record->field(856);
+    foreach my $HTML5Media_field (@HTML5Media_fields) {
+        my %HTML5Media;
+        # protocol
+        if ( $HTML5Media_field->indicator(1) eq '1' ) {
+            $HTML5Media{protocol} = 'ftp';
+        }
+        elsif ( $HTML5Media_field->indicator(1) eq '4' ) {
+            $HTML5Media{protocol} = 'http';
+        }
+        elsif ( $HTML5Media_field->indicator(1) eq '7' ) {
+            if ($marcflavour eq 'MARC21' || $marcflavour eq 'NORMARC') {
+                $HTML5Media{protocol} = $HTML5Media_field->subfield('2');
+            }
+            elsif ($marcflavour eq 'UNIMARC') {
+                $HTML5Media{protocol} = $HTML5Media_field->subfield('y');
+            }
+        }
+        else {
+            $HTML5Media{protocol} = 'http';
+        }
+        # user
+        if ( $HTML5Media_field->subfield('l') ) {
+            $HTML5Media{username} = $HTML5Media_field->subfield('l'); # yes, that is arbitrary if h and l are not the same. originally i flipped a coin in that case.
+        }
+        elsif ( $HTML5Media_field->subfield('h') ) {
+            $HTML5Media{username} = $HTML5Media_field->subfield('h');
+        }
+        # user/pass
+        if ( $HTML5Media{username} && $HTML5Media_field->subfield('k') ) {
+            $HTML5Media{loginblock} = $HTML5Media{username} . ':' . $HTML5Media_field->subfield('k') . '@';
+        }
+        elsif ( $HTML5Media{username} ) {
+            $HTML5Media{loginblock} = $HTML5Media{username} . '@';
+        }
+        else {
+            $HTML5Media{loginblock} = '';
+        }
+        # port
+        if ( $HTML5Media_field->subfield('p') ) {
+            $HTML5Media{portblock} = ':' . $HTML5Media_field->subfield('k');
+        }
+        else {
+            $HTML5Media{portblock} = '';
+        }
+        # src
+        if ( $HTML5Media_field->subfield('u') ) {
+            $HTML5Media{srcblock} = $HTML5Media_field->subfield('u');
+        }
+        elsif ( $HTML5Media_field->subfield('a') && $HTML5Media_field->subfield('d') && $HTML5Media_field->subfield('f') ) {
+            $HTML5Media{host}        = $HTML5Media_field->subfield('a');
+            $HTML5Media{host}        =~ s/(^\/|\/$)//g;
+            $HTML5Media{path}        = $HTML5Media_field->subfield('d');
+            $HTML5Media{path}        =~ s/(^\/|\/$)//g;
+            $HTML5Media{file}        = $HTML5Media_field->subfield('f');
+            $HTML5Media{srcblock}    = $HTML5Media{protocol} . '://' . $HTML5Media{loginblock} . $HTML5Media{host} . $HTML5Media{portblock} . '/' . $HTML5Media{path} . '/' . $HTML5Media{file};
+        }
+        else {
+            next; # no file to play
+        }
+        # extension
+        $HTML5Media{extension} = ($HTML5Media{srcblock} =~ m/([^.]+)$/)[0];
+        if ( !grep /$HTML5Media{extension}/, @HTML5MediaExtensions ) {
+            next; # not a specified media file
+        }
+        # mime
+        if ( $HTML5Media_field->subfield('c') ) {
+            $HTML5Media{codecs} = $HTML5Media_field->subfield('c');
+        }
+        ### from subfield q…
+        if ( $HTML5Media_field->subfield('q') ) {
+            $HTML5Media{mime} = $HTML5Media_field->subfield('q');
+        } 
+        ### …or from file extension and codecs…
+        elsif ( $HTML5Media{codecs} ) {
+            if ( $HTML5Media{codecs} =~ /theora.*vorbis/ ) {
+                $HTML5Media{mime} = 'video/ogg';
+            }
+            elsif ( $HTML5Media{codecs} =~ /vp8.*vorbis/ ) {
+                $HTML5Media{mime} = 'video/webm';
+            }
+            elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'ogg') ) {
+                $HTML5Media{mime} = 'audio/ogg';
+            }
+            elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'webm') ) {
+                $HTML5Media{mime} = 'audio/webm';
+            }
+        }
+        ### …or just from file extension
+        else {
+            if ( $HTML5Media{extension} eq 'ogv' ) {
+                $HTML5Media{mime} = 'video/ogg';
+                $HTML5Media{codecs} = 'theora,vorbis';
+            }
+            if ( $HTML5Media{extension} eq 'oga' ) {
+                $HTML5Media{mime} = 'audio/ogg';
+              $HTML5Media{codecs} = 'vorbis';
+            }
+            elsif ( $HTML5Media{extension} eq 'spx' ) {
+                $HTML5Media{mime} = 'audio/ogg';
+                $HTML5Media{codecs} = 'speex';
+            }
+            elsif ( $HTML5Media{extension} eq 'opus' ) {
+                $HTML5Media{mime} = 'audio/ogg';
+                $HTML5Media{codecs} = 'opus';
+            }
+            elsif ( $HTML5Media{extension} eq 'vtt' ) {
+                $HTML5Media{mime} = 'text/vtt';
+            }
+        }
+        # codecs
+        if ( $HTML5Media{codecs} ) {
+            $HTML5Media{codecblock} = '; codecs="' . $HTML5Media{codecs} . '"';
+        }
+        else {
+            $HTML5Media{codecblock} = '';
+        }
+        # type
+        if ( $HTML5Media{mime} ) {
+            $HTML5Media{typeblock} = ' type=\'' . $HTML5Media{mime} . $HTML5Media{codecblock} . '\'';
+        }
+        else {
+          $HTML5Media{typeblock} = '';
+        }
+        # element
+        if ( $HTML5Media{mime} =~ /audio/ ) {
+            $HTML5Media{type} = 'audio';
+        }
+        elsif ( $HTML5Media{mime} =~ /video/ ) {
+            $HTML5Media{type} = 'video';
+        }
+        elsif ( $HTML5Media{mime} =~ /text/ ) {
+            $HTML5Media{type} = 'track';
+        }
+        # push
+        if ( $HTML5Media{srcblock} && $HTML5Media{type} ) {
+            push (@HTML5Media_sets, \%HTML5Media);
+        }
+    }
+    # parent element
+    for my $i ( 0 .. $#HTML5Media_sets ) {
+        if ( $HTML5Media_sets[$i]{mime} =~ /audio/ ) {
+            if ( $HTML5MediaParent ne 'video' ) {
+                $HTML5MediaParent = 'audio';
+                $HTML5MediaWidth = '';
+            }
+        }
+        elsif ( $HTML5Media_sets[$i]{mime} =~ /video/ ) {
+            $HTML5MediaParent = 'video';
+            $HTML5MediaWidth = ' width="480"';
+        }
+    }
+    # child element
+    for my $j ( 0 .. $#HTML5Media_sets ) {
+        if ( ($HTML5Media_sets[$j]{type} eq 'video') || ($HTML5Media_sets[$j]{type} eq 'audio') ) {
+            if ( $HTML5Media_sets[$j]{type} eq $HTML5MediaParent ) {
+                $HTML5Media_sets[$j]{child} = 'source';
+            }
+        }
+        else {
+            $HTML5Media_sets[$j]{child} = $HTML5Media_sets[$j]{type};
+        }     
+    }
+    # template parameters
+    if ( (scalar(@HTML5Media_sets) > 0) && ($HTML5MediaParent) ) {
+        $template->param(
+	    HTML5MediaEnabled  => 1,
+	    HTML5MediaSets     => \@HTML5Media_sets,
+            HTML5MediaParent   => $HTML5MediaParent,
+            HTML5MediaWidth    => $HTML5MediaWidth);
+    }
+}
+
+
 # Amazon.com Stuff
 if ( C4::Context->preference("OPACAmazonEnabled") ) {
     $template->param( AmazonTld => get_amazon_tld() );
@@ -983,6 +1165,8 @@ if (my $search_for_title = C4::Context->preference('OPACSearchForTitleIn')){
 # the user wants, and what's available for display
 my $opac_serial_default = C4::Context->preference('opacSerialDefaultTab');
 my $defaulttab = 
+    @HTML5Media_sets > 0
+        ? 'html5media' :
     $opac_serial_default eq 'subscriptions' && $subscriptionsnumber
         ? 'subscriptions' :
     $opac_serial_default eq 'serialcollection' && @serialcollections > 0
@@ -995,6 +1179,7 @@ my $defaulttab =
         ? 'serialcollection' : 'subscription';
 $template->param('defaulttab' => $defaulttab);
 
+
 if (C4::Context->preference('OPACLocalCoverImages') == 1) {
     my @images = ListImagesForBiblio($biblionumber);
     $template->{VARS}->{localimages} = \@images;
-- 
1.7.2.5



More information about the Koha-patches mailing list