diff --git a/db/manifest b/db/manifest
index 074c9df06..030c86619 100755
--- a/db/manifest
+++ b/db/manifest
@@ -285,4 +285,5 @@ musician_search.sql
signup_hints.sql
packaging_notices.sql
first_played_jamtrack_at.sql
-payment_history.sql
\ No newline at end of file
+payment_history.sql
+jam_track_right_private_key.sql
diff --git a/db/up/jam_track_right_private_key.sql b/db/up/jam_track_right_private_key.sql
new file mode 100644
index 000000000..a0e9b9d01
--- /dev/null
+++ b/db/up/jam_track_right_private_key.sql
@@ -0,0 +1,11 @@
+ALTER TABLE jam_track_rights ADD COLUMN private_key_44 VARCHAR;
+ALTER TABLE jam_track_rights ADD COLUMN private_key_48 VARCHAR;
+ALTER TABLE jam_track_rights ADD COLUMN signed_48 BOOLEAN NOT NULL DEFAULT FALSE;
+ALTER TABLE jam_track_rights ADD COLUMN signed_44 BOOLEAN NOT NULL DEFAULT FALSE;
+ALTER TABLE jam_track_rights DROP COLUMN private_key;
+ALTER TABLE jam_track_rights DROP COLUMN signed;
+ALTER TABLE jam_track_rights ADD COLUMN signing_started_at_44 TIMESTAMP;
+ALTER TABLE jam_track_rights ADD COLUMN signing_started_at_48 TIMESTAMP;
+ALTER TABLE jam_track_rights DROP COLUMN signing_started_at;
+
+
diff --git a/ruby/lib/jam_ruby/app/uploaders/jam_track_right_uploader.rb b/ruby/lib/jam_ruby/app/uploaders/jam_track_right_uploader.rb
index e33494063..520908b7b 100644
--- a/ruby/lib/jam_ruby/app/uploaders/jam_track_right_uploader.rb
+++ b/ruby/lib/jam_ruby/app/uploaders/jam_track_right_uploader.rb
@@ -23,6 +23,6 @@ class JamTrackRightUploader < CarrierWave::Uploader::Base
end
def filename
- "#{model.store_dir}/#{model.filename}" if model.id
+ "#{model.store_dir}/#{model.filename(mounted_as)}" if model.id
end
end
diff --git a/ruby/lib/jam_ruby/jam_tracks_manager.rb b/ruby/lib/jam_ruby/jam_tracks_manager.rb
index 36a19c960..644f9ccc3 100644
--- a/ruby/lib/jam_ruby/jam_tracks_manager.rb
+++ b/ruby/lib/jam_ruby/jam_tracks_manager.rb
@@ -82,10 +82,18 @@ module JamRuby
else
jam_track_right.url_44.store!(File.open(output_jkz, "rb"))
end
-
- jam_track_right.signed=true
- jam_track_right.downloaded_since_sign=false
- jam_track_right.private_key=File.read("#{tmp_dir}/skey.pem")
+
+ if sample_rate == 48
+ jam_track_right.signed_48 = true
+ jam_track_right.private_key_48 = File.read("#{tmp_dir}/skey.pem")
+ else
+ jam_track_right.signed_44 = true
+ jam_track_right.private_key_44 = File.read("#{tmp_dir}/skey.pem")
+ end
+
+ jam_track_right.signing_queued_at = nil # if left set, throws off signing_state on subsequent signing attempts
+ jam_track_right.downloaded_since_sign = false
+
jam_track_right.save!
end
end # mktmpdir
diff --git a/ruby/lib/jam_ruby/models/jam_track_right.rb b/ruby/lib/jam_ruby/models/jam_track_right.rb
index a5e127d78..b60bf9755 100644
--- a/ruby/lib/jam_ruby/models/jam_track_right.rb
+++ b/ruby/lib/jam_ruby/models/jam_track_right.rb
@@ -29,7 +29,7 @@ module JamRuby
# try to catch major transitions:
# if just queue time changes, start time changes, or signed time changes, send out a notice
- if signing_queued_at_was != signing_queued_at || signing_started_at_was != signing_started_at || last_signed_at_was != last_signed_at || current_packaging_step != current_packaging_step_was || packaging_steps != packaging_steps_was
+ if signing_queued_at_was != signing_queued_at || signing_started_at_48_was != signing_started_at_48 || signing_started_at_44_was != signing_started_at_44 || last_signed_at_was != last_signed_at || current_packaging_step != current_packaging_step_was || packaging_steps != packaging_steps_was
SubscriptionMessage.jam_track_signing_job_change(self)
end
end
@@ -39,8 +39,8 @@ module JamRuby
end
# create name of the file
- def filename
- "#{jam_track.name}.jkz"
+ def filename(bitrate)
+ "#{jam_track.name}-#{bitrate == :url_48 ? '48' : '44'}.jkz"
end
def verify_download_count
@@ -71,11 +71,12 @@ module JamRuby
if bitrate==48
self.length_48 = length
self.md5_48 = md5
+ self.signed_48 = true
else
self.length_44 = length
self.md5_44 = md5
+ self.signed_44 = true
end
- self.signed = true
self.error_count = 0
self.error_reason = nil
self.error_detail = nil
@@ -104,7 +105,7 @@ module JamRuby
def enqueue(sample_rate=48)
begin
- JamTrackRight.where(:id => self.id).update_all(:signing_queued_at => Time.now, :signing_started_at => nil, :last_signed_at => nil)
+ JamTrackRight.where(:id => self.id).update_all(:signing_queued_at => Time.now, :signing_started_at_44 => nil, :signing_started_at_48 => nil, :last_signed_at => nil)
Resque.enqueue(JamTracksBuilder, self.id, sample_rate)
true
rescue Exception => e
@@ -116,7 +117,7 @@ module JamRuby
# if the job is already signed, just queued up for signing, or currently signing, then don't enqueue... otherwise fire it off
def enqueue_if_needed(sample_rate=48)
- state = signing_state
+ state = signing_state(sample_rate)
if state == 'SIGNED' || state == 'SIGNING' || state == 'QUEUED'
false
else
@@ -129,9 +130,9 @@ module JamRuby
# @return true if signed && file exists for the sample_rate specifed:
def ready?(sample_rate=48)
if sample_rate==48
- self.signed && self.url_48.present? && self.url_48.file.exists?
+ self.signed_48 && self.url_48.present? && self.url_48.file.exists?
else
- self.signed && self.url_44.present? && self.url_44.file.exists?
+ self.signed_44 && self.url_44.present? && self.url_44.file.exists?
end
end
@@ -143,8 +144,20 @@ module JamRuby
# QUEUED_TIMEOUT - the package signing job (JamTrackBuilder) was queued, but never executed
# QUEUED - the package is queued to sign
# QUIET - the jam_track_right exists, but no job has been kicked off; a job needs to be enqueued
- def signing_state
+ def signing_state(sample_rate = nil)
state = nil
+
+ # if the caller did not specified sample rate, we will determine what signing state to check by looking at the most recent signing attempt
+ if sample_rate.nil?
+ # determine what package is being signed by checking the most recent signing_started at
+ time_48 = signing_started_at_48.to_i
+ time_44 = signing_started_at_44.to_i
+ sample_rate = time_48 > time_44 ? 48 : 44
+ end
+
+ signed = sample_rate == 48 ? signed_48 : signed_44
+ signing_started_at = sample_rate == 48 ? signing_started_at_48 : signing_started_at_44
+
if signed
state = 'SIGNED'
elsif signing_started_at
@@ -170,11 +183,16 @@ module JamRuby
end
state
end
+
+ def signed?(sample_rate)
+ sample_rate == 48 ? signed_48 : signed_44
+ end
+
def update_download_count(count=1)
self.download_count = self.download_count + count
self.last_downloaded_at = Time.now
- if self.signed
+ if self.signed_44 || self.signed_48
self.downloaded_since_sign = true
end
end
@@ -184,7 +202,7 @@ module JamRuby
return []
end
- JamTrack.select('jam_tracks.id, jam_track_rights.private_key AS private_key, jam_track_rights.id AS jam_track_right_id')
+ JamTrack.select('jam_tracks.id, jam_track_rights.private_key_44 AS private_key_44, jam_track_rights.private_key_48 AS private_key_48, jam_track_rights.id AS jam_track_right_id')
.joins("LEFT OUTER JOIN jam_track_rights ON jam_tracks.id = jam_track_rights.jam_track_id AND jam_track_rights.user_id = '#{user.id}'")
.where('jam_tracks.id IN (?)', jamtracks)
end
diff --git a/ruby/lib/jam_ruby/resque/jam_tracks_builder.rb b/ruby/lib/jam_ruby/resque/jam_tracks_builder.rb
index 329a52b4d..71018e1bd 100644
--- a/ruby/lib/jam_ruby/resque/jam_tracks_builder.rb
+++ b/ruby/lib/jam_ruby/resque/jam_tracks_builder.rb
@@ -29,7 +29,7 @@ module JamRuby
@jam_track_right = JamTrackRight.find(jam_track_right_id)
# bailout check
- if @jam_track_right.signed
+ if @jam_track_right.signed?(bitrate)
log.debug("package is already signed. bailing")
return
end
@@ -39,12 +39,13 @@ module JamRuby
# track that it's started ( and avoid db validations )
signing_started_at = Time.now
+ signing_started_model_symbol = bitrate == 48 ? :signing_started_at_48 : :signing_started_at_44
last_step_at = Time.now
- JamTrackRight.where(:id => @jam_track_right.id).update_all(:signing_started_at => signing_started_at, :should_retry => false, packaging_steps: total_steps, current_packaging_step: 0, last_step_at: last_step_at)
- # because we are skiping after_save, we have to keep the model current for the notification. A bit ugly...
+ JamTrackRight.where(:id => @jam_track_right.id).update_all(signing_started_model_symbol => signing_started_at, :should_retry => false, packaging_steps: total_steps, current_packaging_step: 0, last_step_at: last_step_at)
+ # because we are skipping 'after_save', we have to keep the model current for the notification. A bit ugly...
@jam_track_right.current_packaging_step = 0
@jam_track_right.packaging_steps = total_steps
- @jam_track_right.signing_started_at = signing_started_at
+ @jam_track_right[signing_started_model_symbol] = signing_started_at
@jam_track_right.should_retry = false
@jam_track_right.last_step_at = Time.now
SubscriptionMessage.jam_track_signing_job_change(@jam_track_right)
diff --git a/ruby/spec/jam_ruby/models/jam_track_right_spec.rb b/ruby/spec/jam_ruby/models/jam_track_right_spec.rb
index 0977703ff..90953fc3b 100644
--- a/ruby/spec/jam_ruby/models/jam_track_right_spec.rb
+++ b/ruby/spec/jam_ruby/models/jam_track_right_spec.rb
@@ -76,7 +76,7 @@ describe JamTrackRight do
JamRuby::JamTracksManager.save_jam_track_jkz(user, jam_track)
#}.to_not raise_error(ArgumentError)
jam_track_right.reload
- jam_track_right[:url_48].should == jam_track_right.store_dir + '/' + jam_track_right.filename
+ jam_track_right[:url_48].should == jam_track_right.store_dir + '/' + jam_track_right.filename(:url_48)
# verify it's on S3
url = jam_track_right[:url_48]
@@ -109,11 +109,12 @@ describe JamTrackRight do
end
it "valid track with rights to it by querying user" do
- jam_track_right = FactoryGirl.create(:jam_track_right, private_key: 'keyabc')
+ jam_track_right = FactoryGirl.create(:jam_track_right, private_key_44: 'keyabc')
keys = JamTrackRight.list_keys(jam_track_right.user, [jam_track_right.jam_track.id])
keys.should have(1).items
keys[0].id.should == jam_track_right.jam_track.id
- keys[0]['private_key'].should eq('keyabc')
+ keys[0]['private_key_44'].should eq('keyabc')
+ keys[0]['private_key_48'].should be_nil
end
end
@@ -124,7 +125,7 @@ describe JamTrackRight do
end
it "signed" do
- right = FactoryGirl.create(:jam_track_right, signed: true)
+ right = FactoryGirl.create(:jam_track_right, signed_44: true, signing_started_at_44: Time.now)
right.signing_state.should eq('SIGNED')
end
@@ -134,23 +135,23 @@ describe JamTrackRight do
end
it "signing" do
- right = FactoryGirl.create(:jam_track_right, signing_started_at: Time.now, packaging_steps: 3, current_packaging_step:0, last_step_at:Time.now)
- right.signing_state.should eq('SIGNING')
+ right = FactoryGirl.create(:jam_track_right, signing_started_at_44: Time.now, packaging_steps: 3, current_packaging_step:0, last_step_at:Time.now)
+ right.signing_state(44).should eq('SIGNING')
end
it "signing timeout" do
- right = FactoryGirl.create(:jam_track_right, signing_started_at: Time.now - 100, packaging_steps: 3, current_packaging_step:0, last_step_at:Time.now)
- right.signing_state.should eq('SIGNING_TIMEOUT')
+ right = FactoryGirl.create(:jam_track_right, signing_started_at_48: Time.now - 100, packaging_steps: 3, current_packaging_step:0, last_step_at:Time.now)
+ right.signing_state(48).should eq('SIGNING_TIMEOUT')
end
it "queued" do
right = FactoryGirl.create(:jam_track_right, signing_queued_at: Time.now)
- right.signing_state.should eq('QUEUED')
+ right.signing_state(44).should eq('QUEUED')
end
it "signing timeout" do
right = FactoryGirl.create(:jam_track_right, signing_queued_at: Time.now - (APP_CONFIG.signing_job_queue_max_time + 1))
- right.signing_state.should eq('QUEUED_TIMEOUT')
+ right.signing_state(44).should eq('QUEUED_TIMEOUT')
end
end
diff --git a/ruby/spec/jam_ruby/resque/jam_tracks_builder_spec.rb b/ruby/spec/jam_ruby/resque/jam_tracks_builder_spec.rb
index 7ead35e3a..982c56f87 100644
--- a/ruby/spec/jam_ruby/resque/jam_tracks_builder_spec.rb
+++ b/ruby/spec/jam_ruby/resque/jam_tracks_builder_spec.rb
@@ -44,8 +44,13 @@ describe JamTracksBuilder do
jam_track_right[:url_44].should be_nil
JamTracksBuilder.perform(jam_track_right.id, 48)
jam_track_right.reload
- jam_track_right[:url_48].should == jam_track_right.store_dir + '/' + jam_track_right.filename
+ jam_track_right[:url_48].should == jam_track_right.store_dir + '/' + jam_track_right.filename(:url_48)
jam_track_track[:url_44].should be_nil
+
+ jam_track_right.signed_48.should be_true
+ jam_track_right.signing_started_at_48.should_not be_nil
+ jam_track_right.signed_44.should be_false
+ jam_track_right.signing_started_at_44.should be_nil
end
describe "with bitrate 44" do
@@ -76,9 +81,14 @@ describe JamTracksBuilder do
jam_track_right[:url_48].should be_nil
JamTracksBuilder.perform(jam_track_right.id, 44)
jam_track_right.reload
- jam_track_right[:url_44].should == jam_track_right.store_dir + '/' + jam_track_right.filename
+ jam_track_right[:url_44].should == jam_track_right.store_dir + '/' + jam_track_right.filename(:url_44)
jam_track_right.url_44.should_not be_nil
jam_track_track[:url_48].should be_nil
+
+ jam_track_right.signed_44.should be_true
+ jam_track_right.signing_started_at_44.should_not be_nil
+ jam_track_right.signed_48.should be_false
+ jam_track_right.signing_started_at_48.should be_nil
end
end
end
\ No newline at end of file
diff --git a/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb b/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb
index 1c900bc52..e8a244b14 100644
--- a/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb
+++ b/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb
@@ -23,14 +23,14 @@ describe JamTracksCleaner do
it "should clean" do
jam_track_right = JamTrackRight.create(:user=>@user, :jam_track=>@jam_track)
- jam_track_right.signed=true
+ jam_track_right.signed_48=true
jam_track_right
jam_track_right.url_48.store!(File.open(RIGHT_NAME))
jam_track_right.downloaded_since_sign=true
jam_track_right.save!
- jam_track_right[:url_48].should == jam_track_right.store_dir + '/' + jam_track_right.filename
+ jam_track_right[:url_48].should == jam_track_right.store_dir + '/' + jam_track_right.filename(:url_48)
jam_track_right.reload
# Should exist after uploading:
diff --git a/web/app/assets/javascripts/accounts.js b/web/app/assets/javascripts/accounts.js
index b392633e2..8c5ccbabe 100644
--- a/web/app/assets/javascripts/accounts.js
+++ b/web/app/assets/javascripts/accounts.js
@@ -8,7 +8,7 @@
var rest = context.JK.Rest();
var userId;
var user = {};
-
+ var gearUtils = context.JK.GearUtilsInstance;
function beforeShow(data) {
console.log("beforeShow", data)
@@ -90,7 +90,11 @@
var delimiter = ", ";
if (profileMap && profileMap.length > 0) {
$.each(profileMap, function(index, val) {
- profiles += val.name + delimiter;
+ var inputName = val.name;
+ if (inputName == gearUtils.JAMKAZAM_VIRTUAL_INPUT) {
+ inputName = gearUtils.SYSTEM_DEFAULT_PLAYBACK_ONLY;
+ }
+ profiles += inputName + delimiter;
});
return profiles.substring(0, profiles.length - delimiter.length);
diff --git a/web/app/assets/javascripts/backend_alerts.js b/web/app/assets/javascripts/backend_alerts.js
index d1c9628e1..b2ef4b7cf 100644
--- a/web/app/assets/javascripts/backend_alerts.js
+++ b/web/app/assets/javascripts/backend_alerts.js
@@ -69,7 +69,10 @@
logger.debug("alert callback", type, text);
- var alertData = ALERT_TYPES[type];
+ var alertData = $.extend({}, ALERT_TYPES[type]);
+
+ alertData.text = text;
+
if(alertData) {
$document.triggerHandler(alertData.name, alertData);
}
diff --git a/web/app/assets/javascripts/dialog/openJamTrackDialog.js b/web/app/assets/javascripts/dialog/openJamTrackDialog.js
index 9f0fc5ce6..8843838f5 100644
--- a/web/app/assets/javascripts/dialog/openJamTrackDialog.js
+++ b/web/app/assets/javascripts/dialog/openJamTrackDialog.js
@@ -13,6 +13,8 @@
var $templateOpenJamTrackRow = null;
var $downloadedTrackHelp = null;
var $whatAreJamTracks = null;
+ var sampleRate = null;
+ var sampleRateForFilename = null;
function emptyList() {
@@ -24,18 +26,25 @@
}
function beforeShow() {
+
+ }
+
+ function afterShow() {
$dialog.data('result', null)
emptyList();
resetPagination();
showing = true;
+ sampleRate = context.jamClient.GetSampleRate()
+ sampleRateForFilename = sampleRate == 48 ? '48' : '44';
+
getPurchasedJamTracks(0)
.done(function(data, textStatus, jqXHR) {
// initialize pagination
var $paginator = context.JK.Paginator.create(parseInt(jqXHR.getResponseHeader('total-entries')), perPage, 0, onPageSelected)
$paginatorHolder.append($paginator);
});
- }
+ }
function afterHide() {
showing = false;
}
@@ -58,7 +67,7 @@
options.jamTrackId = jamTrack.id;
options.name = jamTrack.name;
options.artist = jamTrack.original_artist;
- var detail = context.jamClient.JamTrackGetTrackDetail(jamTrack.id) || {}
+ var detail = context.jamClient.JamTrackGetTrackDetail(jamTrack.id + '-' + sampleRateForFilename) || {}
options.downloaded = detail.key_state == 'ready' ? 'Yes' : 'No'
var $tr = $(context._.template($templateOpenJamTrackRow.html(), options, { variable: 'data' }));
@@ -99,6 +108,7 @@
function initialize(){
var dialogBindings = {
'beforeShow' : beforeShow,
+ 'afterShow' : afterShow,
'afterHide': afterHide
};
diff --git a/web/app/assets/javascripts/dialog/recordingFinishedDialog.js b/web/app/assets/javascripts/dialog/recordingFinishedDialog.js
index 866e460a1..6152927a2 100644
--- a/web/app/assets/javascripts/dialog/recordingFinishedDialog.js
+++ b/web/app/assets/javascripts/dialog/recordingFinishedDialog.js
@@ -108,6 +108,10 @@
context.jamClient.ClosePreviewRecording();
}
+ function onCancel() {
+ return false;
+ }
+
function discardRecording(e) {
resetForm();
@@ -323,7 +327,8 @@
function initialize() {
var dialogBindings = {
'beforeShow': beforeShow,
- 'afterHide': afterHide
+ 'afterHide': afterHide,
+ 'onCancel': onCancel
};
app.bindDialog('recordingFinished', dialogBindings);
diff --git a/web/app/assets/javascripts/download_jamtrack.js.coffee b/web/app/assets/javascripts/download_jamtrack.js.coffee
index 0854d49db..800cdc276 100644
--- a/web/app/assets/javascripts/download_jamtrack.js.coffee
+++ b/web/app/assets/javascripts/download_jamtrack.js.coffee
@@ -205,6 +205,8 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
showInitial: () =>
@logger.debug("showing #{@state.name}")
+ @sampleRate = context.jamClient.GetSampleRate()
+ @sampleRateForFilename = if @sampleRate == 48 then '48' else '44'
@attempts = @attempts + 1
this.expectTransition()
context.JK.SubscriptionUtils.subscribe('jam_track_right', @jamTrack.jam_track_right_id).on(context.JK.EVENTS.SUBSCRIBE_NOTIFICATION, this.onJamTrackRightEvent)
@@ -350,17 +352,18 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
checkState: () =>
# check for the success state against the local state of the client... if it's playable, then we should be OK
- @trackDetail = context.jamClient.JamTrackGetTrackDetail (@jamTrack.id)
+ fqId = "#{@jamTrack.id}-#{@sampleRateForFilename}"
+ @trackDetail = context.jamClient.JamTrackGetTrackDetail (fqId)
- @logger.debug("DownloadJamTrack: JamTrackGetTrackDetail.key_state: " + @trackDetail.key_state)
+ @logger.debug("DownloadJamTrack: JamTrackGetTrackDetail(#{fqId}).key_state: " + @trackDetail.key_state, @trackDetail)
# first check if the version is not the same; if so, invalidate.
if @trackDetail.version?
if @jamTrack.version != @trackDetail.version
@logger.info("DownloadJamTrack: JamTrack on disk is different version (stored: #{@trackDetail.version}, server: #{@jamTrack.version}. Invalidating")
- context.jamClient.InvalidateJamTrack(@jamTrack.id)
- @trackDetail = context.jamClient.JamTrackGetTrackDetail (@jamTrack.id)
+ context.jamClient.InvalidateJamTrack("#{@jamTrack.id}-#{@sampleRateForFilename}")
+ @trackDetail = context.jamClient.JamTrackGetTrackDetail ("#{@jamTrack.id}-#{@sampleRateForFilename}")
if @trackDetail.version?
@logger.error("after invalidating package, the version is still wrong!")
@@ -447,9 +450,7 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
@attemptedEnqueue = true
@ajaxEnqueueAborted = false
- sampleRate = context.jamClient.GetSampleRate()
-
- @rest.enqueueJamTrack({id: @jamTrack.id, sample_rate: sampleRate})
+ @rest.enqueueJamTrack({id: @jamTrack.id, sample_rate: @sampleRate})
.done(this.processEnqueueJamTrack)
.fail(this.processEnqueueJamTrackFail)
diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js
index 98468defb..d2bd66a80 100644
--- a/web/app/assets/javascripts/fakeJamClient.js
+++ b/web/app/assets/javascripts/fakeJamClient.js
@@ -59,6 +59,10 @@
}
function FTUESetMusicProfileName() {
+ }
+
+ function FTUESetPreferredMixerSampleRate() {
+
}
function FTUESelectVideoCaptureDevice(device, settings) {
@@ -1040,6 +1044,7 @@
this.FTUEPageLeave = FTUEPageLeave;
this.FTUEGetMusicProfileName = FTUEGetMusicProfileName;
this.FTUESetMusicProfileName = FTUESetMusicProfileName;
+ this.FTUESetPreferredMixerSampleRate = FTUESetPreferredMixerSampleRate;
this.FTUEGetInputLatency = FTUEGetInputLatency;
this.FTUEGetInputVolume = FTUEGetInputVolume;
this.FTUEGetMusicInputs = FTUEGetMusicInputs;
diff --git a/web/app/assets/javascripts/playbackControls.js b/web/app/assets/javascripts/playbackControls.js
index 2aeaf0632..1634150c1 100644
--- a/web/app/assets/javascripts/playbackControls.js
+++ b/web/app/assets/javascripts/playbackControls.js
@@ -53,6 +53,7 @@
var playbackMode = PlaybackMode.EveryWhere;
var monitorPlaybackTimeout = null;
var playbackMonitorMode = PLAYBACK_MONITOR_MODE.MEDIA_FILE;
+ var monitoring = false;
function init() {
updateSliderPosition(0);
@@ -210,6 +211,9 @@
}
}
function monitorRecordingPlayback() {
+ if(!monitoring) {
+ return;
+ }
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
var positionMs = context.jamClient.SessionCurrrentJamTrackPlayPosMs();
var duration = context.jamClient.SessionGetJamTracksPlayDurationMs();
@@ -262,7 +266,7 @@
}
// at the end of the play, the duration sets to 0, as does currentTime. but isPlaying does not reset to
- //logger.debug("currentTimeMs, durationTimeMs, mode", currentTimeMs, durationTimeMs, playbackMonitorMode);
+ logger.debug("currentTimeMs, durationTimeMs, mode", currentTimeMs, durationTimeMs, playbackMonitorMode);
if(currentTimeMs == 0 && seenActivity) {
if(playbackPlaying) {
isPlaying = false;
@@ -355,7 +359,7 @@
}
function startMonitor(_playbackMonitorMode) {
-
+ monitoring = true;
// resets everything to zero
init();
@@ -373,6 +377,7 @@
}
function stopMonitor() {
+ monitoring = false;
logger.debug("playbackControl.stopMonitor")
if(monitorPlaybackTimeout!= null) {
clearTimeout(monitorPlaybackTimeout);
diff --git a/web/app/assets/javascripts/scheduled_session.js.erb b/web/app/assets/javascripts/scheduled_session.js.erb
index 707d63554..cfaf2bd4e 100644
--- a/web/app/assets/javascripts/scheduled_session.js.erb
+++ b/web/app/assets/javascripts/scheduled_session.js.erb
@@ -932,9 +932,9 @@
}
if(optionRequiresMultiplayerProfile()) {
- if(context.JK.guardAgainstSinglePlayerProfile(app).canPlay == false) {
- return false;
- }
+ // if(context.JK.guardAgainstSinglePlayerProfile(app).canPlay == false) {
+ // return false;
+ //}
}
var valid = beforeMoveStep();
diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js
index 58cfb6f93..2c665aa53 100644
--- a/web/app/assets/javascripts/session.js
+++ b/web/app/assets/javascripts/session.js
@@ -94,6 +94,7 @@
var claimedRecording = null;
var backing_track_path = null;
var jamTrack = null;
+ var musicianAccessOnJoin; // was this a private or public session when the user tried to joined?
var metronomeMixer = null;
var playbackControls = null;
@@ -211,16 +212,7 @@
rest.getSessionHistory(data.id)
.done(function(musicSession) {
- var singlePlayerCheckOK = true;
- // to know whether we are allowed to be in this session, we have to check if we are the creator when checking against single player functionality
- if(musicSession.user_id != context.JK.currentUserId) {
- var canPlay = context.JK.guardAgainstSinglePlayerProfile(app, function () {
- promptLeave = false;
- });
-
- singlePlayerCheckOK = canPlay.canPlay;
- }
- if(singlePlayerCheckOK) {
+ musicianAccessOnJoin = musicSession.musician_access;;
var shouldVerifyNetwork = musicSession.musician_access;
gearUtils.guardAgainstInvalidConfiguration(app, shouldVerifyNetwork)
@@ -270,17 +262,6 @@
});
})
})
- }
- else {
- if(canPlay.dialog) {
- canPlay.dialog.one(EVENTS.DIALOG_CLOSED, function(e, data) {
- if(data.canceled) {
- promptLeave = false;
- window.location = '/client#/home'
- }
- })
- }
- }
})
.fail(function() {
@@ -308,188 +289,209 @@
function afterCurrentUserLoaded() {
- var sessionModel = context.JK.CurrentSessionModel;
- $(sessionModel.recordingModel)
+ // now check if the user can play in a session with others
+ var deferred = new $.Deferred();
+ if(musicianAccessOnJoin) {
+ deferred = context.JK.guardAgainstSinglePlayerProfile(app, function () {
+ promptLeave = false;
+ });
+ }
+ else {
+ deferred.resolve();
+ }
+ deferred.fail(function(result) {
+ if(!result.controlled_location) {
+ window.location="/client#/home"
+ }
+ })
+ .done(function() {logger.debug("user has passed all session guards")
+ promptLeave = true;
+ var sessionModel = context.JK.CurrentSessionModel;
+
+ $(sessionModel.recordingModel)
.on('startingRecording', function(e, data) {
- displayStartingRecording();
- lockControlsforJamTrackRecording();
+ displayStartingRecording();
+ lockControlsforJamTrackRecording();
})
.on('startedRecording', function(e, data) {
- if(data.reason) {
- var reason = data.reason;
- var detail = data.detail;
-
- var title = "Could Not Start Recording";
-
- if(data.reason == 'client-no-response') {
- notifyWithUserInfo(title, 'did not respond to the start signal.', detail);
- }
- else if(data.reason == 'empty-recording-id') {
- app.notifyAlert(title, "No recording ID specified.");
- }
- else if(data.reason == 'missing-client') {
- notifyWithUserInfo(title, 'could not be signalled to start recording.', detail);
- }
- else if(data.reason == 'already-recording') {
- app.notifyAlert(title, 'Already recording. If this appears incorrect, try restarting JamKazam.');
- }
- else if(data.reason == 'recording-engine-unspecified') {
- notifyWithUserInfo(title, 'had a problem writing recording data to disk.', detail);
- }
- else if(data.reason == 'recording-engine-create-directory') {
- notifyWithUserInfo(title, 'had a problem creating a recording folder.', detail);
- }
- else if(data.reason == 'recording-engine-create-file') {
- notifyWithUserInfo(title, 'had a problem creating a recording file.', detail);
- }
- else if(data.reason == 'recording-engine-sample-rate') {
- notifyWithUserInfo(title, 'had a problem recording at the specified sample rate.', detail);
- }
- else if(data.reason == 'rest') {
- var jqXHR = detail[0];
- app.notifyServerError(jqXHR);
- }
- else {
- notifyWithUserInfo(title, 'Error Reason: ' + reason);
- }
- displayDoneRecording();
- }
- else
- {
- displayStartedRecording();
- displayWhoCreated(data.clientId);
- lockControlsforJamTrackRecording();
- }
- })
- .on('stoppingRecording', function(e, data) {
- displayStoppingRecording(data);
- unlockControlsforJamTrackRecording();
- })
- .on('stoppedRecording', function(e, data) {
-
- unlockControlsforJamTrackRecording();
- if(sessionModel.selfOpenedJamTracks()) {
-
- var timeline = context.jamClient.GetJamTrackTimeline();
-
- rest.addRecordingTimeline(data.recordingId, timeline)
- .fail(function(){
- app.notify(
- { title: "Unable to Add JamTrack Volume Data",
- text: "The volume of the JamTrack will not be correct in the recorded mix." },
- null,
- true);
- })
- }
-
- if(data.reason) {
- logger.warn("Recording Discarded: ", data);
- var reason = data.reason;
- var detail = data.detail;
-
- var title = "Recording Discarded";
-
- if(data.reason == 'client-no-response') {
- notifyWithUserInfo(title, 'did not respond to the stop signal.', detail);
- }
- else if(data.reason == 'missing-client') {
- notifyWithUserInfo(title, 'could not be signalled to stop recording.', detail);
- }
- else if(data.reason == 'empty-recording-id') {
- app.notifyAlert(title, "No recording ID specified.");
- }
- else if(data.reason == 'wrong-recording-id') {
- app.notifyAlert(title, "Wrong recording ID specified.");
- }
- else if(data.reason == 'not-recording') {
- app.notifyAlert(title, "Not currently recording.");
- }
- else if(data.reason == 'already-stopping') {
- app.notifyAlert(title, "Already stopping the current recording.");
- }
- else if(data.reason == 'start-before-stop') {
- notifyWithUserInfo(title, 'asked that we start a new recording; cancelling the current one.', detail);
- }
- else {
- app.notifyAlert(title, "Error reason: " + reason);
- }
-
- displayDoneRecording();
- }
- else {
- displayDoneRecording();
- promptUserToSave(data.recordingId, timeline);
- }
-
- })
- .on('abortedRecording', function(e, data) {
+ if(data.reason) {
var reason = data.reason;
var detail = data.detail;
- var title = "Recording Cancelled";
+ var title = "Could Not Start Recording";
if(data.reason == 'client-no-response') {
- notifyWithUserInfo(title, 'did not respond to the start signal.', detail);
+ notifyWithUserInfo(title, 'did not respond to the start signal.', detail);
+ }
+ else if(data.reason == 'empty-recording-id') {
+ app.notifyAlert(title, "No recording ID specified.");
}
else if(data.reason == 'missing-client') {
- notifyWithUserInfo(title, 'could not be signalled to start recording.', detail);
+ notifyWithUserInfo(title, 'could not be signalled to start recording.', detail);
}
- else if(data.reason == 'populate-recording-info') {
- notifyWithUserInfo(title, 'could not synchronize with the server.', detail);
+ else if(data.reason == 'already-recording') {
+ app.notifyAlert(title, 'Already recording. If this appears incorrect, try restarting JamKazam.');
}
else if(data.reason == 'recording-engine-unspecified') {
- notifyWithUserInfo(title, 'had a problem writing recording data to disk.', detail);
+ notifyWithUserInfo(title, 'had a problem writing recording data to disk.', detail);
}
else if(data.reason == 'recording-engine-create-directory') {
- notifyWithUserInfo(title, 'had a problem creating a recording folder.', detail);
+ notifyWithUserInfo(title, 'had a problem creating a recording folder.', detail);
}
else if(data.reason == 'recording-engine-create-file') {
- notifyWithUserInfo(title, 'had a problem creating a recording file.', detail);
+ notifyWithUserInfo(title, 'had a problem creating a recording file.', detail);
}
else if(data.reason == 'recording-engine-sample-rate') {
- notifyWithUserInfo(title, 'had a problem recording at the specified sample rate.', detail);
+ notifyWithUserInfo(title, 'had a problem recording at the specified sample rate.', detail);
+ }
+ else if(data.reason == 'rest') {
+ var jqXHR = detail[0];
+ app.notifyServerError(jqXHR);
}
else {
- app.notifyAlert(title, "Error reason: " + reason);
+ notifyWithUserInfo(title, 'Error Reason: ' + reason);
+ }
+ displayDoneRecording();
+ }
+ else
+ {
+ displayStartedRecording();
+ displayWhoCreated(data.clientId);
+ lockControlsforJamTrackRecording();
+ }
+ })
+ .on('stoppingRecording', function(e, data) {
+ displayStoppingRecording(data);
+ unlockControlsforJamTrackRecording();
+ })
+ .on('stoppedRecording', function(e, data) {
+
+ unlockControlsforJamTrackRecording();
+ if(sessionModel.selfOpenedJamTracks()) {
+
+ var timeline = context.jamClient.GetJamTrackTimeline();
+
+ rest.addRecordingTimeline(data.recordingId, timeline)
+ .fail(function(){
+ app.notify(
+ { title: "Unable to Add JamTrack Volume Data",
+ text: "The volume of the JamTrack will not be correct in the recorded mix." },
+ null,
+ true);
+ })
+ }
+
+ if(data.reason) {
+ logger.warn("Recording Discarded: ", data);
+ var reason = data.reason;
+ var detail = data.detail;
+
+ var title = "Recording Discarded";
+
+ if(data.reason == 'client-no-response') {
+ notifyWithUserInfo(title, 'did not respond to the stop signal.', detail);
+ }
+ else if(data.reason == 'missing-client') {
+ notifyWithUserInfo(title, 'could not be signalled to stop recording.', detail);
+ }
+ else if(data.reason == 'empty-recording-id') {
+ app.notifyAlert(title, "No recording ID specified.");
+ }
+ else if(data.reason == 'wrong-recording-id') {
+ app.notifyAlert(title, "Wrong recording ID specified.");
+ }
+ else if(data.reason == 'not-recording') {
+ app.notifyAlert(title, "Not currently recording.");
+ }
+ else if(data.reason == 'already-stopping') {
+ app.notifyAlert(title, "Already stopping the current recording.");
+ }
+ else if(data.reason == 'start-before-stop') {
+ notifyWithUserInfo(title, 'asked that we start a new recording; cancelling the current one.', detail);
+ }
+ else {
+ app.notifyAlert(title, "Error reason: " + reason);
}
displayDoneRecording();
+ }
+ else {
+ displayDoneRecording();
+ promptUserToSave(data.recordingId, timeline);
+ }
+
+ })
+ .on('abortedRecording', function(e, data) {
+ var reason = data.reason;
+ var detail = data.detail;
+
+ var title = "Recording Cancelled";
+
+ if(data.reason == 'client-no-response') {
+ notifyWithUserInfo(title, 'did not respond to the start signal.', detail);
+ }
+ else if(data.reason == 'missing-client') {
+ notifyWithUserInfo(title, 'could not be signalled to start recording.', detail);
+ }
+ else if(data.reason == 'populate-recording-info') {
+ notifyWithUserInfo(title, 'could not synchronize with the server.', detail);
+ }
+ else if(data.reason == 'recording-engine-unspecified') {
+ notifyWithUserInfo(title, 'had a problem writing recording data to disk.', detail);
+ }
+ else if(data.reason == 'recording-engine-create-directory') {
+ notifyWithUserInfo(title, 'had a problem creating a recording folder.', detail);
+ }
+ else if(data.reason == 'recording-engine-create-file') {
+ notifyWithUserInfo(title, 'had a problem creating a recording file.', detail);
+ }
+ else if(data.reason == 'recording-engine-sample-rate') {
+ notifyWithUserInfo(title, 'had a problem recording at the specified sample rate.', detail);
+ }
+ else {
+ app.notifyAlert(title, "Error reason: " + reason);
+ }
+
+ displayDoneRecording();
})
- sessionModel.subscribe('sessionScreen', sessionChanged);
- sessionModel.joinSession(sessionId)
+ sessionModel.subscribe('sessionScreen', sessionChanged);
+
+ sessionModel.joinSession(sessionId)
.fail(function(xhr, textStatus, errorMessage) {
- if(xhr.status == 404) {
- // we tried to join the session, but it's already gone. kick user back to join session screen
- promptLeave = false;
- context.window.location = "/client#/findSession";
- app.notify(
- { title: "Unable to Join Session",
- text: "The session you attempted to join is over."
- },
- null,
- true);
+ if(xhr.status == 404) {
+ // we tried to join the session, but it's already gone. kick user back to join session screen
+ promptLeave = false;
+ context.window.location = "/client#/findSession";
+ app.notify(
+ { title: "Unable to Join Session",
+ text: "The session you attempted to join is over."
+ },
+ null,
+ true);
+ }
+ else if(xhr.status == 422) {
+ var response = JSON.parse(xhr.responseText);
+ if(response["errors"] && response["errors"]["tracks"] && response["errors"]["tracks"][0] == "Please select at least one track") {
+ app.notifyAlert("No Inputs Configured", $('You will need to reconfigure your audio device.'));
}
- else if(xhr.status == 422) {
- var response = JSON.parse(xhr.responseText);
- if(response["errors"] && response["errors"]["tracks"] && response["errors"]["tracks"][0] == "Please select at least one track") {
- app.notifyAlert("No Inputs Configured", $('You will need to reconfigure your audio device.'));
- }
- else if(response["errors"] && response["errors"]["music_session"] && response["errors"]["music_session"][0] == ["is currently recording"]) {
- promptLeave = false;
- context.window.location = "/client#/findSession";
- app.notify( { title: "Unable to Join Session", text: "The session is currently recording." }, null, true);
- }
- else {
- app.notifyServerError(xhr, 'Unable to Join Session');
- }
+ else if(response["errors"] && response["errors"]["music_session"] && response["errors"]["music_session"][0] == ["is currently recording"]) {
+ promptLeave = false;
+ context.window.location = "/client#/findSession";
+ app.notify( { title: "Unable to Join Session", text: "The session is currently recording." }, null, true);
}
else {
- app.notifyServerError(xhr, 'Unable to Join Session');
+ app.notifyServerError(xhr, 'Unable to Join Session');
}
+ }
+ else {
+ app.notifyServerError(xhr, 'Unable to Join Session');
+ }
});
+ })
+
}
// not leave session but leave screen
@@ -2727,17 +2729,22 @@
// XXX: test with this removed; it should be unnecessary
context.jamClient.JamTrackStopPlay();
+ var sampleRate = context.jamClient.GetSampleRate()
+ var sampleRateForFilename = sampleRate == 48 ? '48' : '44'
+ var fqId = jamTrack.id + '-' + sampleRateForFilename
+
if(jamTrack.jmep)
{
logger.debug("setting jmep data")
- context.jamClient.JamTrackLoadJmep(jamTrack.id, jamTrack.jmep)
+
+ context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep)
}
else {
logger.debug("no jmep data for jamtrack")
}
// JamTrackPlay means 'load'
- var result = context.jamClient.JamTrackPlay(jamTrack.id);
+ var result = context.jamClient.JamTrackPlay(fqId);
if(!result) {
app.notify(
@@ -2947,13 +2954,18 @@
}
function closeJamTrack() {
- logger.debug("closing recording");
+ logger.debug("closing jam track");
if (sessionModel.recordingModel.isRecording()) {
logger.debug("can't close jamtrack while recording")
return false;
}
+ if(!sessionModel.selfOpenedJamTracks()) {
+ logger.debug("can't close jamtrack if not the opener")
+ return false;
+ }
+
if(downloadJamTrack) {
logger.debug("closing DownloadJamTrack widget")
downloadJamTrack.root.remove();
diff --git a/web/app/assets/javascripts/session_utils.js b/web/app/assets/javascripts/session_utils.js
index 4e3b13594..a7eefa791 100644
--- a/web/app/assets/javascripts/session_utils.js
+++ b/web/app/assets/javascripts/session_utils.js
@@ -136,20 +136,19 @@
return false;
}
- if(context.JK.guardAgainstSinglePlayerProfile(app).canPlay) {
- gearUtils.guardAgainstInvalidConfiguration(app)
- .fail(function() {
- app.notify(
- { title: "Unable to Join Session",
- text: "You can only join a session once you have working audio gear and a tested internet connection."
- });
- })
- .done(function() {
- if (successCallback) {
- successCallback();
- }
- });
- }
+ gearUtils.guardAgainstInvalidConfiguration(app)
+ .fail(function() {
+ app.notify(
+ { title: "Unable to Join Session",
+ text: "You can only join a session once you have working audio gear and a tested internet connection."
+ });
+ })
+ .done(function() {
+ if (successCallback) {
+ successCallback();
+ }
+ });
+
}
sessionUtils.joinSession = function(sessionId) {
diff --git a/web/app/assets/javascripts/shopping_cart.js b/web/app/assets/javascripts/shopping_cart.js
index ac115f175..9de0c7cf2 100644
--- a/web/app/assets/javascripts/shopping_cart.js
+++ b/web/app/assets/javascripts/shopping_cart.js
@@ -11,7 +11,7 @@
var $content = null;
function beforeShow(data) {
-
+ clearContent();
}
function afterShow(data) {
diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js
index 7b8b3802a..7aa234f7a 100644
--- a/web/app/assets/javascripts/utils.js
+++ b/web/app/assets/javascripts/utils.js
@@ -584,6 +584,7 @@
logger.debug("offBackendEvent: " + alertData.name + '.' + namespace, alertData)
$(document).off(alertData.name + '.' + namespace);
}
+
/*
* Loads a listbox or dropdown with the values in input_array, setting the option value
* to the id_field and the option text to text_field. It will preselect the option with
@@ -1128,70 +1129,6 @@
return true;
}
- context.JK.guardAgainstSinglePlayerProfile = function(app, beforeCallback) {
-
- var canPlayWithOthers = context.JK.GearUtilsInstance.canPlayWithOthers();
-
- if(!canPlayWithOthers.canPlay) {
- logger.debug("guarding against single player profile")
-
- var $dialog = app.layout.showDialog('single-player-profile-dialog');
-
- // so that callers can check dialog result
- canPlayWithOthers.dialog = $dialog;
-
- // allow callers to take action before default behavior
- if(beforeCallback) {
- $dialog.one(EVENTS.DIALOG_CLOSED, beforeCallback);
- }
-
- $dialog.one(EVENTS.DIALOG_CLOSED, function(e, data) {
-
- if(!data.canceled) {
- if(data.result.choice == 'private_session') {
- var data = {
- createType: 'quick-start',
- timezone: {},
- recurring_mode: {},
- language: {},
- band: {},
- musician_access: {},
- fans_access: {},
- rsvp_slots: [],
- open_rsvps: false
- };
-
- context.JK.privateSessionSettings(data)
-
- context.JK.createSession(app, data)
- .done(function(response) {
- var sessionId = response.id;
-
- context.JK.GA.trackSessionCount(true, true, 0);
-
- // we redirect to the session screen, which handles the REST call to POST /participants.
- logger.debug("joining session screen: " + sessionId)
- context.location = '/client#/session/' + sessionId;
- })
- .fail(function(jqXHR) {
- logger.debug("unable to schedule a private session")
- app.notifyServerError(jqXHR, "Unable to schedule a private session");
- })
- }
- else if(data.result.choice == 'gear_setup') {
- window.location = '/client#/account/audio'
- }
- else
- {
- logger.error("unknown choice: " + data.result.choice)
- alert("unknown choice: " + data.result.choice)
- }
- }
- })
- }
-
- return canPlayWithOthers;
- }
context.JK.createSession = function(app, data) {
diff --git a/web/app/assets/javascripts/wizard/gear/gear_wizard.js b/web/app/assets/javascripts/wizard/gear/gear_wizard.js
index f80a5fe0a..6a2d1b0ae 100644
--- a/web/app/assets/javascripts/wizard/gear/gear_wizard.js
+++ b/web/app/assets/javascripts/wizard/gear/gear_wizard.js
@@ -80,6 +80,7 @@
var newProfileName = 'FTUEAttempt-' + new Date().getTime().toString();
logger.debug("setting FTUE-prefixed profile name to: " + newProfileName);
context.jamClient.FTUESetMusicProfileName(newProfileName);
+ context.jamClient.FTUESetPreferredMixerSampleRate(1);
context.jamClient.FTUEClearChannelAssignments();
newSession();
diff --git a/web/app/assets/javascripts/wizard/gear_utils.js b/web/app/assets/javascripts/wizard/gear_utils.js
index d5c70d9a1..489b6294c 100644
--- a/web/app/assets/javascripts/wizard/gear_utils.js
+++ b/web/app/assets/javascripts/wizard/gear_utils.js
@@ -10,16 +10,20 @@
var rest = new context.JK.Rest();
context.JK.GearUtils = gearUtils;
var logger = context.JK.logger;
+ var ALERT_NAMES = context.JK.ALERT_NAMES;
var ASSIGNMENT = context.JK.ASSIGNMENT;
var VOICE_CHAT = context.JK.VOICE_CHAT;
var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR;
var EVENTS = context.JK.EVENTS;
var SYSTEM_DEFAULT_PLAYBACK_ONLY = 'System Default (Playback Only)';
+ var JAMKAZAM_VIRTUAL_INPUT = "JamKazam Virtual Input";
context.JK.GearUtilsInstance = gearUtils;
gearUtils.SKIPPED_NETWORK_TEST = -1; // we store a negative 1 to mean that we let the user skip.
+ gearUtils.SYSTEM_DEFAULT_PLAYBACK_ONLY = SYSTEM_DEFAULT_PLAYBACK_ONLY;
+ gearUtils.JAMKAZAM_VIRTUAL_INPUT = JAMKAZAM_VIRTUAL_INPUT;
gearUtils.skippedNetworkTest = false; // we allow someone to play in session (for one client run) if it's our fault they can't network test score
var reloadAudioTimeout = null;
@@ -30,17 +34,39 @@
return channel.assignment == ASSIGNMENT.CHAT || channel.assignment == ASSIGNMENT.OUTPUT || channel.assignment > 0;
}
+
+ gearUtils.resyncAudio = function() {
+
+ function backendMixerChange (e, data) {
+
+ if (data.text == 'deferred') {
+ context.JK.offBackendEvent(ALERT_NAMES.BACKEND_MIXER_CHANGE, 'gearUtilsResyncAudio', backendMixerChange)
+ console.log("context.jamClient.FTUEGetExpectedLatency()", context.jamClient.FTUEGetExpectedLatency().latency)
+ deferred.resolve();
+ }
+ ;
+ }
+
+ var deferred = new $.Deferred();
+
+ context.JK.onBackendEvent(ALERT_NAMES.BACKEND_MIXER_CHANGE, 'gearUtilsResyncAudio', backendMixerChange);
+
+ context.jamClient.SessionAudioResync();
+
+ // give backend 5 seconds to timeout
+ deferred.timer = setTimeout(function() {
+ deferred.rejectWith('timeout');
+ context.JK.offBackendEvent(ALERT_NAMES.BACKEND_MIXER_CHANGE, 'gearUtilsResyncAudio', backendMixerChange)
+ }, 5000);
+
+ return deferred;
+ }
+
+
// to play with others, you have to have inputs,
// as well have a score below 20 ms
gearUtils.canPlayWithOthers = function(profile) {
- if(gon.global.gear_check_reload_audio) {
- if (!context.jamClient.IsAudioStarted()) {
- context.jamClient.ReloadAudioSystem(true, true, true);
- context.jamClient.StopAudio();
- }
- }
-
var isNoInputProfile = gearUtils.isNoInputProfile(profile);
var expectedLatency = context.jamClient.FTUEGetExpectedLatency();
@@ -182,7 +208,7 @@
return;
}
- if (device.name == "JamKazam Virtual Input") {
+ if (device.name == JAMKAZAM_VIRTUAL_INPUT) {
return;
}
@@ -431,6 +457,84 @@
return deferred;
}
+ context.JK.guardAgainstSinglePlayerProfile = function(app, beforeCallback) {
+
+ var deferred = new $.Deferred();
+
+ var canPlayWithOthers = context.JK.GearUtilsInstance.canPlayWithOthers();
+
+ if(!canPlayWithOthers.canPlay) {
+ logger.debug("guarding against single player profile")
+
+ var $dialog = app.layout.showDialog('single-player-profile-dialog');
+
+ // so that callers can check dialog result
+ canPlayWithOthers.dialog = $dialog;
+
+ // allow callers to take action before default behavior
+ if(beforeCallback) {
+ $dialog.one(EVENTS.DIALOG_CLOSED, beforeCallback);
+ }
+
+ $dialog.one(EVENTS.DIALOG_CLOSED, function(e, data) {
+
+ if(data.canceled) {
+ deferred.rejectWith(canPlayWithOthers, [{ reason: 'canceled', controlled_location:false }])
+ }
+ else {
+ if(data.result.choice == 'private_session') {
+ var data = {
+ createType: 'quick-start',
+ timezone: {},
+ recurring_mode: {},
+ language: {},
+ band: {},
+ musician_access: {},
+ fans_access: {},
+ rsvp_slots: [],
+ open_rsvps: false
+ };
+
+ context.JK.privateSessionSettings(data)
+
+ context.JK.createSession(app, data)
+ .done(function(response) {
+ var sessionId = response.id;
+
+ context.JK.GA.trackSessionCount(true, true, 0);
+
+ deferred.rejectWith(canPlayWithOthers, [{ reason: 'private_session', controlled_location:true }])
+ // we redirect to the session screen, which handles the REST call to POST /participants.
+ logger.debug("joining session screen: " + sessionId)
+ context.location = '/client#/session/' + sessionId;
+ })
+ .fail(function(jqXHR) {
+ deferred.rejectWith(canPlayWithOthers, [{ reason: 'gear_setup', controlled_location:false }])
+ logger.debug("unable to schedule a private session")
+ app.notifyServerError(jqXHR, "Unable to schedule a private session");
+ })
+ }
+ else if(data.result.choice == 'gear_setup') {
+ deferred.rejectWith(canPlayWithOthers, [{ reason: data.result.choice,controlled_location:true }])
+ window.location = '/client#/account/audio'
+ }
+ else
+ {
+ deferred.rejectWith(canPlayWithOthers, [{ reason: 'unknown', controlled_location:false }])
+ logger.error("unknown choice: " + data.result.choice)
+ alert("unknown choice: " + data.result.choice)
+ }
+ }
+ })
+ }
+ else {
+ deferred.resolveWith(canPlayWithOthers)
+ }
+
+
+ return deferred;
+ }
+
gearUtils.guardAgainstActiveProfileMissing = function (app, backendInfo) {
diff --git a/web/app/assets/stylesheets/playbackControls.css.scss b/web/app/assets/stylesheets/playbackControls.css.scss
index a1e20c77f..2dcfb5b0f 100644
--- a/web/app/assets/stylesheets/playbackControls.css.scss
+++ b/web/app/assets/stylesheets/playbackControls.css.scss
@@ -1,3 +1,4 @@
+// see audioWidgets.css
.recording-controls {
diff --git a/web/app/controllers/api_jam_tracks_controller.rb b/web/app/controllers/api_jam_tracks_controller.rb
index f7dbc3b18..399410554 100644
--- a/web/app/controllers/api_jam_tracks_controller.rb
+++ b/web/app/controllers/api_jam_tracks_controller.rb
@@ -7,6 +7,10 @@ class ApiJamTracksController < ApiController
respond_to :json
+ def log
+ @log || Logging.logger[ApiJamTracksController]
+ end
+
def show
@jam_track = JamTrack.find_by_plan_code!(params[:plan_code])
end
@@ -70,7 +74,7 @@ class ApiJamTracksController < ApiController
def download
if @jam_track_right.valid?
sample_rate = params[:sample_rate].nil? ? nil : params[:sample_rate].to_i
- if (@jam_track_right && @jam_track_right.ready?(sample_rate))
+ if @jam_track_right && @jam_track_right.ready?(sample_rate)
@jam_track_right.update_download_count
@jam_track_right.last_downloaded_at = Time.now
@jam_track_right.save!
@@ -86,7 +90,8 @@ class ApiJamTracksController < ApiController
def enqueue
sample_rate = params[:sample_rate].nil? ? nil : params[:sample_rate].to_i
- @jam_track_right.enqueue_if_needed(sample_rate)
+ enqueued = @jam_track_right.enqueue_if_needed(sample_rate)
+ log.debug("jamtrack #{enqueued ? "ENQUEUED" : "NOT ENQUEUED"}: jam_track_right=#{@jam_track_right.id} sample_rate=#{sample_rate} ")
render :json => { :message => "enqueued" }, :status => 200
end
@@ -102,14 +107,31 @@ class ApiJamTracksController < ApiController
return
end
- jamtrack_ids = jamtrack_holder[:tracks]
+ jamtracks = jamtrack_holder[:tracks]
- unless jamtrack_ids.kind_of?(Array)
+ unless jamtracks.kind_of?(Array)
render :json => {message: 'jamtracks:tracks parameter must be an array'}, :status => 422
return
end
+
+ # jamtracks come in the form id-44 or id-48, so we need to do a little extra parsing
+ puts "#{jamtracks.inspect}"
+ jamtrack_ids = Set.new
+ jamtracks_fq_ids = Set.new
+ jamtracks.each do |jamtrack|
+ rindex = jamtrack.rindex('-')
+ if rindex
+ id = jamtrack[0..(rindex-1)]
+ jamtrack_ids << id
+ jamtracks_fq_ids << jamtrack # includes sample rate
+ end
+ end
+
+
+ puts "#{jamtrack_ids.inspect} #{jamtracks_fq_ids.inspect}"
@jam_tracks = JamTrackRight.list_keys(current_user, jamtrack_ids)
+ @jamtracks_fq_ids = jamtracks_fq_ids
end
private
diff --git a/web/app/views/api_jam_tracks/keys.rabl b/web/app/views/api_jam_tracks/keys.rabl
index f82aa5650..a5cd9d471 100644
--- a/web/app/views/api_jam_tracks/keys.rabl
+++ b/web/app/views/api_jam_tracks/keys.rabl
@@ -1,9 +1,23 @@
object @jam_tracks
node do |jam_track|
-{
- id: jam_track['id'].to_s,
- private: jam_track['private_key'],
- error: jam_track['private_key'] ? nil : ( jam_track['jam_track_right_id'] ? 'no_key' : 'not_purchased' )
-}
+
+ id = jam_track['id']
+ result = { id: id }
+
+ if @jamtracks_fq_ids.include?("#{id}-44")
+ result['44'] = {
+ private: jam_track['private_key_44'],
+ error: jam_track['private_key_44'] ? nil : ( jam_track['jam_track_right_id'] ? 'no_key' : 'not_purchased' )
+ }
+ end
+
+ if @jamtracks_fq_ids.include?("#{id}-48")
+ result['48'] = {
+ private: jam_track['private_key_48'],
+ error: jam_track['private_key_48'] ? nil : ( jam_track['jam_track_right_id'] ? 'no_key' : 'not_purchased' )
+ }
+ end
+
+ result
end
\ No newline at end of file
diff --git a/web/config/application.rb b/web/config/application.rb
index 9a21433ce..ad3aff3e3 100644
--- a/web/config/application.rb
+++ b/web/config/application.rb
@@ -332,6 +332,5 @@ if defined?(Bundler)
config.alerts_api_enabled = true
config.gear_check_ignore_high_latency = false
- config.gear_check_reload_audio = true
end
end
diff --git a/web/config/initializers/gon.rb b/web/config/initializers/gon.rb
index f9eb797f6..ff5a4d74f 100644
--- a/web/config/initializers/gon.rb
+++ b/web/config/initializers/gon.rb
@@ -14,5 +14,4 @@ Gon.global.recurly_public_api_key = Rails.application.config.recurly_public_api_
Gon.global.one_free_jamtrack_per_user = Rails.application.config.one_free_jamtrack_per_user
Gon.global.video_available = Rails.application.config.video_available
Gon.global.gear_check_ignore_high_latency = Rails.application.config.gear_check_ignore_high_latency
-Gon.global.gear_check_reload_audio = Rails.application.config.gear_check_reload_audio
Gon.global.env = Rails.env
diff --git a/web/spec/controllers/api_jam_tracks_controller_spec.rb b/web/spec/controllers/api_jam_tracks_controller_spec.rb
index e70578564..123041120 100644
--- a/web/spec/controllers/api_jam_tracks_controller_spec.rb
+++ b/web/spec/controllers/api_jam_tracks_controller_spec.rb
@@ -143,30 +143,33 @@ describe ApiJamTracksController do
end
it "download depends on rights" do
- get :download, :id=>@jam_track.id
+ get :download, :id=>@jam_track.id, sample_rate: 48
response.status.should == 403
right = JamTrackRight.create(:user=>@user, :jam_track=>@jam_track)
- get :download, :id=>@jam_track.id
+ get :download, :id=>@jam_track.id, sample_rate: 48
response.status.should == 202
right.download_count.should eq(0)
- right.private_key.should be_nil
+ right.private_key_44.should be_nil
+ right.private_key_48.should be_nil
qname = "#{ResqueSpec.queue_name(JamRuby::JamTracksBuilder)}"
#puts "ResqueSpec.peek(qname)#{ResqueSpec.peek(qname)}"
- JamTracksBuilder.should have_queued(right.id,nil).in(:jam_tracks_builder)
+ JamTracksBuilder.should have_queued(right.id,48).in(:jam_tracks_builder)
expect(ResqueSpec.peek(qname).present?).to eq(true)
ResqueSpec.perform_next(qname)
JamTracksBuilder.should_not have_queued(right.id,nil).in(:jam_tracks_builder)
right.reload
- right.private_key.should_not be_nil
+ right.private_key_44.should be_nil
+ right.private_key_48.should_not be_nil
right.download_count.should eq(0)
- get :download, :id=>@jam_track.id
+ get :download, :id=>@jam_track.id, sample_rate: 48
response.status.should == 302
- response.location.should =~ /.*#{Regexp.escape(right.filename)}.*/
+ puts response.location
+ response.location.should =~ /.*#{Regexp.escape(right.filename(:url_48))}.*/
right.reload
right.download_count.should eq(1)
@@ -182,7 +185,8 @@ describe ApiJamTracksController do
get :download, :id=>@jam_track.id, :sample_rate=>44
response.status.should == 202
right.download_count.should eq(0)
- right.private_key.should be_nil
+ right.private_key_44.should be_nil
+ right.private_key_48.should be_nil
qname = "#{ResqueSpec.queue_name(JamRuby::JamTracksBuilder)}"
#puts "ResqueSpec.peek(qname)#{ResqueSpec.peek(qname)}"
@@ -193,12 +197,13 @@ describe ApiJamTracksController do
JamTracksBuilder.should_not have_queued(right.id, 44).in(:jam_tracks_builder)
right.reload
- right.private_key.should_not be_nil
+ right.private_key_44.should_not be_nil
+ right.private_key_48.should be_nil
right.download_count.should eq(0)
get :download, :id=>@jam_track.id, :sample_rate=>44
response.status.should == 302
- response.location.should =~ /.*#{Regexp.escape(right.filename)}.*/
+ response.location.should =~ /.*#{Regexp.escape(right.filename(:url_44))}.*/
right.reload
right.download_count.should eq(1)
@@ -216,53 +221,66 @@ describe ApiJamTracksController do
end
it "track with no rights" do
- get :keys, jamtracks: { tracks: [@jam_track.id] }
+ get :keys, jamtracks: { tracks: ["#{@jam_track.id}-44"] }
response.status.should == 200
json = JSON.parse(response.body)
json.length.should == 1
json[0]['id'].should == @jam_track.id.to_s
- json[0]['private'].should be_nil
- json[0]['error'].should == 'not_purchased'
+ json[0]['44'].should_not be_nil
+ json[0]['44']['private'].should be_nil
+ json[0]['44']['error'].should == 'not_purchased'
+ json[0]['48'].should be_nil
end
it "track with no key" do
- right = FactoryGirl.create(:jam_track_right, user: @user, private_key: nil, jam_track: @jam_track)
+ right = FactoryGirl.create(:jam_track_right, user: @user, private_key_44: nil, private_key_48:nil, jam_track: @jam_track)
- get :keys, jamtracks: { tracks: [@jam_track.id] }
+ get :keys, jamtracks: { tracks: ["#{@jam_track.id}-44", "#{@jam_track.id}-48"] }
response.status.should == 200
json = JSON.parse(response.body)
json.length.should == 1
- json[0]['id'].should == @jam_track.id.to_s
- json[0]['private'].should be_nil
- json[0]['error'].should == 'no_key'
+ json[0]['44'].should_not be_nil
+ json[0]['44']['private'].should be_nil
+ json[0]['44']['error'].should == 'no_key'
+ json[0]['48'].should_not be_nil
+ json[0]['48']['private'].should be_nil
+ json[0]['48']['error'].should == 'no_key'
end
it "track with key" do
- right = FactoryGirl.create(:jam_track_right, user: @user, private_key: 'abc', jam_track: @jam_track)
- get :keys, jamtracks: { tracks: [@jam_track.id] }
+ right = FactoryGirl.create(:jam_track_right, user: @user, private_key_44: 'abc', private_key_48:nil, jam_track: @jam_track)
+ get :keys, jamtracks: { tracks: ["#{@jam_track.id}-44", "#{@jam_track.id}-48"] }
response.status.should == 200
json = JSON.parse(response.body)
json.length.should == 1
json[0]['id'].should == @jam_track.id.to_s
- json[0]['private'].should eq('abc')
- json[0]['error'].should be_nil
+ json[0]['44'].should_not be_nil
+ json[0]['44']['private'].should eq('abc')
+ json[0]['44']['error'].should be_nil
+ json[0]['48'].should_not be_nil
+ json[0]['48']['private'].should be_nil
+ json[0]['48']['error'].should == 'no_key'
end
it "non-owning user asking for a real track" do
- right = FactoryGirl.create(:jam_track_right, user: FactoryGirl.create(:user), private_key: 'abc', jam_track: @jam_track)
- get :keys, jamtracks: { tracks: [@jam_track.id] }
+ right = FactoryGirl.create(:jam_track_right, user: FactoryGirl.create(:user), private_key_44: 'abc', private_key_48:nil, jam_track: @jam_track)
+ get :keys, jamtracks: { tracks: ["#{@jam_track.id}-44", "#{@jam_track.id}-48"] }
response.status.should == 200
json = JSON.parse(response.body)
json[0]['id'].should == @jam_track.id.to_s
- json[0]['private'].should be_nil
- json[0]['error'].should == 'not_purchased'
+ json[0]['44'].should_not be_nil
+ json[0]['44']['private'].should be_nil
+ json[0]['44']['error'].should eq('not_purchased')
+ json[0]['48'].should_not be_nil
+ json[0]['48']['private'].should be_nil
+ json[0]['48']['error'].should eq('not_purchased')
end
end
describe "enqueue" do
it "success" do
- right = FactoryGirl.create(:jam_track_right, user: @user, signed: false)
+ right = FactoryGirl.create(:jam_track_right, user: @user, signed_44: false, signed_48:false)
right.signing_queued_at.should be_nil
post :enqueue, {:format=>'json', :id=>right.jam_track.id}
response.should be_success
diff --git a/web/spec/features/jamtrack_shopping_spec.rb b/web/spec/features/jamtrack_shopping_spec.rb
index 4dd20a058..4273067ce 100644
--- a/web/spec/features/jamtrack_shopping_spec.rb
+++ b/web/spec/features/jamtrack_shopping_spec.rb
@@ -135,11 +135,15 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
find_jamtrack jt_us
find("a.jamtrack-add-cart[data-jamtrack-id=\"#{jt_us.id}\"]").trigger(:click)
- find('a.button-orange', text: 'CONTINUE SHOPPING').trigger(:click)
- find("a.jamtrack-add-cart[data-jamtrack-id=\"#{jt_ww.id}\"]").trigger(:click)
+ find('.shopping-sub-total', text: "Subtotal:$ #{jt_us.price}")
find('a.button-orange', text: 'CONTINUE SHOPPING').trigger(:click)
- find('.shopping-sub-total', text: "Subtotal: $ #{jt_us.price + jt_ww.price}")
+ find_jamtrack jt_ww
+
+ find("a.jamtrack-add-cart[data-jamtrack-id=\"#{jt_ww.id}\"]").trigger(:click)
+ find('.shopping-sub-total', text: "Subtotal:$ #{jt_us.price + jt_ww.price}")
+ #find('a.button-orange', text: 'CONTINUE SHOPPING').trigger(:click)
+
end
it "can expand" do