This commit is contained in:
Seth Call 2015-02-25 10:43:21 -06:00
parent 4841e56dce
commit dbaeb8d996
17 changed files with 161 additions and 11 deletions

View File

@ -253,4 +253,5 @@ recorded_backing_tracks.sql
recorded_backing_tracks_add_filename.sql
user_syncs_include_backing_tracks.sql
remove_bpm_from_jamtracks.sql
jam_track_version.sql
jam_track_version.sql
recorded_jam_track_tracks.sql

View File

@ -0,0 +1,15 @@
ALTER TABLE recordings ADD COLUMN jam_track_id BIGINT REFERENCES jam_tracks(id);
ALTER TABLE recordings ADD COLUMN jam_track_initiator_id VARCHAR(64) REFERENCES users(id);
CREATE TABLE recorded_jam_track_tracks (
id BIGINT PRIMARY KEY,
user_id VARCHAR(64) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
jam_track_track_id VARCHAR(64) REFERENCES jam_track_tracks(id) NOT NULL,
recording_id VARCHAR(64) REFERENCES recordings(id) NOT NULL,
discard BOOLEAN,
timeline JSON,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE recorded_jam_track_tracks ALTER COLUMN id SET DEFAULT nextval('tracks_next_tracker_seq');

View File

@ -138,6 +138,7 @@ require "jam_ruby/models/recorded_backing_track_observer"
require "jam_ruby/models/recorded_track"
require "jam_ruby/models/recorded_track_observer"
require "jam_ruby/models/recorded_video"
require "jam_ruby/models/recorded_jam_track_track"
require "jam_ruby/models/quick_mix"
require "jam_ruby/models/quick_mix_observer"
require "jam_ruby/models/share_token"

View File

@ -51,6 +51,8 @@ module JamRuby
has_many :playing_sessions, :class_name => "JamRuby::ActiveMusicSession"
has_many :recordings, :class_name => "JamRuby::Recording"
accepts_nested_attributes_for :jam_track_tracks, allow_destroy: true
accepts_nested_attributes_for :jam_track_tap_ins, allow_destroy: true

View File

@ -21,6 +21,8 @@ module JamRuby
belongs_to :instrument, class_name: "JamRuby::Instrument"
belongs_to :jam_track, class_name: "JamRuby::JamTrack"
has_many :recorded_jam_track_tracks, :class_name => "JamRuby::RecordedJamTrackTrack", :foreign_key => :jam_track_track_id, :dependent => :destroy
# create storage directory that will house this jam_track, as well as
def store_dir
"#{jam_track.store_dir}/tracks"

View File

@ -0,0 +1,21 @@
module JamRuby
# BackingTrack analog to JamRuby::RecordedTrack
class RecordedJamTrackTrack < ActiveRecord::Base
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :recorded_jam_track_tracks
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :recorded_jam_track_tracks
belongs_to :jam_track_track, :class_name => "JamRuby::JamTrackTrack", :inverse_of => :recorded_jam_track_tracks
validates :user, presence: true
validates :jam_track_track, presence:true
def self.create_from_jam_track_track(jam_track_track, recording)
recorded_jam_track_track = self.new
recorded_jam_track_track.recording = recording
recorded_jam_track_track.jam_track_track = jam_track_track
recorded_jam_track_track.save
recorded_jam_track_track
end
end
end

View File

@ -12,6 +12,7 @@ module JamRuby
has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :foreign_key => :recording_id, :dependent => :destroy
has_many :recorded_videos, :class_name => "JamRuby::RecordedVideo", :foreign_key => :recording_id, :dependent => :destroy
has_many :recorded_backing_tracks, :class_name => "JamRuby::RecordedBackingTrack", :foreign_key => :recording_id, :dependent => :destroy
has_many :recorded_jam_track_tracks, :class_name => "JamRuby::RecordedJamTrackTrack", :foreign_key => :recording_id, :dependent => :destroy
has_many :comments, :class_name => "JamRuby::RecordingComment", :foreign_key => "recording_id", :dependent => :destroy
has_many :likes, :class_name => "JamRuby::RecordingLiker", :foreign_key => "recording_id", :dependent => :destroy
has_many :plays, :class_name => "JamRuby::PlayablePlay", :as => :playable, :dependent => :destroy
@ -20,6 +21,8 @@ module JamRuby
belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings, :foreign_key => 'owner_id'
belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recordings
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", :inverse_of => :recordings, foreign_key: :music_session_id
belongs_to :jam_track, :class_name => "JamRuby::JamTrack", :inverse_of => :recordings, :foreign_key => 'jam_track_id'
belongs_to :jam_track_initiator, :class_name => "JamRuby::User", :inverse_of => :recorded_jam_tracks, :foreign_key => 'jam_track_initiator_id'
accepts_nested_attributes_for :recorded_tracks, :mixes, :claimed_recordings, allow_destroy: true
@ -223,6 +226,14 @@ module JamRuby
recording.recorded_backing_tracks << RecordedBackingTrack.create_from_backing_track(backing_track, recording)
end
end
if music_session.jam_track
music_session.jam_track.jam_track_tracks.each do |jam_track_track|
recording.recorded_jam_tracks << RecordedJamTrack.create_from_jam_track_track(jam_track_track, recording)
end
recording.jam_track = music_session.jam_track
recording.jam_track_initiator = music_session.jam_track_initiator
end
end
end
@ -556,7 +567,7 @@ module JamRuby
:recording_id => recorded_item.recording_id,
:client_track_id => recorded_item.client_track_id,
:next => recorded_item.id
})
})
else
end
@ -678,6 +689,24 @@ module JamRuby
self.save(:validate => false)
end
def add_timeline(timeline)
tracks = timeline["tracks"]
raise JamArgumentError, "tracks must be specified" unless tracks
jam_tracks = tracks.select {|track| track["type"] == "jam_track"}
jam_tracks.each do |client_jam_track|
recorded_jam_track_track = RecordedJamTrackTrack.find_by_jam_track_track_id(client_jam_track["id"])
if recorded_jam_track_track
recorded_jam_track_track.timeline = client_jam_track["timeline"].to_json
recorded_jam_track_track.save!
else
@@log.error("unable to find JamTrackTrack with id #{recorded_jam_track_track.id}")
end
end
end
private
def self.validate_user_is_band_member(user, band)
unless band.users.exists? user

View File

@ -124,6 +124,10 @@ module JamRuby
has_many :recorded_videos, :foreign_key => "user_id", :class_name => "JamRuby::RecordedVideo", :inverse_of => :user
has_many :recorded_backing_tracks, :foreign_key => "user_id", :class_name => "JamRuby::RecordedBackingTrack", :inverse_of => :user
has_many :quick_mixes, :foreign_key => "user_id", :class_name => "JamRuby::QuickMix", :inverse_of => :user
has_many :recorded_jam_track_tracks, :foreign_key => "user_id", :class_name => "JamRuby::RecordedJamTrackTrack", :inverse_of => :user
# jam track recordings started
has_many :initiated_jam_track_recordings, :foreign_key => 'jam_track_initiator_id', :class_name => "JamRuby::Recording", :inverse_of => :jam_track_initiator
# invited users
has_many :invited_users, :foreign_key => "sender_id", :class_name => "JamRuby::InvitedUser"

View File

@ -268,7 +268,6 @@ FactoryGirl.define do
association :recording, factory: :recording
end
factory :recorded_video, :class => JamRuby::RecordedVideo do
sequence(:client_video_source_id) { |n| "client_video_source_id-#{n}"}
fully_uploaded true
@ -277,6 +276,12 @@ FactoryGirl.define do
association :recording, factory: :recording
end
factory :recorded_jam_track_track, :class => JamRuby::RecordedJamTrackTrack do
association :user, factory: :user
association :recording, factory: :recording
association :jam_track_track, factory: :jam_track_track
end
factory :instrument, :class => JamRuby::Instrument do
description { |n| "Instrument #{n}" }
end

View File

@ -1073,6 +1073,33 @@ describe Recording do
RecordedVideo.find_by_id(video.id).should_not be_nil
end
end
describe "add_timeline" do
let!(:recorded_jam_track_track) {FactoryGirl.create(:recorded_jam_track_track)}
let(:recording) {recorded_jam_track_track.recording}
let(:timeline_data) {{"sample" => "data"}}
let(:good_timeline) { {
"tracks" => [
{
"id" => recorded_jam_track_track.jam_track_track.id,
"timeline" => timeline_data,
"type" => "jam_track"
}
]
}
}
it "applies timeline data correctly" do
recording.add_timeline good_timeline
recorded_jam_track_track.reload
JSON.parse(recorded_jam_track_track.timeline).should eq(timeline_data)
end
it "fails if no tracks data" do
expect { recording.add_timeline({}) }.to raise_error(JamRuby::JamArgumentError)
end
end
end

View File

@ -1585,13 +1585,23 @@
});
}
function validateUrlSite(url, sitetype) {
function validateUrlSite(url, sitetype) {
return $.ajax({
type: "GET",
url: '/api/data_validation?sitetype='+sitetype+'&data=' + encodeURIComponent(url),
contentType: 'application/json'
});
}
function addRecordingTimeline(recordingId, data) {
return $.ajax({
type: "GET",
url: '/api/data_validation?sitetype='+sitetype+'&data=' + encodeURIComponent(url),
contentType: 'application/json'
type: "POST",
url: '/api/recordings/' + recordingId + '/timeline',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(data),
});
}
}
function initialize() {
return self;
@ -1734,6 +1744,7 @@
this.createSourceChange = createSourceChange;
this.validateUrlSite = validateUrlSite;
this.markRecordedBackingTrackSilent = markRecordedBackingTrackSilent;
this.addRecordingTimeline = addRecordingTimeline;
return this;
};

View File

@ -132,7 +132,6 @@
$self.triggerHandler('stoppedRecording', {'recordingId': recording.id, 'reason' : 'rest', 'details' : arguments});
}
});
});
return true;
}

View File

@ -300,6 +300,21 @@
displayStoppingRecording(data);
})
.on('stoppedRecording', function(e, data) {
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;
@ -1056,6 +1071,7 @@
// Default trackData to participant + no Mixer state.
var trackData = {
type: 'backing_track',
trackId: backingTrack.id,
clientId: backingTrack.client_id,
name: 'Backing',
@ -1140,6 +1156,7 @@
// Default trackData to participant + no Mixer state.
var trackData = {
type: 'jam_track',
trackId: oneOfTheTracks.id,
clientId: oneOfTheTracks.client_id,
name: name,
@ -1241,6 +1258,7 @@
// Default trackData to participant + no Mixer state.
var trackData = {
type: 'metronome',
trackId: "MS" + oneOfTheTracks.id,
clientId: oneOfTheTracks.client_id,
name: "Metronome",
@ -1340,6 +1358,7 @@
// Default trackData to participant + no Mixer state.
var trackData = {
type: 'recorded_track',
trackId: oneOfTheTracks.id,
clientId: oneOfTheTracks.client_id,
name: name,

View File

@ -113,6 +113,11 @@
}
}
// did I open up the current JamTrack?
function selfOpenedJamTracks() {
return currentSession && (currentSession.jam_track_initiator_id == context.JK.currentUserId)
}
function backingTrack() {
if(currentSession) {
// TODO: objectize this for VRFS-2665, VRFS-2666, VRFS-2667, VRFS-2668
@ -830,6 +835,7 @@
this.isMasterMixMode = isMasterMixMode;
this.isPersonalMixMode = isPersonalMixMode;
this.getMixMode = getMixMode;
this.selfOpenedJamTracks = selfOpenedJamTracks;
// ALERT HANDLERS
this.onBackendMixerChanged = onBackendMixerChanged;

View File

@ -1,7 +1,7 @@
class ApiRecordingsController < ApiController
before_filter :api_signed_in_user, :except => [ :add_like ]
before_filter :lookup_recording, :only => [ :show, :stop, :claim, :discard, :keep, :delete_claim ]
before_filter :lookup_recording, :only => [ :show, :stop, :claim, :discard, :keep, :delete_claim, :add_timeline_data ]
before_filter :lookup_recorded_track, :only => [ :download, :upload_next_part, :upload_sign, :upload_part_complete, :upload_complete ]
before_filter :lookup_recorded_backing_track, :only => [ :backing_track_download, :backing_track_upload_next_part, :backing_track_upload_sign, :backing_track_upload_part_complete, :backing_track_upload_complete ]
before_filter :lookup_recorded_video, :only => [ :video_upload_sign, :video_upload_start, :video_upload_complete ]
@ -377,6 +377,13 @@ class ApiRecordingsController < ApiController
end
end
# metadata
def add_timeline
@recording.add_timeline(params[:metadata])
render :json => {}, :status => 200
end
private
def lookup_recording

View File

@ -13,7 +13,7 @@ if !current_user
}
else
attributes :id, :name, :description, :musician_access, :approval_required, :fan_access, :fan_chat, :band_id, :user_id, :claimed_recording_initiator_id, :track_changes_counter, :max_score, :backing_track_path, :metronome_active
attributes :id, :name, :description, :musician_access, :approval_required, :fan_access, :fan_chat, :band_id, :user_id, :claimed_recording_initiator_id, :track_changes_counter, :max_score, :backing_track_path, :metronome_active, :jam_track_initiator_id
node :can_join do |session|
session.can_join?(current_user, true)

View File

@ -451,6 +451,7 @@ SampleApp::Application.routes.draw do
match '/recordings/:id/comments' => 'api_recordings#add_comment', :via => :post, :as => 'api_recordings_add_comment'
match '/recordings/:id/likes' => 'api_recordings#add_like', :via => :post, :as => 'api_recordings_add_like'
match '/recordings/:id/discard' => 'api_recordings#discard', :via => :post, :as => 'api_recordings_discard'
match '/recordings/:id/timeline' => 'api_recordings#add_timeline', :via => :post, :as => 'api_recordings_timeline'
# Recordings - recorded_tracks
match '/recordings/:id/tracks/:track_id' => 'api_recordings#show_recorded_track', :via => :get, :as => 'api_recordings_show_recorded_track'