120 lines
3.0 KiB
Ruby
120 lines
3.0 KiB
Ruby
module JamRuby
|
|
class Mix < ActiveRecord::Base
|
|
include S3ManagerMixin
|
|
|
|
MAX_MIX_TIME = 7200 # 2 hours
|
|
|
|
before_destroy :delete_s3_files
|
|
|
|
self.primary_key = 'id'
|
|
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :mixes
|
|
|
|
|
|
|
|
def self.schedule(recording)
|
|
raise if recording.nil?
|
|
|
|
mix = Mix.new
|
|
mix.recording = recording
|
|
mix.save
|
|
mix.url = construct_filename(mix.created_at, recording.id, mix.id)
|
|
if mix.save
|
|
mix.enqueue
|
|
end
|
|
|
|
mix
|
|
end
|
|
|
|
def enqueue
|
|
begin
|
|
Resque.enqueue(AudioMixer, self.id, self.sign_put)
|
|
rescue
|
|
# implies redis is down. we don't update started_at
|
|
false
|
|
end
|
|
|
|
Mix.where(:id => self.id).update_all(:started_at => Time.now)
|
|
|
|
true
|
|
end
|
|
|
|
def can_download?(some_user)
|
|
!ClaimedRecording.find_by_user_id_and_recording_id(some_user.id, recording_id).nil?
|
|
end
|
|
|
|
|
|
def errored(reason, detail)
|
|
self.error_reason = reason
|
|
self.error_detail = detail
|
|
self.error_count = self.error_count + 1
|
|
save
|
|
end
|
|
|
|
def finish(length, md5)
|
|
self.completed_at = Time.now
|
|
self.length = length
|
|
self.md5 = md5
|
|
self.completed = true
|
|
if save
|
|
Notification.send_recording_master_mix_complete(recording)
|
|
end
|
|
end
|
|
|
|
# valid for 1 day; because the s3 urls eventually expire
|
|
def manifest
|
|
one_day = 60 * 60 * 24
|
|
|
|
manifest = { "files" => [], "timeline" => [] }
|
|
mix_params = []
|
|
recording.recorded_tracks.each do |recorded_track|
|
|
manifest["files"] << { "filename" => recorded_track.sign_url(one_day), "codec" => "vorbis", "offset" => 0 }
|
|
mix_params << { "level" => 100, "balance" => 0 }
|
|
end
|
|
|
|
manifest["timeline"] << { "timestamp" => 0, "mix" => mix_params }
|
|
manifest["output"] = { "codec" => "vorbis" }
|
|
manifest["recording_id"] = self.id
|
|
manifest
|
|
end
|
|
|
|
def s3_url
|
|
s3_manager.s3_url(url)
|
|
end
|
|
|
|
def is_completed
|
|
completed
|
|
end
|
|
|
|
def sign_url(expiration_time = 120)
|
|
# expire link in 1 minute--the expectation is that a client is immediately following this link
|
|
s3_manager.sign_url(self.url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false})
|
|
end
|
|
|
|
def sign_put(expiration_time = 3600 * 24)
|
|
s3_manager.sign_url(self.url, {:expires => expiration_time, :content_type => 'audio/ogg', :secure => false}, :put)
|
|
end
|
|
|
|
def self.queue_jobs_needing_retry
|
|
Mix.find_each(:conditions => 'should_retry = TRUE or started_at is NULL', :batch_size => 100) do |mix|
|
|
mix.enqueue
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def delete_s3_files
|
|
s3_manager.delete(filename)
|
|
end
|
|
|
|
def filename
|
|
# construct a path for s3
|
|
Mix.construct_filename(self.created_at, self.recording.id, self.id)
|
|
end
|
|
|
|
def self.construct_filename(created_at, recording_id, id)
|
|
raise "unknown ID" unless id
|
|
"recordings/#{created_at.strftime('%m-%d-%Y')}/#{recording_id}/mix-#{id}.ogg"
|
|
end
|
|
end
|
|
end
|