Marcel de Rooy
158442eb9e
The get routine actually returns records from uploaded_files. It should be possible to replace its calls by direct calls of Koha::UploadedFiles. This patch is the crux of this patch set. It deals with all scripts that use Koha::Upload. In the process we do: [1] Add a file_handle method to Koha::UploadedFile. This was previously arranged via the fh parameter of get. [2] Add a full_path method to UploadedFile. Previously returned in the path hash key of get. (Name is replaced by filename.) [3] Add a search_term method too (implementing get({ term => .. }). This logic came from _lookup. [4] Add a keep_file parameter to delete method. Only used in test now. Test plan: [1] Run t/db_dependent/Upload.t [2] Go to Tools/Upload. Add an upload, download and delete. [3] Add another public upload , search for it. Use the hashvalue to download via opac with URL: cgi-bin/koha/opac-retrieve-file.pl?id=[hashvalue] [4] Go to Tools/Stage MARC for import. Import a marc file. [5] Go to Tools/Upload local cover image. Import an image file. Enable OPACLocalCoverImages to see result. [6] Test uploading a offline circulation file: Enable AllowOfflineCirculation, and create a koc file (plain text): Line1: Version=1.0\tA=1\tB=2 Line2: 2016-11-23 16:00:00 345\treturn\t[barcode] Note: Replace tabs and barcode. The number of tabs is essential! Checkout the item with your barcode. Go to Circulation/Offline circulation file upload. Upload and click Apply directly. Checkout again. Repeat Offline circulation file upload. Now click Add to offline circulation queue. [7] Connect the upload plugin to field 856$u. Enable HTML5MediaEnabled. Upload a webm file via the plugin. Click Choose to save the URL, and put 'video/webm' into 856$q. Save the biblio record. Check if you see the media tab with player on staff detail. (See also: Bug 17673 about empty OPACBaseURL.) Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
262 lines
9.7 KiB
Perl
262 lines
9.7 KiB
Perl
package C4::HTML5Media;
|
|
|
|
# Copyright 2012/2015 Mirko Tietgen
|
|
#
|
|
# This file is part of Koha.
|
|
#
|
|
# Koha is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Koha is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use C4::Context;
|
|
use MARC::Field;
|
|
use Koha::UploadedFiles;
|
|
|
|
=head1 HTML5Media
|
|
|
|
C4::HTML5Media
|
|
|
|
=head1 Description
|
|
|
|
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.
|
|
|
|
=cut
|
|
|
|
=head2 gethtml5media
|
|
|
|
Get all relevant data from field 856. Takes a $record in the subroutine call, sets appropriate params.
|
|
|
|
=cut
|
|
|
|
sub gethtml5media {
|
|
my $self = shift;
|
|
my $record = shift;
|
|
my @HTML5Media_sets = ();
|
|
my @HTML5Media_fields = $record->field(856);
|
|
my $HTML5MediaParent;
|
|
my $HTML5MediaWidth;
|
|
my @HTML5MediaExtensions = split( /\|/, C4::Context->preference("HTML5MediaExtensions") );
|
|
my $HTML5MediaYouTube = C4::Context->preference("HTML5MediaYouTube");
|
|
my $marcflavour = C4::Context->preference("marcflavour");
|
|
my $isyoutube = 0;
|
|
foreach my $HTML5Media_field (@HTML5Media_fields) {
|
|
my %HTML5Media;
|
|
# protocol
|
|
if ( $HTML5Media_field->indicator(1) eq '1' ) {
|
|
$HTML5Media{protocol} = 'ftp';
|
|
}
|
|
elsif ( $HTML5Media_field->indicator(1) eq '4' ) {
|
|
$HTML5Media{protocol} = 'http';
|
|
}
|
|
elsif ( $HTML5Media_field->indicator(1) eq '7' ) {
|
|
if ($marcflavour eq 'MARC21' || $marcflavour eq 'NORMARC') {
|
|
$HTML5Media{protocol} = $HTML5Media_field->subfield('2');
|
|
}
|
|
elsif ($marcflavour eq 'UNIMARC') {
|
|
$HTML5Media{protocol} = $HTML5Media_field->subfield('y');
|
|
}
|
|
}
|
|
else {
|
|
$HTML5Media{protocol} = 'http';
|
|
}
|
|
# user
|
|
if ( $HTML5Media_field->subfield('l') ) {
|
|
$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.
|
|
}
|
|
elsif ( $HTML5Media_field->subfield('h') ) {
|
|
$HTML5Media{username} = $HTML5Media_field->subfield('h');
|
|
}
|
|
# user/pass
|
|
if ( $HTML5Media{username} && $HTML5Media_field->subfield('k') ) {
|
|
$HTML5Media{loginblock} = $HTML5Media{username} . ':' . $HTML5Media_field->subfield('k') . '@';
|
|
}
|
|
elsif ( $HTML5Media{username} ) {
|
|
$HTML5Media{loginblock} = $HTML5Media{username} . '@';
|
|
}
|
|
else {
|
|
$HTML5Media{loginblock} = '';
|
|
}
|
|
# port
|
|
if ( $HTML5Media_field->subfield('p') ) {
|
|
$HTML5Media{portblock} = ':' . $HTML5Media_field->subfield('k');
|
|
}
|
|
else {
|
|
$HTML5Media{portblock} = '';
|
|
}
|
|
# src
|
|
if ( $HTML5Media_field->subfield('u') ) {
|
|
$HTML5Media{srcblock} = $HTML5Media_field->subfield('u');
|
|
if (grep /youtu\.?be/, $HTML5Media_field->subfield('u') ) {
|
|
if ($HTML5MediaYouTube == 1) {
|
|
require WWW::YouTube::Download;
|
|
import WWW::YouTube::Download qw(playback_url);
|
|
my $youtube = WWW::YouTube::Download->new;
|
|
eval {
|
|
$HTML5Media{srcblock} = $youtube->playback_url(
|
|
$HTML5Media_field->subfield('u'), {
|
|
'fmt' => '43' #webm is the only format compatible to all modern browsers. maybe check for available qualities
|
|
}
|
|
);
|
|
};
|
|
if ($@) { warn $@; }
|
|
else { $isyoutube = 1;}
|
|
}
|
|
else {
|
|
next; # do not embed youtube videos
|
|
}
|
|
}
|
|
}
|
|
elsif ( $HTML5Media_field->subfield('a') && $HTML5Media_field->subfield('d') && $HTML5Media_field->subfield('f') ) {
|
|
$HTML5Media{host} = $HTML5Media_field->subfield('a');
|
|
$HTML5Media{host} =~ s/(^\/|\/$)//g;
|
|
$HTML5Media{path} = $HTML5Media_field->subfield('d');
|
|
$HTML5Media{path} =~ s/(^\/|\/$)//g; # TODO we could check for youtube here too, but nobody uses these fields anyway…
|
|
$HTML5Media{file} = $HTML5Media_field->subfield('f');
|
|
$HTML5Media{srcblock} = $HTML5Media{protocol} . '://' . $HTML5Media{loginblock} . $HTML5Media{host} . $HTML5Media{portblock} . '/' . $HTML5Media{path} . '/' . $HTML5Media{file};
|
|
}
|
|
else {
|
|
next; # no file to play
|
|
}
|
|
# extension
|
|
# check uploaded files
|
|
if ( $HTML5Media{srcblock} =~ /\Qopac-retrieve-file.pl\E/ ) {
|
|
my ( undef, $id ) = split /id=/, $HTML5Media{srcblock};
|
|
next if !$id;
|
|
my %public = ( ( caller )[1] =~ /opac/ ) ? ( public => 1 ): ();
|
|
my $upload = Koha::UploadedFiles->search({
|
|
hashvalue => $id, %public,
|
|
})->next;
|
|
next if !$upload || $upload->filename !~ /\./;
|
|
$HTML5Media{extension} = ( $upload->filename =~ m/([^.]+)$/ )[0];
|
|
}
|
|
# check remote files
|
|
else {
|
|
$HTML5Media{extension} = ($HTML5Media{srcblock} =~ m/([^.]+)$/)[0];
|
|
}
|
|
if ( ( !grep /\Q$HTML5Media{extension}\E/, @HTML5MediaExtensions ) && ( $isyoutube != 1) ) {
|
|
next; # not a specified media file
|
|
}
|
|
# youtube
|
|
if ($isyoutube == 1) {
|
|
$HTML5Media{mime} = 'video/webm';
|
|
}
|
|
# mime
|
|
if ( $HTML5Media_field->subfield('c') ) {
|
|
$HTML5Media{codecs} = $HTML5Media_field->subfield('c');
|
|
}
|
|
### from subfield q…
|
|
if ( $HTML5Media_field->subfield('q') ) {
|
|
$HTML5Media{mime} = $HTML5Media_field->subfield('q');
|
|
}
|
|
### …or from file extension and codecs…
|
|
elsif ( $HTML5Media{codecs} ) {
|
|
if ( $HTML5Media{codecs} =~ /theora.*vorbis/ ) {
|
|
$HTML5Media{mime} = 'video/ogg';
|
|
}
|
|
elsif ( $HTML5Media{codecs} =~ /vp8.*vorbis/ ) {
|
|
$HTML5Media{mime} = 'video/webm';
|
|
}
|
|
elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'ogg') ) {
|
|
$HTML5Media{mime} = 'audio/ogg';
|
|
}
|
|
elsif ( ($HTML5Media{codecs} =~ /^vorbis$/) && ($HTML5Media{extension} eq 'webm') ) {
|
|
$HTML5Media{mime} = 'audio/webm';
|
|
}
|
|
}
|
|
### …or just from file extension
|
|
else {
|
|
if ( $HTML5Media{extension} eq 'ogv' ) {
|
|
$HTML5Media{mime} = 'video/ogg';
|
|
$HTML5Media{codecs} = 'theora,vorbis';
|
|
}
|
|
if ( $HTML5Media{extension} eq 'oga' ) {
|
|
$HTML5Media{mime} = 'audio/ogg';
|
|
$HTML5Media{codecs} = 'vorbis';
|
|
}
|
|
elsif ( $HTML5Media{extension} eq 'spx' ) {
|
|
$HTML5Media{mime} = 'audio/ogg';
|
|
$HTML5Media{codecs} = 'speex';
|
|
}
|
|
elsif ( $HTML5Media{extension} eq 'opus' ) {
|
|
$HTML5Media{mime} = 'audio/ogg';
|
|
$HTML5Media{codecs} = 'opus';
|
|
}
|
|
elsif ( $HTML5Media{extension} eq 'vtt' ) {
|
|
$HTML5Media{mime} = 'text/vtt';
|
|
}
|
|
}
|
|
# codecs
|
|
if ( $HTML5Media{codecs} ) {
|
|
$HTML5Media{codecblock} = '; codecs="' . $HTML5Media{codecs} . '"';
|
|
}
|
|
else {
|
|
$HTML5Media{codecblock} = '';
|
|
}
|
|
# type
|
|
if ( $HTML5Media{mime} ) {
|
|
$HTML5Media{typeblock} = ' type=\'' . $HTML5Media{mime} . $HTML5Media{codecblock} . '\'';
|
|
}
|
|
else {
|
|
$HTML5Media{typeblock} = '';
|
|
}
|
|
# element
|
|
if ( $HTML5Media{mime} =~ /audio/ ) {
|
|
$HTML5Media{type} = 'audio';
|
|
}
|
|
elsif ( $HTML5Media{mime} =~ /video/ ) {
|
|
$HTML5Media{type} = 'video';
|
|
}
|
|
elsif ( $HTML5Media{mime} =~ /text/ ) {
|
|
$HTML5Media{type} = 'track';
|
|
}
|
|
# push
|
|
if ( $HTML5Media{srcblock} && $HTML5Media{type} ) {
|
|
push (@HTML5Media_sets, \%HTML5Media);
|
|
}
|
|
}
|
|
# parent element
|
|
for my $media ( @HTML5Media_sets ) {
|
|
if ( ($media->{mime}) && ($media->{mime} =~ /audio/) ) {
|
|
if ( $HTML5MediaParent ne 'video' ) {
|
|
$HTML5MediaParent = 'audio';
|
|
$HTML5MediaWidth = '';
|
|
}
|
|
}
|
|
elsif ( ($media->{mime}) && ($media->{mime} =~ /video/) ) {
|
|
$HTML5MediaParent = 'video';
|
|
$HTML5MediaWidth = ' width="480"';
|
|
}
|
|
}
|
|
# child element
|
|
for my $media ( @HTML5Media_sets ) {
|
|
if ( ($media->{type}) && ( ($media->{type} eq 'video') || ($media->{type} eq 'audio') ) ) {
|
|
if ( $media->{type} eq $HTML5MediaParent ) {
|
|
$media->{child} = 'source';
|
|
}
|
|
}
|
|
else {
|
|
$media->{child} = $media->{type};
|
|
}
|
|
}
|
|
|
|
return (
|
|
HTML5MediaEnabled => ( (scalar(@HTML5Media_sets) > 0) && ($HTML5MediaParent) ),
|
|
HTML5MediaSets => \@HTML5Media_sets,
|
|
HTML5MediaParent => $HTML5MediaParent,
|
|
HTML5MediaWidth => $HTML5MediaWidth,
|
|
);
|
|
}
|
|
|
|
1;
|