Skip to content

Commit

Permalink
Allow manual loading of records with progressive download streams ins…
Browse files Browse the repository at this point in the history
…tead of HLS streams

This allows use of mp3s pushed into avalon via inges api to playback correctly in ramp.
  • Loading branch information
cjcolvar committed Oct 7, 2024
1 parent eae4c6c commit 6c3b0ce
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 23 deletions.
30 changes: 19 additions & 11 deletions app/models/iiif_canvas_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,29 @@ def service

def video_content
# @see https://github.com/samvera-labs/iiif_manifest
stream_urls.collect { |quality, _url| video_display_content(quality) }
stream_urls.collect { |quality, url, mimetype| video_display_content(quality, url, mimetype) }
end

def video_display_content(quality)
IIIFManifest::V3::DisplayContent.new(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality),
**manifest_attributes(quality, 'Video'))
def video_display_content(quality, url, mimetype)
if mimetype.present? && mimetype != 'application/x-mpegURL'
IIIFManifest::V3::DisplayContent.new(url, **manifest_attributes(quality, 'Video', mimetype: mimetype))
else
IIIFManifest::V3::DisplayContent.new(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality),
**manifest_attributes(quality, 'Video'))
end
end

def audio_content
stream_urls.collect { |quality, _url| audio_display_content(quality) }
stream_urls.collect { |quality, url, mimetype| audio_display_content(quality, url, mimetype) }
end

def audio_display_content(quality)
IIIFManifest::V3::DisplayContent.new(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality),
**manifest_attributes(quality, 'Sound'))
def audio_display_content(quality, url, mimetype)
if mimetype.present? && mimetype != 'application/x-mpegURL'
IIIFManifest::V3::DisplayContent.new(url, **manifest_attributes(quality, 'Sound', mimetype: mimetype))
else
IIIFManifest::V3::DisplayContent.new(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality),
**manifest_attributes(quality, 'Sound'))
end
end

def supplementing_content_data(file)
Expand Down Expand Up @@ -142,7 +150,7 @@ def supplementing_content_data(file)

def stream_urls
stream_info[:stream_hls].collect do |d|
[d[:quality], d[:url]]
[d[:quality], d[:url], d[:mimetype]]
end
end

Expand Down Expand Up @@ -214,14 +222,14 @@ def parse_hour_min_sec(s)
smh[0] + (60 * smh[1]) + (3600 * smh[2])
end

def manifest_attributes(quality, media_type)
def manifest_attributes(quality, media_type, mimetype: 'application/x-mpegURL')
media_hash = {
label: quality,
width: (master_file.width || '1280').to_i,
height: (master_file.height || MasterFile::AUDIO_HEIGHT).to_i,
duration: stream_info[:duration],
type: media_type,
format: 'application/x-mpegURL'
format: mimetype
}.compact

if master_file.media_object.visibility == 'public'
Expand Down
30 changes: 19 additions & 11 deletions app/models/iiif_playlist_canvas_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,29 @@ def metadata_field(label, value, default = nil)

def video_content
# @see https://github.com/samvera-labs/iiif_manifest
stream_urls.collect { |quality, _url| video_display_content(quality) }
stream_urls.collect { |quality, url, mimetype| video_display_content(quality, url, mimetype) }
end

def video_display_content(quality)
IIIFManifest::V3::DisplayContent.new(CGI.unescape(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality, anchor: fragment_identifier)),
**manifest_attributes(quality, 'Video'))
def video_display_content(quality, url, mimetype)
if mimetype.present? && mimetype != 'application/x-mpegURL'
IIIFManifest::V3::DisplayContent.new(URI.join(url, "##{fragment_identifier}").to_s, **manifest_attributes(quality, 'Video', mimetype: mimetype))
else
IIIFManifest::V3::DisplayContent.new(CGI.unescape(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality, anchor: fragment_identifier)),
**manifest_attributes(quality, 'Video'))
end
end

def audio_content
stream_urls.collect { |quality, _url| audio_display_content(quality) }
stream_urls.collect { |quality, url, mimetype| audio_display_content(quality, url, mimetype) }
end

def audio_display_content(quality)
IIIFManifest::V3::DisplayContent.new(CGI.unescape(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality, anchor: fragment_identifier)),
**manifest_attributes(quality, 'Sound'))
def audio_display_content(quality, url, mimetype)
if mimetype.present? && mimetype != 'application/x-mpegURL'
IIIFManifest::V3::DisplayContent.new(URI.join(url, "##{fragment_identifier}").to_s, **manifest_attributes(quality, 'Sound', mimetype: mimetype))
else
IIIFManifest::V3::DisplayContent.new(CGI.unescape(Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality, anchor: fragment_identifier)),
**manifest_attributes(quality, 'Sound'))
end
end

def marker_content(marker)
Expand Down Expand Up @@ -174,7 +182,7 @@ def supplemental_attributes(file)

def stream_urls
stream_info[:stream_hls].collect do |d|
[d[:quality], d[:url]]
[d[:quality], d[:url], d[:mimetype]]
end
end

Expand All @@ -192,14 +200,14 @@ def simple_iiif_range(label = stream_info[:embed_title])
)
end

def manifest_attributes(quality, media_type)
def manifest_attributes(quality, media_type, mimetype: 'application/x-mpegURL')
media_hash = {
label: quality,
width: (master_file.width || '1280').to_i,
height: (master_file.height || MasterFile::AUDIO_HEIGHT).to_i,
duration: stream_info[:duration],
type: media_type,
format: 'application/x-mpegURL'
format: mimetype
}.compact

if master_file.media_object.visibility == 'public'
Expand Down
3 changes: 2 additions & 1 deletion spec/factories/derivatives.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
video_bitrate { '4000000.0' }
audio_codec { 'AAC' }
audio_bitrate { '163842.0' }
absolute_location { 'file:///srv/avalon/content/6f69c008-06a4-4bad-bb60-26297f0b4c06/35bddaa0-fbb4-404f-ab76-58f22921529c/warning.mp4' }
mime_type { nil }
derivativeFile { 'file:///srv/avalon/content/6f69c008-06a4-4bad-bb60-26297f0b4c06/35bddaa0-fbb4-404f-ab76-58f22921529c/warning.mp4' }

trait :with_master_file do
after(:create) do |d|
Expand Down
26 changes: 26 additions & 0 deletions spec/models/iiif_canvas_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@
expect(subject.width).to eq 1280
expect(subject.height).to eq 40
end

context 'with mp3 file' do
let(:mp3_url) { 'https://streaming.example.com/dir/file.mp3' }
let(:derivative) { FactoryBot.build(:derivative, hls_url: mp3_url, mime_type: 'audio/mpeg' ) }

it 'has format' do
expect(subject.format).to eq 'audio/mpeg'
end

it 'has progressive download url' do
expect(subject.url).to eq mp3_url
end
end
end

context 'when video file' do
Expand All @@ -72,6 +85,19 @@
expect(subject.width).to eq 1024
expect(subject.height).to eq 768
end

context 'with mp4 file' do
let(:mp4_url) { 'https://streaming.example.com/dir/file.mp4' }
let(:derivative) { FactoryBot.build(:derivative, hls_url: mp4_url, mime_type: 'video/mp4' ) }

it 'has format' do
expect(subject.format).to eq 'video/mp4'
end

it 'has progressive download url' do
expect(subject.url).to eq mp4_url
end
end
end
end

Expand Down
26 changes: 26 additions & 0 deletions spec/models/iiif_playlist_canvas_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@
expect(subject.width).to eq 1280
expect(subject.height).to eq 40
end

context 'with mp3 file' do
let(:mp3_url) { 'https://streaming.example.com/dir/file.mp3' }
let(:derivative) { FactoryBot.build(:derivative, hls_url: mp3_url, mime_type: 'audio/mpeg' ) }

it 'has format' do
expect(subject.format).to eq 'audio/mpeg'
end

it 'has progressive download url with media fragment' do
expect(subject.url).to eq "#{mp3_url}#t=#{playlist_item.start_time / 1000},#{playlist_item.end_time / 1000}"
end
end
end

context 'when video file' do
Expand All @@ -105,6 +118,19 @@
expect(subject.width).to eq 1024
expect(subject.height).to eq 768
end

context 'with mp4 file' do
let(:mp4_url) { 'https://streaming.example.com/dir/file.mp4' }
let(:derivative) { FactoryBot.build(:derivative, hls_url: mp4_url, mime_type: 'video/mp4' ) }

it 'has format' do
expect(subject.format).to eq 'video/mp4'
end

it 'has progressive download url with media fragment' do
expect(subject.url).to eq "#{mp4_url}#t=#{playlist_item.start_time / 1000},#{playlist_item.end_time / 1000}"
end
end
end

context 'when a user does not have access to a restricted item' do
Expand Down

0 comments on commit 6c3b0ce

Please sign in to comment.