Skip to content

Commit

Permalink
Merge pull request #5524 from avalonmediasystem/playlist_captions
Browse files Browse the repository at this point in the history
Add captions to playlist IIIF manifests
  • Loading branch information
masaball authored Dec 15, 2023
2 parents b42fc30 + 4e8ef41 commit 6a56d31
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 12 deletions.
37 changes: 36 additions & 1 deletion app/models/iiif_playlist_canvas_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ def display_content

def annotation_content
return if cannot_read_item || master_file.nil?
playlist_item.marker.collect { |m| marker_content(m) }
annotations = supplemental_captions.collect { |file| supplemental_captions_data(file) }
annotations += playlist_item.marker.collect { |marker| marker_content(marker) }
end

def placeholder_content
Expand Down Expand Up @@ -127,6 +128,40 @@ def marker_content(marker)
IIIFManifest::V3::AnnotationContent.new(annotation_id: url, **marker_attributes(marker))
end

def supplemental_captions
files = master_file.supplemental_files(tag: 'caption')
files += [master_file.captions] if master_file.captions.present? && master_file.captions.persisted?
files
end

def supplemental_captions_data(file)
url = if !file.is_a?(SupplementalFile)
Rails.application.routes.url_helpers.captions_master_file_url(master_file.id)
elsif file.tags.include?('caption')
Rails.application.routes.url_helpers.captions_master_file_supplemental_file_url(master_file.id, file.id)
end
IIIFManifest::V3::AnnotationContent.new(body_id: url, **supplemental_attributes(file))
end

def supplemental_attributes(file)
if file.is_a?(SupplementalFile)
label = file.tags.include?('machine_generated') ? file.label + ' (machine generated)' : file.label
format = file.file.content_type
language = file.language || 'en'
else
label = 'English'
format = file.mime_type
language = 'en'
end
{
motivation: 'supplementing',
label: label,
type: 'Text',
format: format,
language: language
}
end

def stream_urls
stream_info[:stream_hls].collect do |d|
[d[:quality], d[:url]]
Expand Down
78 changes: 67 additions & 11 deletions spec/models/iiif_playlist_canvas_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,24 +116,80 @@
end

describe '#annotation_content' do
let(:marker) { FactoryBot.create(:avalon_marker) }
let(:playlist_item) { FactoryBot.build(:playlist_item, clip: playlist_clip, marker: [marker]) }
subject { presenter.annotation_content }

it "serializes playlist markers as iiif annotations" do
expect(subject).to all be_a(IIIFManifest::V3::AnnotationContent)
end
context 'item has markers and no captions' do
let(:marker) { FactoryBot.create(:avalon_marker) }
let(:playlist_item) { FactoryBot.build(:playlist_item, clip: playlist_clip, marker: [marker]) }

it "serializes playlist markers as iiif annotations" do
expect(subject).to all be_a(IIIFManifest::V3::AnnotationContent)
expect(subject.length).to eq 1
end

it "includes marker label" do
expect(subject.first.value).to eq marker.title
end

it "includes marker start_time" do
expect(subject.first.media_fragment).to eq "t=#{marker.start_time}"
end

it "includes marker label" do
expect(subject.first.value).to eq marker.title
it "includes 'highlighting' motivation" do
expect(subject.first.motivation).to eq 'highlighting'
end
end

it "includes marker start_time" do
expect(subject.first.media_fragment).to eq "t=#{marker.start_time}"
context 'item has captions and no markers' do
let(:caption_file) { FactoryBot.create(:supplemental_file, :with_caption_file, :with_caption_tag) }
let(:master_file) { FactoryBot.create(:master_file, :with_captions, media_object: media_object, derivatives: [derivative], supplemental_files: [caption_file]) }

it "serializes captions as iiif annotations" do
expect(subject).to all be_a(IIIFManifest::V3::AnnotationContent)
expect(subject.length).to eq 2
end

it "includes paths to supplemental and legacy caption files" do
expect(subject.any? { |content| content.body_id =~ /supplemental_files\/#{caption_file.id}\/captions/ }).to eq true
expect(subject.any? { |content| content.body_id =~ /master_files\/#{master_file.id}\/captions/ }).to eq true
end

it "includes 'supplementing' motivation" do
expect(subject.any? { |content| content.motivation =~ /supplementing/ }).to eq true
end
end

it "includes 'highlighting' motivation" do
expect(subject.first.motivation).to eq 'highlighting'
context 'item has captions and markers' do
let(:marker) { FactoryBot.create(:avalon_marker) }
let(:playlist_item) { FactoryBot.build(:playlist_item, clip: playlist_clip, marker: [marker]) }
let(:caption_file) { FactoryBot.create(:supplemental_file, :with_caption_file, :with_caption_tag) }
let(:master_file) { FactoryBot.create(:master_file, :with_captions, media_object: media_object, derivatives: [derivative], supplemental_files: [caption_file]) }

it "serializes captions as iiif annotations" do
expect(subject).to all be_a(IIIFManifest::V3::AnnotationContent)
expect(subject.length).to eq 3
end

it "includes marker label" do
expect(subject.any? { |content| content.value =~ /#{marker.title}/ }).to eq true
end

it "includes marker start_time" do
expect(subject.any? { |content| content.media_fragment =~ /t=#{marker.start_time}/ }).to eq true
end

it "includes paths to supplemental and legacy caption files" do
expect(subject.any? { |content| content.body_id =~ /supplemental_files\/#{caption_file.id}\/captions/ }).to eq true
expect(subject.any? { |content| content.body_id =~ /master_files\/#{master_file.id}\/captions/ }).to eq true
end

it "includes 'highlighting' motivation" do
expect(subject.any? { |content| content.motivation =~ /highlighting/ }).to eq true
end

it "includes 'supplementing' motivation" do
expect(subject.any? { |content| content.motivation =~ /supplementing/ }).to eq true
end
end

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

0 comments on commit 6a56d31

Please sign in to comment.