jam-cloud/ruby/lib/jam_ruby/models/mix.rb

133 lines
3.7 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.ogg_url = construct_filename(mix.created_at, recording.id, mix.id, type='ogg')
mix.mp3_url = construct_filename(mix.created_at, recording.id, mix.id, type='mp3')
if mix.save
mix.enqueue
end
mix
end
def enqueue
begin
Resque.enqueue(AudioMixer, self.id, self.sign_put(3600 * 24, 'ogg'), self.sign_put(3600 * 24, 'mp3'))
rescue
# implies redis is down. we don't update started_at
false
end
# avoid db validations
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(ogg_length, ogg_md5, mp3_length, mp3_md5)
self.completed_at = Time.now
self.ogg_length = ogg_length
self.ogg_md5 = ogg_md5
self.mp3_length = mp3_length
self.mp3_md5 = mp3_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.recording.id
manifest
end
def s3_url(type='ogg')
if type == 'ogg'
s3_manager.s3_url(ogg_url)
else
s3_manager.s3_url(mp3_url)
end
end
def is_completed
completed
end
def sign_url(expiration_time = 120, type='ogg')
# expire link in 1 minute--the expectation is that a client is immediately following this link
if type == 'ogg'
s3_manager.sign_url(self.ogg_url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false})
else
s3_manager.sign_url(self.mp3_url, {:expires => expiration_time, :response_content_type => 'audio/mp3', :secure => false})
end
end
def sign_put(expiration_time = 3600 * 24, type='ogg')
if type == 'ogg'
s3_manager.sign_url(self.ogg_url, {:expires => expiration_time, :content_type => 'audio/ogg', :secure => false}, :put)
else
s3_manager.sign_url(self.mp3_url, {:expires => expiration_time, :content_type => 'audio/mp3', :secure => false}, :put)
end
end
private
def delete_s3_files
s3_manager.delete(filename(type='ogg'))
s3_manager.delete(filename(type='mp3'))
end
def filename(type='ogg')
# construct a path for s3
Mix.construct_filename(self.created_at, self.recording.id, self.id, type)
end
def self.construct_filename(created_at, recording_id, id, type='ogg')
raise "unknown ID" unless id
"recordings/#{created_at.strftime('%m-%d-%Y')}/#{recording_id}/mix-#{id}.#{type}"
end
end
end