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 379-384 if ( C4::Context->preference("LocalCoverImages") == 1 ) { Link Here
379
    $template->{VARS}->{localimages} = \@images;
380
    $template->{VARS}->{localimages} = \@images;
380
}
381
}
381
382
383
# HTML5 Media
384
if ( (C4::Context->preference("HTML5MediaEnabled") eq 'staff') || (C4::Context->preference("HTML5MediaEnabled") eq 'both') ) {
385
    $template = C4::HTML5Media->gethtml5media($template,$record);
386
}
387
388
382
# Get OPAC URL
389
# Get OPAC URL
383
if (C4::Context->preference('OPACBaseURL')){
390
if (C4::Context->preference('OPACBaseURL')){
384
     $template->param( OpacUrl => C4::Context->preference('OPACBaseURL') );
391
     $template->param( OpacUrl => C4::Context->preference('OPACBaseURL') );
(-)a/installer/data/mysql/sysprefs.sql (+2 lines)
Lines 400-402 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' Link Here
400
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSeparateHoldings', '0', 'Separate current branch holdings from other holdings (OPAC)', NULL, 'YesNo');
400
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSeparateHoldings', '0', 'Separate current branch holdings from other holdings (OPAC)', NULL, 'YesNo');
401
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSeparateHoldingsBranch', 'homebranch', 'Branch used to separate holdings (OPAC)', 'homebranch|holdingbranch', 'Choice');
401
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSeparateHoldingsBranch', 'homebranch', 'Branch used to separate holdings (OPAC)', 'homebranch|holdingbranch', 'Choice');
402
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RenewalSendNotice','0', NULL, '', 'YesNo');
402
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RenewalSendNotice','0', NULL, '', 'YesNo');
403
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');
404
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 (+8 lines)
Lines 6309-6314 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
6309
    SetVersion($DBversion);
6309
    SetVersion($DBversion);
6310
}
6310
}
6311
6311
6312
$DBversion = 'XXX';
6313
if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
6314
   $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');");
6315
   $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','Media file extensions','','free');");
6316
   print "Upgrade to $DBversion done (Add HTML5MediaEnabled and HTML5MediaExtensions sysprefs)\n";
6317
   SetVersion ($DBversion);
6318
}
6319
6312
=head1 FUNCTIONS
6320
=head1 FUNCTIONS
6313
6321
6314
=head2 TableExists($table)
6322
=head2 TableExists($table)
(-)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 272-278 function verify_images() { Link Here
272
[% IF ( subscriptionsnumber ) %]<li><a href="#subscriptions">Subscriptions</a></li>[% END %]
272
[% IF ( subscriptionsnumber ) %]<li><a href="#subscriptions">Subscriptions</a></li>[% END %]
273
[% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]<li><a href="#editions">Editions</a></li>[% END %][% END %]
273
[% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]<li><a href="#editions">Editions</a></li>[% END %][% END %]
274
[% IF ( LocalCoverImages ) %][% IF ( localimages || CAN_user_tools_upload_local_cover_images ) %]<li><a href="#images">Images</a></li>[% END %][% END %]
274
[% IF ( LocalCoverImages ) %][% IF ( localimages || CAN_user_tools_upload_local_cover_images ) %]<li><a href="#images">Images</a></li>[% END %][% END %]
275
 </ul>
275
[% IF ( HTML5MediaEnabled ) %][% IF ( HTML5MediaSets ) %]<li><a href="#html5media">Play media</a></li>[% END %][% END %]
276
</ul>
276
277
277
[% BLOCK items_table %]
278
[% BLOCK items_table %]
278
    <table>
279
    <table>
Lines 587-592 function verify_images() { Link Here
587
</div>
588
</div>
588
[% END %]
589
[% END %]
589
590
591
[% IF ( HTML5MediaEnabled ) %]
592
<div id="html5media">
593
        <p>
594
        <[% HTML5MediaParent %][% HTML5MediaWidth %] controls preload=none>
595
          [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
596
            <[% HTML5MediaSet.child  %] src="[% HTML5MediaSet.srcblock %]"[% HTML5MediaSet.typeblock %] />
597
          [% END %]
598
            [[% HTML5MediaParent %] tag not supported by your browser.]
599
        </[% HTML5MediaParent %]>
600
        </p>
601
</div>
602
[% END %]
603
604
590
</div><!-- /bibliodetails -->
605
</div><!-- /bibliodetails -->
591
606
592
<div class="yui-g" id="export" style="margin-top: 1em;">
607
<div class="yui-g" id="export" style="margin-top: 1em;">
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt (+19 lines)
Lines 16-21 Link Here
16
<link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />[% END %]
16
<link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />[% END %]
17
17
18
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js"></script>[% END %]
18
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js"></script>[% END %]
19
19
<script type="text/JavaScript" language="JavaScript">
20
<script type="text/JavaScript" language="JavaScript">
20
//<![CDATA[
21
//<![CDATA[
21
22
Lines 718-723 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
718
[% IF ( OPACLocalCoverImages && localimages.size ) %]
719
[% IF ( OPACLocalCoverImages && localimages.size ) %]
719
    <li id="tab_images"><a href="#images">Images</a></li>
720
    <li id="tab_images"><a href="#images">Images</a></li>
720
[% END %]
721
[% END %]
722
723
[% IF ( HTML5MediaEnabled ) %][% IF ( HTML5MediaSets ) %]
724
    <li id="tab_html5media"><a href="#html5media">Play media</a></li>
725
[% END %][% END %]
726
721
</ul>
727
</ul>
722
728
723
[% IF ( serialcollection ) %]
729
[% IF ( serialcollection ) %]
Lines 1053-1058 YAHOO.util.Event.onContentReady("furtherm", function () { Link Here
1053
</table>
1059
</table>
1054
</div>[% END %][% END %]
1060
</div>[% END %][% END %]
1055
1061
1062
[% IF ( HTML5MediaEnabled ) %]
1063
<div id="html5media">
1064
        <p>
1065
        <[% HTML5MediaParent %][% HTML5MediaWidth %] controls preload=none>
1066
          [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
1067
            <[% HTML5MediaSet.child  %] src="[% HTML5MediaSet.srcblock %]"[% HTML5MediaSet.typeblock %] />
1068
          [% END %]
1069
            [[% HTML5MediaParent %] tag not supported by your browser.]
1070
        </[% HTML5MediaParent %]>
1071
        </p>
1072
</div>
1073
[% END %]
1074
1056
[% IF ( OPACLocalCoverImages && localimages.size ) %]
1075
[% IF ( OPACLocalCoverImages && localimages.size ) %]
1057
<div id="images">
1076
<div id="images">
1058
<p>Click on an image to view it in the image viewer</p>
1077
<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 776-781 if (C4::Context->preference("OPACLocalCoverImages")){ Link Here
776
		$template->param(OPACLocalCoverImages => 1);
777
		$template->param(OPACLocalCoverImages => 1);
777
}
778
}
778
779
780
# HTML5 Media
781
if ( (C4::Context->preference("HTML5MediaEnabled") eq 'opac') || (C4::Context->preference("HTML5MediaEnabled") eq 'both') ) {
782
    $template = C4::HTML5Media->gethtml5media($template,$record);
783
}
784
779
my $syndetics_elements;
785
my $syndetics_elements;
780
786
781
if ( C4::Context->preference("SyndeticsEnabled") ) {
787
if ( C4::Context->preference("SyndeticsEnabled") ) {
782
- 

Return to bug 8377