diff --git a/app/models/derivative.rb b/app/models/derivative.rb index bf4526c789..bdc923ec0a 100644 --- a/app/models/derivative.rb +++ b/app/models/derivative.rb @@ -71,22 +71,36 @@ class Derivative < ActiveFedora::Base def initialize(*args) super(*args) - self.managed = true + self.managed = true if self.managed.nil? end - def set_streaming_locations! + alias_method :'_hls_url', :'hls_url' + def hls_url if managed path = Addressable::URI.parse(absolute_location).path - self.location_url = Avalon::StreamMapper.stream_path(path) is_mp3 = format == "audio" && audio_codec == "mp3" - self.hls_url = Avalon::StreamMapper.map(path, 'http', (is_mp3 ? "audio_mp3" : format)) + Avalon::StreamMapper.map(path, 'http', (is_mp3 ? "audio_mp3" : format)) + else + _hls_url end - self + rescue + nil + end + + alias_method :'_location_url', :'location_url' + def location_url + if managed + path = Addressable::URI.parse(absolute_location).path + Avalon::StreamMapper.stream_path(path) + else + _location_url + end + rescue + nil end def absolute_location=(value) self.derivativeFile = value - set_streaming_locations! derivativeFile end diff --git a/app/presenters/speedy_af/proxy/derivative.rb b/app/presenters/speedy_af/proxy/derivative.rb index 1d934076b6..a521d85d85 100644 --- a/app/presenters/speedy_af/proxy/derivative.rb +++ b/app/presenters/speedy_af/proxy/derivative.rb @@ -18,4 +18,27 @@ class SpeedyAF::Proxy::Derivative < SpeedyAF::Base def bitrate audio_bitrate.to_i + video_bitrate.to_i end + + def hls_url + if managed + path = Addressable::URI.parse(absolute_location).path + is_mp3 = format == "audio" && audio_codec == "mp3" + Avalon::StreamMapper.map(path, 'http', (is_mp3 ? "audio_mp3" : format)) + else + @attrs[:hls_url] + end + rescue + nil + end + + def location_url + if managed + path = Addressable::URI.parse(absolute_location).path + Avalon::StreamMapper.stream_path(path) + else + @attrs[:location_url] + end + rescue + nil + end end diff --git a/lib/tasks/avalon.rake b/lib/tasks/avalon.rake index e3c0a94c51..44f813ceab 100644 --- a/lib/tasks/avalon.rake +++ b/lib/tasks/avalon.rake @@ -101,15 +101,6 @@ namespace :avalon do FileUtils.rm(Dir['public/stylesheets/cache/[^.]*']) end end - namespace :derivative do - desc "Sets streaming urls for derivatives based on configured content_path in avalon.yml" - task :set_streams => :environment do - Derivative.find_each({},{batch_size:5}) do |derivative| - derivative.set_streaming_locations! - derivative.save! - end - end - end namespace :batch do desc "Starts Avalon batch ingest" task :ingest => :environment do diff --git a/spec/controllers/master_files_controller_spec.rb b/spec/controllers/master_files_controller_spec.rb index 959b19cec3..de9b41490e 100644 --- a/spec/controllers/master_files_controller_spec.rb +++ b/spec/controllers/master_files_controller_spec.rb @@ -906,7 +906,8 @@ class << file it 'should display a flash message if file is not found' do allow(ENV).to receive(:[]).and_call_original allow(ENV).to receive(:[]).with("ENCODE_WORK_DIR").and_return(Rails.root.join('spec').to_s) - allow(high_derivative).to receive(:hls_url).and_return('missing') + high_derivative.absolute_location = 'missing' + high_derivative.save! get :download_derivative, params: { id: master_file.id } expect(response).to redirect_to(edit_media_object_path(media_object)) expect(flash[:error]).to be_present diff --git a/spec/factories/derivatives.rb b/spec/factories/derivatives.rb index 0f4b2641a8..ebaee7a093 100644 --- a/spec/factories/derivatives.rb +++ b/spec/factories/derivatives.rb @@ -15,9 +15,9 @@ FactoryBot.define do factory :derivative do duration { "21575" } - location_url { "6f69c008-06a4-4bad-bb60-26297f0b4c06/35bddaa0-fbb4-404f-ab76-58f22921529c/warning" } + location_url { nil } track_id { "track-6" } - hls_url { "http://localhost:3000/streams/6f69c008-06a4-4bad-bb60-26297f0b4c06/35bddaa0-fbb4-404f-ab76-58f22921529c/warning.mp4.m3u8" } + hls_url { nil } hls_track_id { "track-8" } width { '1024' } height { '768' } diff --git a/spec/models/derivative_spec.rb b/spec/models/derivative_spec.rb index e09f971145..2c2f2ba737 100644 --- a/spec/models/derivative_spec.rb +++ b/spec/models/derivative_spec.rb @@ -60,8 +60,8 @@ let(:http_base) { Settings.streaming.http_base } let(:root) { Settings.streaming.content_path } let(:location) { "file://#{root}/c5e0f8b8-3f69-40de-9524-604f03b5f867/8c871d4b-a9a6-4841-8e2a-dd98cf2ee625/content.mp4" } - let(:audio_derivative) { Derivative.new(audio_codec: 'AAC').tap { |d| d.absolute_location = location } } - let(:video_derivative) { Derivative.new(video_codec: 'AVC').tap { |d| d.absolute_location = location } } + let(:audio_derivative) { Derivative.new(audio_codec: 'AAC', derivativeFile: location) } + let(:video_derivative) { Derivative.new(video_codec: 'AVC', derivativeFile: location) } around :each do |example| old_value = Avalon::StreamMapper.streaming_server @@ -113,6 +113,33 @@ expect(audio_derivative.streaming_url(true)).to eq("#{http_base}/mp4:c5e0f8b8-3f69-40de-9524-604f03b5f867/8c871d4b-a9a6-4841-8e2a-dd98cf2ee625/content.mp4/playlist.m3u8") end end + + describe "unmanaged" do + let(:audio_derivative) { Derivative.new(audio_codec: 'AAC', derivativeFile: location, managed: false, hls_url: hls_url) } + let(:video_derivative) { Derivative.new(video_codec: 'AVC', derivativeFile: location, managed: false, hls_url: hls_url) } + let(:hls_url) { 'http://streaming.server/hls.m3u8' } + + it "does not map stored hls_url" do + expect(video_derivative.streaming_url(true)).to eq hls_url + expect(audio_derivative.streaming_url(true)).to eq hls_url + end + end + + describe "dynamic based on config" do + it "HTTP video" do + Avalon::StreamMapper.streaming_server = :wowza + expect(video_derivative.streaming_url(true)).to eq("#{http_base}/mp4:c5e0f8b8-3f69-40de-9524-604f03b5f867/8c871d4b-a9a6-4841-8e2a-dd98cf2ee625/content.mp4/playlist.m3u8") + Avalon::StreamMapper.streaming_server = :generic + expect(video_derivative.streaming_url(true)).to eq("#{http_base}/c5e0f8b8-3f69-40de-9524-604f03b5f867/8c871d4b-a9a6-4841-8e2a-dd98cf2ee625/content.mp4.m3u8") + end + + it "HTTP audio" do + Avalon::StreamMapper.streaming_server = :wowza + expect(audio_derivative.streaming_url(true)).to eq("#{http_base}/mp4:c5e0f8b8-3f69-40de-9524-604f03b5f867/8c871d4b-a9a6-4841-8e2a-dd98cf2ee625/content.mp4/playlist.m3u8") + Avalon::StreamMapper.streaming_server = :generic + expect(audio_derivative.streaming_url(true)).to eq("#{http_base}/c5e0f8b8-3f69-40de-9524-604f03b5f867/8c871d4b-a9a6-4841-8e2a-dd98cf2ee625/content.mp4.m3u8") + end + end end describe "#download_path" do diff --git a/spec/models/iiif_canvas_presenter_spec.rb b/spec/models/iiif_canvas_presenter_spec.rb index f5886fb799..7a6318a6b5 100644 --- a/spec/models/iiif_canvas_presenter_spec.rb +++ b/spec/models/iiif_canvas_presenter_spec.rb @@ -95,7 +95,7 @@ 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' ) } + let(:derivative) { FactoryBot.build(:derivative, hls_url: mp3_url, managed: false, mime_type: 'audio/mpeg' ) } it 'has format' do expect(subject.format).to eq 'audio/mpeg' @@ -123,7 +123,7 @@ 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' ) } + let(:derivative) { FactoryBot.build(:derivative, hls_url: mp4_url, managed: false, mime_type: 'video/mp4' ) } it 'has format' do expect(subject.format).to eq 'video/mp4' diff --git a/spec/models/iiif_playlist_canvas_presenter_spec.rb b/spec/models/iiif_playlist_canvas_presenter_spec.rb index fdece7af02..737843c23e 100644 --- a/spec/models/iiif_playlist_canvas_presenter_spec.rb +++ b/spec/models/iiif_playlist_canvas_presenter_spec.rb @@ -97,7 +97,7 @@ 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' ) } + let(:derivative) { FactoryBot.build(:derivative, hls_url: mp3_url, managed: false, mime_type: 'audio/mpeg' ) } it 'has format' do expect(subject.format).to eq 'audio/mpeg' @@ -129,7 +129,7 @@ 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' ) } + let(:derivative) { FactoryBot.build(:derivative, hls_url: mp4_url, managed: false, mime_type: 'video/mp4' ) } it 'has format' do expect(subject.format).to eq 'video/mp4'