Skip to content

Commit

Permalink
Use Ramp for embedded player
Browse files Browse the repository at this point in the history
  • Loading branch information
masaball committed Apr 8, 2024
1 parent aae0d9c commit 6d19304
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 301 deletions.
4 changes: 0 additions & 4 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,4 @@
// include all of our vendored js
//= require_tree ../../../vendor/assets/javascripts/.

// Require VideoJS and VideoJS quality selector for embedded player
//= require video.js/dist/video.min.js
//= require @silvermine/videojs-quality-selector/dist/js/silvermine-videojs-quality-selector.min.js

//= require_tree .
3 changes: 0 additions & 3 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,3 @@
@import 'avalon';

@import "datatables";

@import "video.js/dist/video-js.css";
@import "@silvermine/videojs-quality-selector/dist/css/quality-selector.css";
116 changes: 0 additions & 116 deletions app/assets/stylesheets/embed.scss

This file was deleted.

8 changes: 0 additions & 8 deletions app/controllers/master_files_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,6 @@ def show
end

def embed
if can? :read, @master_file
@stream_info = secure_streams(@master_file.stream_details, @master_file.media_object_id)
@stream_info['t'] = view_context.parse_media_fragment(params[:t]) # add MediaFragment from params
@stream_info['link_back_url'] = view_context.share_link_for(@master_file)
end

@player_width = "100%"
@player_height = "100%"
respond_to do |format|
format.html do
response.headers.delete "X-Frame-Options"
Expand Down
118 changes: 118 additions & 0 deletions app/javascript/components/EmbeddedRamp.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright 2011-2024, The Trustees of Indiana University and Northwestern
* University. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
* --- END LICENSE_HEADER BLOCK ---
*/

import React from 'react';
import {
IIIFPlayer,
MediaPlayer
} from '@samvera/ramp';
import 'video.js/dist/video-js.css';
import "@samvera/ramp/dist/ramp.css";
import './Ramp.scss';

const Ramp = ({
urls,
media_object_id
}) => {
const [manifestUrl, setManifestUrl] = React.useState('');
const [startCanvasId, setStartCanvasId] = React.useState();
const [startCanvasTime, setStartCanvasTime] = React.useState();
let interval;

React.useEffect(() => {
const { base_url, fullpath_url } = urls;
// Split the current path from the time fragment in the format .../:id?t=time
let [fullpath, start_time] = fullpath_url.split('?t=');
// Split the current path in the format /master_files/:mf_id/embed
let [_, __, mf_id, ___] = fullpath.split('/');
// Build the manifest URL
let url = `${base_url}/media_objects/${media_object_id}/manifest.json`;

// Set start Canvas ID and start time in the state for Ramp
setStartCanvasId(
mf_id && mf_id != undefined
? `${base_url}/media_objects/${media_object_id}/manifest/canvas/${mf_id}`
: undefined
);
setStartCanvasTime(
start_time && start_time != undefined
? parseFloat(start_time)
: undefined
);
setManifestUrl(url);

interval = setInterval(addControls, 500);

// Clear interval upon component unmounting
return () => clearInterval(interval);
}, []);

const addControls = () => {
let player = document.getElementById('iiif-media-player');
if (player && player.player) {
let embeddedPlayer = player.player

// Player API handling
window.addEventListener('message', function(event) {
var command = event.data.command;

if (command=='play') embeddedPlayer.play();
else if (command=='pause') embeddedPlayer.pause();
else if (command=='toggle_loop') {
embeddedPlayer.loop() ? embeddedPlayer.loop(false): embeddedPlayer.loop(true);
embeddedPlayer.autoplay() ? embeddedPlayer.autoplay(false) : embeddedPlayer.autoplay(true);
}
else if (command=='set_offset') embeddedPlayer.currentTime(event.data.offset); // time is in seconds
else if (command=='get_offset') event.source.postMessage({'command': 'currentTime','currentTime': embeddedPlayer.currentTime()}, event.origin);
});

/*
Quality selector extends outside iframe for audio items, so we need to disable that control
and rely on the quality automatically selected by the user's system.
*/
if (embeddedPlayer.isAudio()) { embeddedPlayer.controlBar.removeChild('qualitySelector'); }

// Create button component for "View in Repository" and add to control bar
let repositoryUrl = Object.values(urls).join('/').replace('/embed', '');
let position = embeddedPlayer.isAudio() ? embeddedPlayer.controlBar.children_.length : embeddedPlayer.controlBar.children_.length - 1;
var viewInRepoButton = embeddedPlayer.getChild('ControlBar').addChild('button', {
clickHandler: function(event) {
window.open(repositoryUrl, '_blank').focus();
}
}, position);

viewInRepoButton.addClass('vjs-custom-external-link');
viewInRepoButton.controlText('View in Repository');

// Add button icon
document.querySelector('.vjs-custom-external-link .vjs-icon-placeholder').innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><style>svg{fill:#ffffff}</style><path d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg>'

// This function only needs to run once, so we clear the interval here
clearInterval(interval);
}
};

return (
<IIIFPlayer manifestUrl={manifestUrl}
customErrorMessage='This embed encountered an error. Please refresh or contact an administrator.'
startCanvasId={startCanvasId}
startCanvasTime={startCanvasTime}>
<MediaPlayer enableFileDownload={false} />
</IIIFPlayer>
);
};

export default Ramp;
2 changes: 1 addition & 1 deletion app/javascript/components/MediaObjectRamp.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023, The Trustees of Indiana University and Northwestern
* Copyright 2011-2024, The Trustees of Indiana University and Northwestern
* University. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/components/PlaylistRamp.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023, The Trustees of Indiana University and Northwestern
* Copyright 2011-2024, The Trustees of Indiana University and Northwestern
* University. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
Expand Down
6 changes: 2 additions & 4 deletions app/views/layouts/embed.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ Unless required by applicable law or agreed to in writing, software distributed
specific language governing permissions and limitations under the License.
--- END LICENSE_HEADER BLOCK ---
%>
<% content_for :page_styles do %>
<%= stylesheet_link_tag 'embed' %>
<% end %>

<!DOCTYPE html>
<html lang="en">
<head>
Expand All @@ -28,6 +24,8 @@ Unless required by applicable law or agreed to in writing, software distributed
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<%= favicon_link_tag %>
<%= stylesheet_link_tag "application", media: "all" %>
<%= stylesheet_pack_tag 'application' %>
<%= javascript_pack_tag 'application' %>
<%= yield :page_styles %>
<%= yield :additional_head_content %>
<%= render "modules/google_analytics" %>
Expand Down
31 changes: 6 additions & 25 deletions app/views/master_files/_player.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,9 @@ Unless required by applicable law or agreed to in writing, software distributed
--- END LICENSE_HEADER BLOCK ---
%>
<%= render partial: 'modules/player/section', locals: {section: @master_file, section_info: @stream_info, f_start: @f_start, f_end: @f_end} %>
<% content_for :page_scripts do %>

<script>
window.addEventListener('message', function(event) {
var command = event.data.command;
let embeddedPlayer = videojs.getPlayer('video-js-embed-<%= @master_file.id %>_html5_api');

if (command=='play') embeddedPlayer.play();
else if (command=='pause') embeddedPlayer.pause();
else if (command=='toggle_loop') {
embeddedPlayer.loop() ? embeddedPlayer.loop(false): embeddedPlayer.loop(true);
embeddedPlayer.autoplay() ? embeddedPlayer.autoplay(false) : embeddedPlayer.autoplay(true);
}
else if (command=='set_offset') embeddedPlayer.currentTime(event.data.offset); // time is in seconds
else if (command=='get_offset') event.source.postMessage({'command':'currentTime','currentTime':embeddedPlayer.currentTime()}, event.origin);
});
</script>

<style>
a { text-decoration: none; }
a:hover { text-decoration: underline }
</style>
<% end %>
<%= react_component("EmbeddedRamp",
{
urls: { base_url: request.protocol+request.host_with_port, fullpath_url: request.fullpath },
media_object_id: @master_file.media_object_id
}
) %>
20 changes: 0 additions & 20 deletions app/views/modules/player/_section.html.erb

This file was deleted.

Loading

0 comments on commit 6d19304

Please sign in to comment.