Bug 15800: Koha::AuthorisedValues - Remove C4::Koha::IsAuthorisedValueCategory
[koha.git] / C4 / HTML5Media.pm
1 package C4::HTML5Media;
2
3 # Copyright 2012/2015 Mirko Tietgen
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use strict;
21 use warnings;
22
23 use C4::Context;
24 use MARC::Field;
25 use Koha::Upload;
26 use WWW::YouTube::Download qw(playback_url);
27
28 =head1 HTML5Media
29
30 C4::HTML5Media
31
32 =head1 Description
33
34 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.
35
36 =cut
37
38 =head2 gethtml5media
39
40 Get all relevant data from field 856. Takes a $record in the subroutine call, sets appropriate params.
41
42 =cut
43
44 sub gethtml5media {
45     my $self = 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 $HTML5MediaYouTube    = C4::Context->preference("HTML5MediaYouTube");
53     my $marcflavour          = C4::Context->preference("marcflavour");
54     my $isyoutube            = 0;
55     foreach my $HTML5Media_field (@HTML5Media_fields) {
56         my %HTML5Media;
57         # protocol
58         if ( $HTML5Media_field->indicator(1) eq '1' ) {
59             $HTML5Media{protocol} = 'ftp';
60         }
61         elsif ( $HTML5Media_field->indicator(1) eq '4' ) {
62             $HTML5Media{protocol} = 'http';
63         }
64         elsif ( $HTML5Media_field->indicator(1) eq '7' ) {
65             if ($marcflavour eq 'MARC21' || $marcflavour eq 'NORMARC') {
66                 $HTML5Media{protocol} = $HTML5Media_field->subfield('2');
67             }
68             elsif ($marcflavour eq 'UNIMARC') {
69                 $HTML5Media{protocol} = $HTML5Media_field->subfield('y');
70             }
71         }
72         else {
73             $HTML5Media{protocol} = 'http';
74         }
75         # user
76         if ( $HTML5Media_field->subfield('l') ) {
77             $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.
78         }
79         elsif ( $HTML5Media_field->subfield('h') ) {
80             $HTML5Media{username} = $HTML5Media_field->subfield('h');
81         }
82         # user/pass
83         if ( $HTML5Media{username} && $HTML5Media_field->subfield('k') ) {
84             $HTML5Media{loginblock} = $HTML5Media{username} . ':' . $HTML5Media_field->subfield('k') . '@';
85         }
86         elsif ( $HTML5Media{username} ) {
87             $HTML5Media{loginblock} = $HTML5Media{username} . '@';
88         }
89         else {
90             $HTML5Media{loginblock} = '';
91         }
92         # port
93         if ( $HTML5Media_field->subfield('p') ) {
94             $HTML5Media{portblock} = ':' . $HTML5Media_field->subfield('k');
95         }
96         else {
97             $HTML5Media{portblock} = '';
98         }
99         # src
100         if ( $HTML5Media_field->subfield('u') ) {
101             $HTML5Media{srcblock} = $HTML5Media_field->subfield('u');
102             if (grep /youtube/, $HTML5Media_field->subfield('u') ) { # TODO is there an official YT URL shortener? Can we use that too?
103                 if ($HTML5MediaYouTube == 1) {
104                     my $youtube           = WWW::YouTube::Download->new;
105                     $HTML5Media{srcblock} = $youtube->playback_url(
106                         $HTML5Media_field->subfield('u'), {
107                             'fmt' => '43' #webm is the only format compatible to all modern browsers. maybe check for available qualities
108                         }
109                     );
110                     # TODO handle error if format not available. Does that ever occur?
111                     $isyoutube = 1;
112                 }
113                else {
114                    next; # do not embed youtube videos
115                }
116             }
117         }
118         elsif ( $HTML5Media_field->subfield('a') && $HTML5Media_field->subfield('d') && $HTML5Media_field->subfield('f') ) {
119             $HTML5Media{host}        = $HTML5Media_field->subfield('a');
120             $HTML5Media{host}        =~ s/(^\/|\/$)//g;
121             $HTML5Media{path}        = $HTML5Media_field->subfield('d');
122             $HTML5Media{path}        =~ s/(^\/|\/$)//g; # TODO we could check for youtube here too, but nobody uses these fields anyway…
123             $HTML5Media{file}        = $HTML5Media_field->subfield('f');
124             $HTML5Media{srcblock}    = $HTML5Media{protocol} . '://' . $HTML5Media{loginblock} . $HTML5Media{host} . $HTML5Media{portblock} . '/' . $HTML5Media{path} . '/' . $HTML5Media{file};
125         }
126         else {
127             next; # no file to play
128         }
129         # extension
130         # check uploaded files
131         if ( $HTML5Media{srcblock} =~ /\Qopac-retrieve-file.pl\E/ ) {
132             my ( undef, $id ) = split /id=/, $HTML5Media{srcblock};
133             next if !$id;
134             my $public = ( ( caller )[1] =~ /opac/ ) ? { public => 1 }: {};
135             my $upl = Koha::Upload->new( $public )->get({ hashvalue => $id });
136             next if !$upl || $upl->{name} !~ /\./;
137             $HTML5Media{extension} = ( $upl->{name} =~ m/([^.]+)$/ )[0];
138         }
139         # check remote files
140         else {
141             $HTML5Media{extension} = ($HTML5Media{srcblock} =~ m/([^.]+)$/)[0];
142         }
143         if ( ( !grep /\Q$HTML5Media{extension}\E/, @HTML5MediaExtensions ) && ( $isyoutube != 1) ) {
144             next; # not a specified media file
145         }
146         # youtube
147         if ($isyoutube == 1) {
148                 $HTML5Media{mime} = 'video/webm';
149         }
150         # mime
151         if ( $HTML5Media_field->subfield('c') ) {
152             $HTML5Media{codecs} = $HTML5Media_field->subfield('c');
153         }
154         ### from subfield q…
155         if ( $HTML5Media_field->subfield('q') ) {
156             $HTML5Media{mime} = $HTML5Media_field->subfield('q');
157         }
158         ### …or from file extension and codecs…
159         elsif ( $HTML5Media{codecs} ) {
160             if ( $HTML5Media{codecs} =~ /theora.*vorbis/ ) {
161                 $HTML5Media{mime} = 'video/ogg';
162             }
163             elsif ( $HTML5Media{codecs} =~ /vp8.*vorbis/ ) {
164                 $HTML5Media{mime} = 'video/webm';
165             }
166             elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'ogg') ) {
167                 $HTML5Media{mime} = 'audio/ogg';
168             }
169             elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'webm') ) {
170                 $HTML5Media{mime} = 'audio/webm';
171             }
172         }
173         ### …or just from file extension
174         else {
175             if ( $HTML5Media{extension} eq 'ogv' ) {
176                 $HTML5Media{mime} = 'video/ogg';
177                 $HTML5Media{codecs} = 'theora,vorbis';
178             }
179             if ( $HTML5Media{extension} eq 'oga' ) {
180                 $HTML5Media{mime} = 'audio/ogg';
181                 $HTML5Media{codecs} = 'vorbis';
182             }
183             elsif ( $HTML5Media{extension} eq 'spx' ) {
184                 $HTML5Media{mime} = 'audio/ogg';
185                 $HTML5Media{codecs} = 'speex';
186             }
187             elsif ( $HTML5Media{extension} eq 'opus' ) {
188                 $HTML5Media{mime} = 'audio/ogg';
189                 $HTML5Media{codecs} = 'opus';
190             }
191             elsif ( $HTML5Media{extension} eq 'vtt' ) {
192                 $HTML5Media{mime} = 'text/vtt';
193             }
194         }
195         # codecs
196         if ( $HTML5Media{codecs} ) {
197             $HTML5Media{codecblock} = '; codecs="' . $HTML5Media{codecs} . '"';
198         }
199         else {
200             $HTML5Media{codecblock} = '';
201         }
202         # type
203         if ( $HTML5Media{mime} ) {
204             $HTML5Media{typeblock} = ' type=\'' . $HTML5Media{mime} . $HTML5Media{codecblock} . '\'';
205         }
206         else {
207           $HTML5Media{typeblock} = '';
208         }
209         # element
210         if ( $HTML5Media{mime} =~ /audio/ ) {
211             $HTML5Media{type} = 'audio';
212         }
213         elsif ( $HTML5Media{mime} =~ /video/ ) {
214             $HTML5Media{type} = 'video';
215         }
216         elsif ( $HTML5Media{mime} =~ /text/ ) {
217             $HTML5Media{type} = 'track';
218         }
219         # push
220         if ( $HTML5Media{srcblock} && $HTML5Media{type} ) {
221             push (@HTML5Media_sets, \%HTML5Media);
222         }
223     }
224     # parent element
225     for my $media ( @HTML5Media_sets ) {
226         if ( ($media->{mime}) && ($media->{mime} =~ /audio/) ) {
227             if ( $HTML5MediaParent ne 'video' ) {
228                 $HTML5MediaParent = 'audio';
229                 $HTML5MediaWidth = '';
230             }
231         }
232         elsif ( ($media->{mime}) && ($media->{mime} =~ /video/) ) {
233             $HTML5MediaParent = 'video';
234             $HTML5MediaWidth = ' width="480"';
235         }
236     }
237     # child element
238     for my $media ( @HTML5Media_sets ) {
239         if ( ($media->{type}) && ( ($media->{type} eq 'video') || ($media->{type} eq 'audio') ) ) {
240             if ( $media->{type} eq $HTML5MediaParent ) {
241                 $media->{child} = 'source';
242             }
243         }
244         else {
245             $media->{child} = $media->{type};
246         }
247     }
248
249     return (
250         HTML5MediaEnabled  => ( (scalar(@HTML5Media_sets) > 0) && ($HTML5MediaParent) ),
251         HTML5MediaSets     => \@HTML5Media_sets,
252         HTML5MediaParent   => $HTML5MediaParent,
253         HTML5MediaWidth    => $HTML5MediaWidth,
254     );
255 }
256
257 1;