View | Details | Raw Unified | Return to bug 8377
Collapse All | Expand All

(-)a/C4/HTML5Media.pm (+226 lines)
Line 0 Link Here
1
package C4::HTML5Media;
2
3
# Copyright 2012 Mirko Tietgen
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
23
use C4::Context;
24
use MARC::Field;
25
26
27
=head1 HTML5Media
28
29
C4::HTML5Media
30
31
=head1 Description
32
33
This module gets the relevant data from field 856 (MARC21/UNIMARC) to create a HTML5 audio or video element containing the file(s) catalogued in 856.
34
35
=cut
36
37
=head2 gethtml5media
38
39
Get all relevant data from field 856. Takes $template and $record in the subroutine call, sets appropriate params.
40
41
=cut
42
43
sub gethtml5media {
44
    my $self = shift;
45
    my $template = shift;
46
    my $record = shift;
47
    my @HTML5Media_sets = ();
48
    my @HTML5Media_fields = $record->field(856);
49
    my $HTML5MediaParent;
50
    my $HTML5MediaWidth;
51
    my @HTML5MediaExtensions = split( /\|/, C4::Context->preference("HTML5MediaExtensions") );
52
    my $marcflavour          = C4::Context->preference("marcflavour");
53
    foreach my $HTML5Media_field (@HTML5Media_fields) {
54
        my %HTML5Media;
55
        # protocol
56
        if ( $HTML5Media_field->indicator(1) eq '1' ) {
57
            $HTML5Media{protocol} = 'ftp';
58
        }
59
        elsif ( $HTML5Media_field->indicator(1) eq '4' ) {
60
            $HTML5Media{protocol} = 'http';
61
        }
62
        elsif ( $HTML5Media_field->indicator(1) eq '7' ) {
63
            if ($marcflavour eq 'MARC21' || $marcflavour eq 'NORMARC') {
64
                $HTML5Media{protocol} = $HTML5Media_field->subfield('2');
65
            }
66
            elsif ($marcflavour eq 'UNIMARC') {
67
                $HTML5Media{protocol} = $HTML5Media_field->subfield('y');
68
            }
69
        }
70
        else {
71
            $HTML5Media{protocol} = 'http';
72
        }
73
        # user
74
        if ( $HTML5Media_field->subfield('l') ) {
75
            $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.
76
        }
77
        elsif ( $HTML5Media_field->subfield('h') ) {
78
            $HTML5Media{username} = $HTML5Media_field->subfield('h');
79
        }
80
        # user/pass
81
        if ( $HTML5Media{username} && $HTML5Media_field->subfield('k') ) {
82
            $HTML5Media{loginblock} = $HTML5Media{username} . ':' . $HTML5Media_field->subfield('k') . '@';
83
        }
84
        elsif ( $HTML5Media{username} ) {
85
            $HTML5Media{loginblock} = $HTML5Media{username} . '@';
86
        }
87
        else {
88
            $HTML5Media{loginblock} = '';
89
        }
90
        # port
91
        if ( $HTML5Media_field->subfield('p') ) {
92
            $HTML5Media{portblock} = ':' . $HTML5Media_field->subfield('k');
93
        }
94
        else {
95
            $HTML5Media{portblock} = '';
96
        }
97
        # src
98
        if ( $HTML5Media_field->subfield('u') ) {
99
            $HTML5Media{srcblock} = $HTML5Media_field->subfield('u');
100
        }
101
        elsif ( $HTML5Media_field->subfield('a') && $HTML5Media_field->subfield('d') && $HTML5Media_field->subfield('f') ) {
102
            $HTML5Media{host}        = $HTML5Media_field->subfield('a');
103
            $HTML5Media{host}        =~ s/(^\/|\/$)//g;
104
            $HTML5Media{path}        = $HTML5Media_field->subfield('d');
105
            $HTML5Media{path}        =~ s/(^\/|\/$)//g;
106
            $HTML5Media{file}        = $HTML5Media_field->subfield('f');
107
            $HTML5Media{srcblock}    = $HTML5Media{protocol} . '://' . $HTML5Media{loginblock} . $HTML5Media{host} . $HTML5Media{portblock} . '/' . $HTML5Media{path} . '/' . $HTML5Media{file};
108
        }
109
        else {
110
            next; # no file to play
111
        }
112
        # extension
113
        $HTML5Media{extension} = ($HTML5Media{srcblock} =~ m/([^.]+)$/)[0];
114
        if ( !grep /$HTML5Media{extension}/, @HTML5MediaExtensions ) {
115
            next; # not a specified media file
116
        }
117
        # mime
118
        if ( $HTML5Media_field->subfield('c') ) {
119
            $HTML5Media{codecs} = $HTML5Media_field->subfield('c');
120
        }
121
        ### from subfield q…
122
        if ( $HTML5Media_field->subfield('q') ) {
123
            $HTML5Media{mime} = $HTML5Media_field->subfield('q');
124
        }
125
        ### …or from file extension and codecs…
126
        elsif ( $HTML5Media{codecs} ) {
127
            if ( $HTML5Media{codecs} =~ /theora.*vorbis/ ) {
128
                $HTML5Media{mime} = 'video/ogg';
129
            }
130
            elsif ( $HTML5Media{codecs} =~ /vp8.*vorbis/ ) {
131
                $HTML5Media{mime} = 'video/webm';
132
            }
133
            elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'ogg') ) {
134
                $HTML5Media{mime} = 'audio/ogg';
135
            }
136
            elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'webm') ) {
137
                $HTML5Media{mime} = 'audio/webm';
138
            }
139
        }
140
        ### …or just from file extension
141
        else {
142
            if ( $HTML5Media{extension} eq 'ogv' ) {
143
                $HTML5Media{mime} = 'video/ogg';
144
                $HTML5Media{codecs} = 'theora,vorbis';
145
            }
146
            if ( $HTML5Media{extension} eq 'oga' ) {
147
                $HTML5Media{mime} = 'audio/ogg';
148
              $HTML5Media{codecs} = 'vorbis';
149
            }
150
            elsif ( $HTML5Media{extension} eq 'spx' ) {
151
                $HTML5Media{mime} = 'audio/ogg';
152
                $HTML5Media{codecs} = 'speex';
153
            }
154
            elsif ( $HTML5Media{extension} eq 'opus' ) {
155
                $HTML5Media{mime} = 'audio/ogg';
156
                $HTML5Media{codecs} = 'opus';
157
            }
158
            elsif ( $HTML5Media{extension} eq 'vtt' ) {
159
                $HTML5Media{mime} = 'text/vtt';
160
            }
161
        }
162
        # codecs
163
        if ( $HTML5Media{codecs} ) {
164
            $HTML5Media{codecblock} = '; codecs="' . $HTML5Media{codecs} . '"';
165
        }
166
        else {
167
            $HTML5Media{codecblock} = '';
168
        }
169
        # type
170
        if ( $HTML5Media{mime} ) {
171
            $HTML5Media{typeblock} = ' type=\'' . $HTML5Media{mime} . $HTML5Media{codecblock} . '\'';
172
        }
173
        else {
174
          $HTML5Media{typeblock} = '';
175
        }
176
        # element
177
        if ( $HTML5Media{mime} =~ /audio/ ) {
178
            $HTML5Media{type} = 'audio';
179
        }
180
        elsif ( $HTML5Media{mime} =~ /video/ ) {
181
            $HTML5Media{type} = 'video';
182
        }
183
        elsif ( $HTML5Media{mime} =~ /text/ ) {
184
            $HTML5Media{type} = 'track';
185
        }
186
        # push
187
        if ( $HTML5Media{srcblock} && $HTML5Media{type} ) {
188
            push (@HTML5Media_sets, \%HTML5Media);
189
        }
190
    }
191
    # parent element
192
    for my $i ( 0 .. $#HTML5Media_sets ) {
193
        if ( ($HTML5Media_sets[$i]{mime}) && ($HTML5Media_sets[$i]{mime} =~ /audio/) ) {
194
            if ( $HTML5MediaParent ne 'video' ) {
195
                $HTML5MediaParent = 'audio';
196
                $HTML5MediaWidth = '';
197
            }
198
        }
199
        elsif ( ($HTML5Media_sets[$i]{mime}) && ($HTML5Media_sets[$i]{mime} =~ /video/) ) {
200
            $HTML5MediaParent = 'video';
201
            $HTML5MediaWidth = ' width="480"';
202
        }
203
    }
204
    # child element
205
    for my $j ( 0 .. $#HTML5Media_sets ) {
206
        if ( ($HTML5Media_sets[$j]{type}) && ( ($HTML5Media_sets[$j]{type} eq 'video') || ($HTML5Media_sets[$j]{type} eq 'audio') ) ) {
207
            if ( $HTML5Media_sets[$j]{type} eq $HTML5MediaParent ) {
208
                $HTML5Media_sets[$j]{child} = 'source';
209
            }
210
        }
211
        else {
212
            $HTML5Media_sets[$j]{child} = $HTML5Media_sets[$j]{type};
213
        }
214
    }
215
    # template parameters
216
    if ( (scalar(@HTML5Media_sets) > 0) && ($HTML5MediaParent) ) {
217
        $template->param(
218
            HTML5MediaEnabled  => 1,
219
            HTML5MediaSets     => \@HTML5Media_sets,
220
            HTML5MediaParent   => $HTML5MediaParent,
221
            HTML5MediaWidth    => $HTML5MediaWidth);
222
    }
223
    return $template;
224
}
225
226
1;
(-)a/catalogue/detail.pl (+7 lines)
Lines 40-45 use C4::VirtualShelves; Link Here
40
use C4::XSLT;
40
use C4::XSLT;
41
use C4::Images;
41
use C4::Images;
42
use Koha::DateUtils;
42
use Koha::DateUtils;
43
use C4::HTML5Media;
43
44
44
# use Smart::Comments;
45
# use Smart::Comments;
45
46
Lines 358-363 if ( C4::Context->preference("LocalCoverImages") == 1 ) { Link Here
358
    $template->{VARS}->{localimages} = \@images;
359
    $template->{VARS}->{localimages} = \@images;
359
}
360
}
360
361
362
# HTML5 Media
363
if ( (C4::Context->preference("HTML5MediaEnabled") eq 'staff') || (C4::Context->preference("HTML5MediaEnabled") eq 'both') ) {
364
    $template = C4::HTML5Media->gethtml5media($template,$record);
365
}
366
367
361
# Get OPAC URL
368
# Get OPAC URL
362
if (C4::Context->preference('OPACBaseURL')){
369
if (C4::Context->preference('OPACBaseURL')){
363
     $template->param( OpacUrl => C4::Context->preference('OPACBaseURL') );
370
     $template->param( OpacUrl => C4::Context->preference('OPACBaseURL') );
(-)a/installer/data/mysql/sysprefs.sql (+2 lines)
Lines 382-384 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' Link Here
382
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacMainUserBlockMobile','','Show the following HTML in its own column on the main page of the OPAC (mobile version):',NULL,'free');
382
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacMainUserBlockMobile','','Show the following HTML in its own column on the main page of the OPAC (mobile version):',NULL,'free');
383
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowLibrariesPulldownMobile','1','Show the libraries pulldown on the mobile version of the OPAC.',NULL,'YesNo');
383
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowLibrariesPulldownMobile','1','Show the libraries pulldown on the mobile version of the OPAC.',NULL,'YesNo');
384
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowFiltersPulldownMobile','1','Show the search filters pulldown on the mobile version of the OPAC.',NULL,'YesNo');
384
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowFiltersPulldownMobile','1','Show the search filters pulldown on the mobile version of the OPAC.',NULL,'YesNo');
385
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaEnabled','not','Show a tab with a HTML5 media player for files catalogued in field 856','not|opac|staff|both','Choice');
386
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','Media file extensions','','free');
(-)a/installer/data/mysql/updatedatabase.pl (+7 lines)
Lines 5952-5957 if (C4::Context->preference("Version") < TransformToNum($DBversion)) { Link Here
5952
    SetVersion ($DBversion);
5952
    SetVersion ($DBversion);
5953
}
5953
}
5954
5954
5955
$DBversion = 'XXX';
5956
if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
5957
   $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaEnabled','not','Show a HTML5 media player in a tab on opac-detail.pl for media files catalogued in field 856.','not|opac|staff|both','Choice');");
5958
   $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','Media file extensions','','free');");
5959
   print "Upgrade to $DBversion done (Add HTML5MediaEnabled and HTML5MediaExtensions sysprefs)\n";
5960
   SetVersion ($DBversion);
5961
}
5955
5962
5956
=head1 FUNCTIONS
5963
=head1 FUNCTIONS
5957
5964
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref (+14 lines)
Lines 286-288 Enhanced Content: Link Here
286
                  yes: Allow
286
                  yes: Allow
287
                  no: "Don't allow"
287
                  no: "Don't allow"
288
            - multiple images to be attached to each bibliographic record.
288
            - multiple images to be attached to each bibliographic record.
289
    HTML5 Media:
290
        -
291
            - Show a tab with a HTML5 media player for files catalogued in field 856
292
            - pref: HTML5MediaEnabled
293
              choices:
294
                  not: "not at all."
295
                  opac: "in the OPAC."
296
                  staff: "in the staff client."
297
                  both: "in OPAC and staff client."
298
        -
299
            - Media file extensions
300
            - pref: HTML5MediaExtensions
301
              class: multi
302
            - (separated with |).
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-1 / +16 lines)
Lines 261-267 function verify_images() { Link Here
261
[% IF ( subscriptionsnumber ) %]<li><a href="#subscriptions">Subscriptions</a></li>[% END %]
261
[% IF ( subscriptionsnumber ) %]<li><a href="#subscriptions">Subscriptions</a></li>[% END %]
262
[% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]<li><a href="#editions">Editions</a></li>[% END %][% END %]
262
[% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]<li><a href="#editions">Editions</a></li>[% END %][% END %]
263
[% IF ( LocalCoverImages ) %][% IF ( localimages || CAN_user_tools_upload_local_cover_images ) %]<li><a href="#images">Images</a></li>[% END %][% END %]
263
[% IF ( LocalCoverImages ) %][% IF ( localimages || CAN_user_tools_upload_local_cover_images ) %]<li><a href="#images">Images</a></li>[% END %][% END %]
264
 </ul>
264
[% IF ( HTML5MediaEnabled ) %][% IF ( HTML5MediaSets ) %]<li><a href="#html5media">Play media</a></li>[% END %][% END %]
265
</ul>
265
266
266
<div id="holdings">
267
<div id="holdings">
267
[% IF ( count ) %]
268
[% IF ( count ) %]
Lines 544-549 function verify_images() { Link Here
544
</div>
545
</div>
545
[% END %]
546
[% END %]
546
547
548
[% IF ( HTML5MediaEnabled ) %]
549
<div id="html5media">
550
        <p>
551
        <[% HTML5MediaParent %][% HTML5MediaWidth %] controls preload=none>
552
          [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
553
            <[% HTML5MediaSet.child  %] src="[% HTML5MediaSet.srcblock %]"[% HTML5MediaSet.typeblock %] />
554
          [% END %]
555
            [[% HTML5MediaParent %] tag not supported by your browser.]
556
        </[% HTML5MediaParent %]>
557
        </p>
558
</div>
559
[% END %]
560
561
547
</div><!-- /bibliodetails -->
562
</div><!-- /bibliodetails -->
548
563
549
<div class="yui-g" id="export" style="margin-top: 1em;">
564
<div class="yui-g" id="export" style="margin-top: 1em;">
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt (+20 lines)
Lines 13-18 Link Here
13
<link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />[% END %]
13
<link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />[% END %]
14
14
15
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js"></script>[% END %]
15
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js"></script>[% END %]
16
16
<script type="text/JavaScript" language="JavaScript">
17
<script type="text/JavaScript" language="JavaScript">
17
//<![CDATA[
18
//<![CDATA[
18
19
Lines 708-713 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
708
[% IF ( OPACLocalCoverImages ) %][% IF ( localimages ) %]
709
[% IF ( OPACLocalCoverImages ) %][% IF ( localimages ) %]
709
    <li id="tab_images"><a href="#images">Images</a></li>
710
    <li id="tab_images"><a href="#images">Images</a></li>
710
[% END %][% END %]
711
[% END %][% END %]
712
713
714
[% IF ( HTML5MediaEnabled ) %][% IF ( HTML5MediaSets ) %]
715
    <li id="tab_html5media"><a href="#html5media">Play media</a></li>
716
[% END %][% END %]
717
711
</ul>
718
</ul>
712
719
713
[% IF ( serialcollection ) %]
720
[% IF ( serialcollection ) %]
Lines 1142-1147 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1142
</table>
1149
</table>
1143
</div>[% END %][% END %]
1150
</div>[% END %][% END %]
1144
1151
1152
[% IF ( HTML5MediaEnabled ) %]
1153
<div id="html5media">
1154
        <p>
1155
        <[% HTML5MediaParent %][% HTML5MediaWidth %] controls preload=none>
1156
          [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
1157
            <[% HTML5MediaSet.child  %] src="[% HTML5MediaSet.srcblock %]"[% HTML5MediaSet.typeblock %] />
1158
          [% END %]
1159
            [[% HTML5MediaParent %] tag not supported by your browser.]
1160
        </[% HTML5MediaParent %]>
1161
        </p>
1162
</div>
1163
[% END %]
1164
1145
[% IF ( OPACLocalCoverImages ) %]
1165
[% IF ( OPACLocalCoverImages ) %]
1146
<div id="images">
1166
<div id="images">
1147
<p>Click on an image to view it in the image viewer</p>
1167
<p>Click on an image to view it in the image viewer</p>
(-)a/opac/opac-detail.pl (-1 / +6 lines)
Lines 49-54 use MARC::Field; Link Here
49
use List::MoreUtils qw/any none/;
49
use List::MoreUtils qw/any none/;
50
use C4::Images;
50
use C4::Images;
51
use Koha::DateUtils;
51
use Koha::DateUtils;
52
use C4::HTML5Media;
52
53
53
BEGIN {
54
BEGIN {
54
	if (C4::Context->preference('BakerTaylorEnabled')) {
55
	if (C4::Context->preference('BakerTaylorEnabled')) {
Lines 755-760 if (C4::Context->preference("OPACLocalCoverImages")){ Link Here
755
		$template->param(OPACLocalCoverImages => 1);
756
		$template->param(OPACLocalCoverImages => 1);
756
}
757
}
757
758
759
# HTML5 Media
760
if ( (C4::Context->preference("HTML5MediaEnabled") eq 'opac') || (C4::Context->preference("HTML5MediaEnabled") eq 'both') ) {
761
    $template = C4::HTML5Media->gethtml5media($template,$record);
762
}
763
758
my $syndetics_elements;
764
my $syndetics_elements;
759
765
760
if ( C4::Context->preference("SyndeticsEnabled") ) {
766
if ( C4::Context->preference("SyndeticsEnabled") ) {
761
- 

Return to bug 8377