Bug 14168 - enhance streaming cataloging to include youtube
[koha.git] / C4 / HTML5Media.pm
blob1094aa976782b9b58ffefea0f25f4fa71f9504e9
1 package C4::HTML5Media;
3 # Copyright 2012/2015 Mirko Tietgen
5 # This file is part of Koha.
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.
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.
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>.
20 use strict;
21 use warnings;
23 use C4::Context;
24 use MARC::Field;
25 use Koha::Upload;
26 use WWW::YouTube::Download qw(playback_url);
28 =head1 HTML5Media
30 C4::HTML5Media
32 =head1 Description
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.
36 =cut
38 =head2 gethtml5media
40 Get all relevant data from field 856. Takes a $record in the subroutine call, sets appropriate params.
42 =cut
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';
61 elsif ( $HTML5Media_field->indicator(1) eq '4' ) {
62 $HTML5Media{protocol} = 'http';
64 elsif ( $HTML5Media_field->indicator(1) eq '7' ) {
65 if ($marcflavour eq 'MARC21' || $marcflavour eq 'NORMARC') {
66 $HTML5Media{protocol} = $HTML5Media_field->subfield('2');
68 elsif ($marcflavour eq 'UNIMARC') {
69 $HTML5Media{protocol} = $HTML5Media_field->subfield('y');
72 else {
73 $HTML5Media{protocol} = 'http';
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.
79 elsif ( $HTML5Media_field->subfield('h') ) {
80 $HTML5Media{username} = $HTML5Media_field->subfield('h');
82 # user/pass
83 if ( $HTML5Media{username} && $HTML5Media_field->subfield('k') ) {
84 $HTML5Media{loginblock} = $HTML5Media{username} . ':' . $HTML5Media_field->subfield('k') . '@';
86 elsif ( $HTML5Media{username} ) {
87 $HTML5Media{loginblock} = $HTML5Media{username} . '@';
89 else {
90 $HTML5Media{loginblock} = '';
92 # port
93 if ( $HTML5Media_field->subfield('p') ) {
94 $HTML5Media{portblock} = ':' . $HTML5Media_field->subfield('k');
96 else {
97 $HTML5Media{portblock} = '';
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
110 # TODO handle error if format not availabe. Does that ever occur?
111 $isyoutube = 1;
113 else {
114 next; # do not embed youtube videos
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};
126 else {
127 next; # no file to play
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];
139 # check remote files
140 else {
141 $HTML5Media{extension} = ($HTML5Media{srcblock} =~ m/([^.]+)$/)[0];
143 if ( ( !grep /\Q$HTML5Media{extension}\E/, @HTML5MediaExtensions ) && ( $isyoutube != 1) ) {
144 next; # not a specified media file
146 # youtube
147 if ($isyoutube == 1) {
148 $HTML5Media{mime} = 'video/webm';
150 # mime
151 if ( $HTML5Media_field->subfield('c') ) {
152 $HTML5Media{codecs} = $HTML5Media_field->subfield('c');
154 ### from subfield q…
155 if ( $HTML5Media_field->subfield('q') ) {
156 $HTML5Media{mime} = $HTML5Media_field->subfield('q');
158 ### …or from file extension and codecs…
159 elsif ( $HTML5Media{codecs} ) {
160 if ( $HTML5Media{codecs} =~ /theora.*vorbis/ ) {
161 $HTML5Media{mime} = 'video/ogg';
163 elsif ( $HTML5Media{codecs} =~ /vp8.*vorbis/ ) {
164 $HTML5Media{mime} = 'video/webm';
166 elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'ogg') ) {
167 $HTML5Media{mime} = 'audio/ogg';
169 elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'webm') ) {
170 $HTML5Media{mime} = 'audio/webm';
173 ### …or just from file extension
174 else {
175 if ( $HTML5Media{extension} eq 'ogv' ) {
176 $HTML5Media{mime} = 'video/ogg';
177 $HTML5Media{codecs} = 'theora,vorbis';
179 if ( $HTML5Media{extension} eq 'oga' ) {
180 $HTML5Media{mime} = 'audio/ogg';
181 $HTML5Media{codecs} = 'vorbis';
183 elsif ( $HTML5Media{extension} eq 'spx' ) {
184 $HTML5Media{mime} = 'audio/ogg';
185 $HTML5Media{codecs} = 'speex';
187 elsif ( $HTML5Media{extension} eq 'opus' ) {
188 $HTML5Media{mime} = 'audio/ogg';
189 $HTML5Media{codecs} = 'opus';
191 elsif ( $HTML5Media{extension} eq 'vtt' ) {
192 $HTML5Media{mime} = 'text/vtt';
195 # codecs
196 if ( $HTML5Media{codecs} ) {
197 $HTML5Media{codecblock} = '; codecs="' . $HTML5Media{codecs} . '"';
199 else {
200 $HTML5Media{codecblock} = '';
202 # type
203 if ( $HTML5Media{mime} ) {
204 $HTML5Media{typeblock} = ' type=\'' . $HTML5Media{mime} . $HTML5Media{codecblock} . '\'';
206 else {
207 $HTML5Media{typeblock} = '';
209 # element
210 if ( $HTML5Media{mime} =~ /audio/ ) {
211 $HTML5Media{type} = 'audio';
213 elsif ( $HTML5Media{mime} =~ /video/ ) {
214 $HTML5Media{type} = 'video';
216 elsif ( $HTML5Media{mime} =~ /text/ ) {
217 $HTML5Media{type} = 'track';
219 # push
220 if ( $HTML5Media{srcblock} && $HTML5Media{type} ) {
221 push (@HTML5Media_sets, \%HTML5Media);
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 = '';
232 elsif ( ($media->{mime}) && ($media->{mime} =~ /video/) ) {
233 $HTML5MediaParent = 'video';
234 $HTML5MediaWidth = ' width="480"';
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';
244 else {
245 $media->{child} = $media->{type};
249 return (
250 HTML5MediaEnabled => ( (scalar(@HTML5Media_sets) > 0) && ($HTML5MediaParent) ),
251 HTML5MediaSets => \@HTML5Media_sets,
252 HTML5MediaParent => $HTML5MediaParent,
253 HTML5MediaWidth => $HTML5MediaWidth,