Bug 8377 [ENH] Show HTML5 video/ audio for media files in OPAC and staff client
[koha.git] / C4 / HTML5Media.pm
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;