Merge branch 'develop' of bitbucket.org:jamkazam/jam-cloud into develop
This commit is contained in:
commit
87b6654f28
|
|
@ -35,7 +35,7 @@ class JamRuby::Promotional < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def self.active(max_count=10)
|
||||
rel = self.where(:aasm_state => ACTIVE_STATE)
|
||||
rel = self.where(:aasm_state => ACTIVE_STATE).where('latest_id IS NOT NULL')
|
||||
if 0 < (mc = max_count.to_i)
|
||||
rel = rel.limit(mc)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -78,14 +78,21 @@
|
|||
|
||||
checkServer()
|
||||
.done(function(response) {
|
||||
audioDomElement.play();
|
||||
|
||||
retryAttempts = 0;
|
||||
if(!response.mount) {
|
||||
transition(PlayStateSessionOver);
|
||||
destroy();
|
||||
}
|
||||
else {
|
||||
audioDomElement.play();
|
||||
|
||||
transition(PlayStateInitializing);
|
||||
retryAttempts = 0;
|
||||
|
||||
// keep this after transition, because any transition clears this timer
|
||||
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
|
||||
transition(PlayStateInitializing);
|
||||
|
||||
// keep this after transition, because any transition clears this timer
|
||||
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +139,7 @@
|
|||
$audio.append(originalSource);
|
||||
audioDomElement = $audio.get(0);
|
||||
audioBind();
|
||||
logger.debug("recreated audio element ")
|
||||
logger.log("recreated audio element ")
|
||||
}
|
||||
|
||||
function clearBufferTimeout() {
|
||||
|
|
@ -143,7 +150,7 @@
|
|||
}
|
||||
|
||||
function transition(newState) {
|
||||
logger.debug("transitioning from " + playState + " to " + newState);
|
||||
logger.log("transitioning from " + playState + " to " + newState);
|
||||
|
||||
playState = newState;
|
||||
|
||||
|
|
@ -156,6 +163,7 @@
|
|||
playState == PlayStateSessionOver ||
|
||||
playState == PlayStateNetworkError ||
|
||||
playState == PlayStateServerError ) {
|
||||
$audio.unbind('canplay');
|
||||
context.JK.ListenBroadcastCurrentlyPlaying = null;
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +173,7 @@
|
|||
function noBuffer() {
|
||||
|
||||
if(retryAttempts >= RETRY_ATTEMPTS) {
|
||||
logger.debug("never received indication of buffering or playing");
|
||||
logger.log("never received indication of buffering or playing");
|
||||
transition(PlayStateFailedStart);
|
||||
}
|
||||
else {
|
||||
|
|
@ -173,20 +181,38 @@
|
|||
|
||||
clearBufferTimeout();
|
||||
|
||||
// tell audio to stop/start, in attempt to retry
|
||||
//audioDomElement.pause();
|
||||
audioDomElement.load();
|
||||
audioDomElement.play();
|
||||
checkServer()
|
||||
.done(function(response) {
|
||||
|
||||
transition(PlayStateRetrying);
|
||||
if(!response.mount) {
|
||||
transition(PlayStateSessionOver);
|
||||
destroy();
|
||||
}
|
||||
else {
|
||||
// tell audio to stop/start, in attempt to retry
|
||||
//audioDomElement.pause();
|
||||
audioDomElement.load();
|
||||
if(needsCanPlayGuard()) {
|
||||
$audio.bind('canplay', function() {
|
||||
audioDomElement.play();
|
||||
})
|
||||
}
|
||||
else {
|
||||
audioDomElement.play();
|
||||
}
|
||||
|
||||
transition(PlayStateRetrying);
|
||||
|
||||
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
|
||||
}
|
||||
})
|
||||
|
||||
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
function isNoisyEvent(eventName) {
|
||||
if(playState == PlayStateNone) {
|
||||
console.log("ignoring: " + eventName)
|
||||
logger.log("ignoring: " + eventName)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -199,21 +225,26 @@
|
|||
|
||||
function onPlaying() {
|
||||
if(isNoisyEvent('playing')) return;
|
||||
logger.debug("playing", arguments);
|
||||
logger.log("playing", arguments);
|
||||
|
||||
transition(PlayStatePlaying);
|
||||
}
|
||||
|
||||
function onPause() {
|
||||
if(isNoisyEvent('pause')) return;
|
||||
logger.debug("pause", arguments);
|
||||
logger.log("pause", arguments);
|
||||
|
||||
if(treatPauseLikeEnd()) {
|
||||
transition(PlayStateEnded);
|
||||
return;
|
||||
};
|
||||
|
||||
transition(PlayStateStalled);
|
||||
}
|
||||
|
||||
function onError() {
|
||||
if(isNoisyEvent('error')) return;
|
||||
logger.debug("error", arguments);
|
||||
logger.log("error", arguments);
|
||||
|
||||
if(playState == PlayStatePlaying || playState == PlayStateStalled) {
|
||||
transition(PlayStateFailedPlaying);
|
||||
|
|
@ -225,29 +256,31 @@
|
|||
|
||||
function onEnded() {
|
||||
if(isNoisyEvent('ended')) return;
|
||||
logger.debug("ended", arguments);
|
||||
logger.log("ended", arguments);
|
||||
|
||||
transition(PlayStateEnded);
|
||||
}
|
||||
|
||||
function onEmptied() {
|
||||
if(isNoisyEvent('emptied')) return;
|
||||
logger.debug("emptied", arguments);
|
||||
logger.log("emptied", arguments);
|
||||
}
|
||||
|
||||
function onAbort() {
|
||||
if(isNoisyEvent('abort')) return;
|
||||
logger.debug("abort", arguments);
|
||||
logger.log("abort", arguments);
|
||||
}
|
||||
|
||||
function onStalled() {
|
||||
if(isNoisyEvent('stalled')) return;
|
||||
logger.debug("stalled", arguments);
|
||||
logger.log("stalled", arguments);
|
||||
|
||||
if(arguments[0].target !== audioDomElement) {
|
||||
logger.debug("ignoring stalled msg for non-active audio element")
|
||||
logger.log("ignoring stalled msg for non-active audio element")
|
||||
return;
|
||||
}
|
||||
|
||||
if(ignoreStalls()) return;
|
||||
// fires in Chrome on page load
|
||||
|
||||
if(playState == PlayStateBuffering || playState == PlayStatePlaying) {
|
||||
|
|
@ -257,15 +290,17 @@
|
|||
|
||||
function onSuspend() {
|
||||
if(isNoisyEvent('suspend')) return;
|
||||
logger.debug("onsuspend", arguments);
|
||||
logger.log("onsuspend", arguments);
|
||||
|
||||
// fires in FF on page load
|
||||
|
||||
if(ignoreSuspend()) return;
|
||||
|
||||
transition(PlayStateStalled);
|
||||
}
|
||||
|
||||
function onTimeUpdate() {
|
||||
//logger.debug("ontimeupdate", arguments);
|
||||
//logger.log("ontimeupdate", arguments);
|
||||
}
|
||||
|
||||
function onProgress() {
|
||||
|
|
@ -368,6 +403,38 @@
|
|||
}
|
||||
}
|
||||
|
||||
function treatPauseLikeEnd() {
|
||||
// never see a pause event until the session is over, in the rich client
|
||||
return playState == PlayStatePlaying && navigator.userAgent.toLowerCase().indexOf('jamkazam') > -1;
|
||||
}
|
||||
function ignoreSuspend() {
|
||||
// client always does a 'suspend' after playing. bleh
|
||||
return playState == PlayStatePlaying && navigator.userAgent.toLowerCase().indexOf('jamkazam') > -1;
|
||||
}
|
||||
|
||||
function ignoreStalls() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function needsCanPlayGuard() {
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (ua.indexOf('safari') != -1) {
|
||||
if (ua.indexOf('chrome') > -1) {
|
||||
} else {
|
||||
if (ua.indexOf('ipad') > -1 || ua.indexOf('iphone') > -1) {
|
||||
return false; // not sure yet which way this should go
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(ua.indexOf('jamkazam') > -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function audioBind() {
|
||||
$audio.bind('play', onPlay);
|
||||
$audio.bind('playing', onPlaying);
|
||||
|
|
@ -380,8 +447,8 @@
|
|||
$audio.bind('stalled', onStalled);
|
||||
//$audio.bind('timeupdate', onTimeUpdate);
|
||||
$audio.bind('progress', onProgress);
|
||||
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
|
||||
musicSessionId = $parent.attr('data-music-session');
|
||||
|
|
@ -394,7 +461,7 @@
|
|||
$audio = $('audio', $parent);
|
||||
|
||||
if($audio.length == 0) {
|
||||
logger.debug("listen_broadcast: no audio element. deactivating")
|
||||
logger.log("listen_broadcast: no audio element. deactivating")
|
||||
return;
|
||||
}
|
||||
if($audio.length > 1) {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@
|
|||
text-align: center;
|
||||
@include border_box_sizing;
|
||||
height: 36px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.recording-controls {
|
||||
margin-top: 15px;
|
||||
padding: 3px 5px 3px 10px;
|
||||
|
|
@ -35,6 +37,10 @@
|
|||
|
||||
.play-button {
|
||||
outline: 0;
|
||||
// the following 3 properties were to make safari on iOS not wrap text after the .play-button float:left was preferred
|
||||
position:absolute;
|
||||
left:5px;
|
||||
top:7px;
|
||||
}
|
||||
|
||||
&.no-mount{
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@ class ApiIcecastController < ApiController
|
|||
remote_ip = params[:ip]
|
||||
remote_user_agent = params[:agent]
|
||||
|
||||
mount = IcecastMount.find_by_name!(@mount_id)
|
||||
mount.listener_add
|
||||
mount = IcecastMount.find_by_name(@mount_id)
|
||||
|
||||
mount.listener_add if mount
|
||||
|
||||
render text: '', :status => :ok
|
||||
end
|
||||
|
|
@ -39,8 +40,8 @@ class ApiIcecastController < ApiController
|
|||
pass = params[:pass]
|
||||
duration = params[:duration] # seconds connected to the listen stream
|
||||
|
||||
mount = IcecastMount.find_by_name!(@mount_id)
|
||||
mount.listener_remove
|
||||
mount = IcecastMount.find_by_name(@mount_id)
|
||||
mount.listener_remove if mount
|
||||
|
||||
render text: '', :status => :ok
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,14 @@ object @music_session
|
|||
if !current_user
|
||||
# there should be more data returned, but we need to think very carefully about what data is public for a music session
|
||||
attributes :id
|
||||
|
||||
# only show mount info if fan_access is public. Eventually we'll also need to show this in other scenarios, like if invited
|
||||
child({:mount => :mount}, :if => lambda { |music_session| music_session.fan_access}) {
|
||||
attributes :id, :name, :sourced, :listeners, :bitrate, :subtype, :url
|
||||
node(:mime_type) { |mount| mount.resolve_string(:mime_type) }
|
||||
node(:bitrate) { |mount| mount.resolve_string(:bitrate) }
|
||||
node(:subtype) { |mount| mount.resolve_string(:subtype) }
|
||||
}
|
||||
else
|
||||
|
||||
attributes :id, :description, :musician_access, :approval_required, :fan_access, :fan_chat, :band_id, :user_id, :claimed_recording_initiator_id, :track_changes_counter
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
- if feed_item.has_mount?
|
||||
%audio{preload: 'none'}
|
||||
%source{src: feed_item.music_session.mount.url, type: feed_item.music_session.mount.resolve_string(:mime_type)}
|
||||
.session-status
|
||||
%span.session-status
|
||||
= session_text(feed_item)
|
||||
/ current playback time
|
||||
= session_duration(feed_item, class: 'session-duration tick-duration recording-current', 'data-created-at' => feed_item.created_at.to_i)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ unless $rails_rake_task
|
|||
:port => APP_CONFIG.websocket_gateway_port,
|
||||
:emwebsocket_debug => APP_CONFIG.websocket_gateway_internal_debug,
|
||||
:connect_time_stale => APP_CONFIG.websocket_gateway_connect_time_stale,
|
||||
:connect_time_expire => APP_CONFIG.websocket_gateway_connect_time_expire)
|
||||
:connect_time_expire => APP_CONFIG.websocket_gateway_connect_time_expire,
|
||||
:rabbitmq_host => APP_CONFIG.rabbitmq_host,
|
||||
:rabbitmq_port => APP_CONFIG.rabbitmq_port)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,4 +48,6 @@ Object.send(:remove_const, :Rails) # this is to 'fool' new relic into not thinki
|
|||
Server.new.run(:port => config["port"],
|
||||
:emwebsocket_debug => config["emwebsocket_debug"],
|
||||
:connect_time_stale => config["connect_time_stale"],
|
||||
:connect_time_expire => config["connect_time_expire"])
|
||||
:connect_time_expire => config["connect_time_expire"],
|
||||
:rabbitmq_host => config['rabbitmq_host'],
|
||||
:rabbitmq_port => config['rabbitmq_port'])
|
||||
|
|
|
|||
|
|
@ -6,14 +6,20 @@ development:
|
|||
port: 6767
|
||||
verbose: true
|
||||
emwebsocket_debug: false
|
||||
rabbitmq_host: localhost
|
||||
rabbitmq_port: 5672
|
||||
<<: *defaults
|
||||
|
||||
test:
|
||||
port: 6769
|
||||
verbose: true
|
||||
rabbitmq_host: localhost
|
||||
rabbitmq_port: 5672
|
||||
<<: *defaults
|
||||
|
||||
production:
|
||||
port: 6767
|
||||
verbose: false
|
||||
verbose: false
|
||||
rabbitmq_host: localhost
|
||||
rabbitmq_port: 5672
|
||||
<<: *defaults
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ module JamWebsockets
|
|||
port = options[:port]
|
||||
connect_time_stale = options[:connect_time_stale].to_i
|
||||
connect_time_expire = options[:connect_time_expire].to_i
|
||||
rabbitmq_host = options[:rabbitmq_host]
|
||||
rabbitmq_port = options[:rabbitmq_port].to_i
|
||||
|
||||
@log.info "starting server #{host}:#{port} with staleness_time=#{connect_time_stale}; reconnect time = #{connect_time_expire}"
|
||||
@log.info "starting server #{host}:#{port} staleness_time=#{connect_time_stale}; reconnect time = #{connect_time_expire}, rabbitmq=#{rabbitmq_host}:#{rabbitmq_port}"
|
||||
|
||||
EventMachine.error_handler{|e|
|
||||
@log.error "unhandled error #{e}"
|
||||
|
|
@ -26,7 +28,7 @@ module JamWebsockets
|
|||
}
|
||||
|
||||
EventMachine.run do
|
||||
@router.start(connect_time_stale) do
|
||||
@router.start(connect_time_stale, host: rabbitmq_host, port: rabbitmq_port) do
|
||||
# take stale off the expire limit because the call to stale will
|
||||
# touch the updated_at column, adding an extra stale limit to the expire time limit
|
||||
# expire_time = connect_time_expire > connect_time_stale ? connect_time_expire - connect_time_stale : connect_time_expire
|
||||
|
|
|
|||
Loading…
Reference in New Issue