Skip to content

Commit

Permalink
Merge pull request #558 from sul-dlss/545-dash-player
Browse files Browse the repository at this point in the history
Add Dash.js reference player as MPEG-DASH prototype
  • Loading branch information
ndushay committed May 3, 2016
2 parents 00ffb54 + 5ce7e97 commit 648cfaf
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 20 deletions.
47 changes: 47 additions & 0 deletions app/assets/javascripts/modules/media_viewer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//= require modules/thumb_slider
/*global ThumbSlider */
/*global dashjs */

(function( global ) {
'use strict';
Expand Down Expand Up @@ -46,9 +47,55 @@
.addThumbnailsToSlider(thumbsForSlider());
}

function loadDashPlayerJavascript(callback) {
var playerJS = jQuery('[data-sul-embed-dash-player]')
.data('sul-embed-dash-player');

jQuery.getScript(playerJS).done(callback);
}

// canPlayType() returns 'probably', 'maybe', or ''
function canPlayHLS() {
var hlsMimeType = 'application/vnd.apple.mpegURL';
var tempVideo = document.createElement('video');
var canPlayTypsHLS = tempVideo.canPlayType(hlsMimeType);
return canPlayTypsHLS !== '';
}

function removeAllMediaDataSrc() {
jQuery('.sul-embed-media audio, .sul-embed-media video').each(function() {
jQuery(this).removeAttr('data-src');
});
}

function preloadVideoUrls() {
jQuery('.sul-embed-media video').each(function() {
$(this).data('src');
});
}

function initialzeDashPlayerForAllVideos() {
preloadVideoUrls();
loadDashPlayerJavascript(function() {
jQuery('.sul-embed-media video').each(function() {
var url = jQuery(this).data('src');
var player = dashjs.MediaPlayer().create();
player.initialize(this, url, false);
});
});
}

return {
init: function() {
setupThumbSlider();
this.initialzeDashPlayer();
},

initialzeDashPlayer: function() {
if ( !canPlayHLS() ) {
initialzeDashPlayerForAllVideos();
}
removeAllMediaDataSrc();
}
};
})();
Expand Down
13 changes: 13 additions & 0 deletions app/assets/javascripts/vendor/dash.js

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ squash_disable: <%= (Rails.env.development? || Rails.env.test?) %>
geo_external_url: 'https://earthworks.stanford.edu/catalog/stanford-'
geo_wms_url: 'https://geowebservices.stanford.edu/geoserver/wms/'
was_thumbs_url: 'https://thumbnail-service-example'
streaming_url_suffixes:
hls: '.m3u8'
dash: '.mpd'
streaming:
source_types:
- hls
hls:
suffix: '.m3u8'
mimetype: 'application/x-mpegURL'
dash:
suffix: '.mpd'
mimetype: 'application/dash+xml'
36 changes: 22 additions & 14 deletions lib/embed/media_tag.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
module Embed
# Utility class to handle generating HTML media tags
# Utility class to handle generating HTML <video> and <audio> tags
# Currently, MPEG-DASH is used at the <video> element level (in a data attribute to be picked up by javascript)
# and HLS is used as a <source> within the <video> or <audio> tag.
class MediaTag
SUPPORTED_MEDIA_TYPES = [:audio, :video].freeze
# ENABLED_STREAMING_TYPES may go away once we implement dash,
# and we may just handle contructing the URLs directly in the markup
# where necessary.
ENABLED_STREAMING_TYPES = [:hls].freeze

def initialize(ng_doc, viewer)
@ng_document = ng_doc
Expand All @@ -19,37 +17,47 @@ def initialize(ng_doc, viewer)
attr_reader :ng_document, :purl_document, :request, :viewer

def build_markup
file_index = 0
purl_document.contents.each do |resource|
label = resource.description
next unless SUPPORTED_MEDIA_TYPES.include?(resource.type.to_sym)
label = resource.description
resource.files.each do |file|
label = file.title if label.blank?
ng_document.send(
resource.type.to_sym,
'data-file-label': label,
'data-slider-object': file_index,
'data-src': streaming_url_for(file, :dash),
controls: 'controls',
height: "#{viewer.body_height.to_i - 24}px"
) do
enabled_streaming_sources(file)
end
file_index += 1
) { enabled_streaming_sources(file) }
@file_index += 1
end
end
end

def enabled_streaming_sources(file)
ENABLED_STREAMING_TYPES.each do |streaming_type|
enabled_streaming_types.each do |streaming_type|
ng_document.source(
src: streaming_url_for(file, streaming_type),
type: file.mimetype
type: streaming_settings_for(streaming_type)[:mimetype]
)
end
end

def streaming_settings_for(type)
Settings.streaming[type] || {}
end

def enabled_streaming_types
Settings.streaming[:source_types]
end

def file_index
@file_index ||= 0
end

def streaming_url_for(file, type)
suffix = Settings.streaming_url_suffixes[type]
suffix = streaming_settings_for(type)[:suffix]
"#{Settings.stacks_url}/media/#{purl_document.druid}/#{file.title}/stream#{suffix}"
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/embed/viewer/media.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ def body_html
doc.div(
class: 'sul-embed-body sul-embed-media',
'style' => "max-height: #{body_height}px",
'data-sul-embed-theme' => asset_url('media.css').to_s
'data-sul-embed-theme' => asset_url('media.css').to_s,
'data-sul-embed-dash-player' => asset_url('vendor/dash.js').to_s
) do
Embed::MediaTag.new(doc, self)
doc.script { doc.text ";jQuery.getScript(\"#{asset_url('media.js')}\");" }
Expand Down
9 changes: 7 additions & 2 deletions spec/lib/embed/media_tag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
subject
end

it 'includes a data-src attribute for the dash player' do
expect(document).to receive(:video).twice.with(hash_including(:'data-src'))
subject
end

it 'includes a height attribute equal to the body height minus some px to make way for the thumb slider' do
expect(document).to receive(:video).twice.with(hash_including('height': '276px'))
subject
Expand All @@ -53,10 +58,10 @@

describe 'private methods' do
before { expect(document).to receive(:video).at_least(:once) }
let(:file) { double('File', title: 'abc123.mp4', mimetype: 'video/mp4') }
let(:file) { double('File', title: 'abc123.mp4') }
describe '#enabled_streaming_sources' do
it 'adds a source element for every enabled type' do
expect(document).to receive(:source).with(hash_including(:src, type: 'video/mp4'))
expect(document).to receive(:source).with(hash_including(:src, type: 'application/x-mpegURL'))
subject.send(:enabled_streaming_sources, file)
end
end
Expand Down
9 changes: 9 additions & 0 deletions spec/lib/embed/viewer/media_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
body_html = Capybara.string(media_viewer.body_html)
expect(body_html).to have_css('video')
end

it 'includes the dash player loaction in a data attribute' do
attribute = 'data-sul-embed-dash-player'
allow(request).to receive(:rails_request).and_return(double(host_with_port: ''))
stub_request(request)
body_html = Capybara.string(media_viewer.body_html)
player_url = body_html.find("[#{attribute}]")[attribute]
expect(player_url).to match(%r{assets/vendor/dash\.js})
end
end

describe '#download_html' do
Expand Down

0 comments on commit 648cfaf

Please sign in to comment.