* some more fixes for broadcasting - VRFS-2523

This commit is contained in:
Seth Call 2015-01-02 15:29:31 -06:00
parent 82b7c005ec
commit 5f14f73322
5 changed files with 91 additions and 83 deletions

View File

@ -33,6 +33,7 @@
context.JK.ListenBroadcast = function($parentElement, options){
var WAIT_FOR_BUFFER_TIMEOUT = 5000;
var WAIT_FOR_PLAYING_TIMEOUT = 7000;
var RETRY_ATTEMPTS = 5; // we try 4 times, so the user will wait up until RETRY_ATTEMPTS * WAIT_FOR_BUFFER_TIMEOUTS
var logger = context.JK.logger;
@ -42,6 +43,7 @@
var audioDomElement = null;
var musicSessionId = null;
var waitForBufferingTimeout = null;
var waitForPlayingTimeout = null;
var fanAccess = null;
var audioSrc = null;
var audioType = null;
@ -49,6 +51,7 @@
var self = this;
var mountInfo = null;
var $mountState = null;
var sessionInfo = null; // stored so we can access .mount, mostly
var lazyAudioInit = options && options.lazyAudioInit;
var hoverOptions = (options && options.hoverOptions) ? options.hoverOptions : {}
var $detailHelper = options && options.detailHelper;
@ -77,21 +80,7 @@
e.stopPropagation();
}
if(lazyAudioInit) {
if($audio.length == 0) {
$audio =
$('<audio preload="none">' +
'<source src="' + cacheBustedSrc(audioSrc) + '" type="' + audioType + '" data-audio-src="' + audioSrc + '" />' +
'</audio>')
$parent.append($audio)
audioDomElement = $audio.get(0);
audioBind();
}
}
if(destroyed) return;
if(!audioDomElement) throw "no audio element supplied; the user should not be able to attempt a play"
//if(destroyed) return;
if(context.JK.ListenBroadcastCurrentlyPlaying) {
context.JK.ListenBroadcastCurrentlyPlaying.forcedPause();
@ -102,20 +91,33 @@
checkServer()
.done(function(response) {
if(!response.mount) {
if(!sessionInfo.mount) {
transition(PlayStateSessionOver);
destroy();
}
else {
audioDomElement.play();
recreateAudioElement();
retryAttempts = 0;
audioDomElement.load();
transition(PlayStateInitializing);
retryAttempts = 0;
transition(PlayStateInitializing);
// keep this after transition, because any transition clears this timer
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
logger.debug("setting buffering timeout");
rest.addPlayablePlay(musicSessionId, 'JamRuby::MusicSession', null, context.JK.currentUserId);
if(needsCanPlayGuard()) {
$audio.bind('canplay', function() {
audioDomElement.play();
})
}
else {
audioDomElement.play();
}
// keep this after transition, because any transition clears this timer
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
rest.addPlayablePlay(musicSessionId, 'JamRuby::MusicSession', null, context.JK.currentUserId);
}
})
}
@ -131,9 +133,7 @@
e.stopPropagation();
}
if(destroyed) return;
if(!lazyAudioInit && !audioDomElement) throw "no audio element supplied; the user should not be able to attempt a pause"
//if(destroyed) return;
transition(PlayStateNone);
@ -141,12 +141,13 @@
}
function destroy() {
if(!destroyed) {
$audio.remove();
$audio = null;
audioDomElement = null;
destroyed = true;
}
// if(!destroyed) {
//$audio.remove();
//$audio = null;
//audioDomElement = null;
recreateAudioElement()
// destroyed = true;
//}
}
function onScreenChanged(e, data) {
@ -155,36 +156,49 @@
}
}
function createAudioElementHtml() {
if (sessionInfo == null) throw "no session info";
if (sessionInfo.mount == null) throw "no session mount info";
$audio =
$('<audio preload="none">' +
'<source src="' + cacheBustedSrc(sessionInfo.mount.url) + '" type="' + sessionInfo.mount.mime_type + '"/>' +
'</audio>')
$parent.append($audio)
audioDomElement = $audio.get(0);
audioBind();
}
// this is the only way to make audio stop buffering after the user hits pause
function recreateAudioElement() {
// jeez: http://stackoverflow.com/questions/4071872/html5-video-force-abort-of-buffering/13302599#13302599
var originalSource = $audio.html()
audioDomElement.pause();
audioDomElement.src = '';
audioDomElement.load();
var $parent = $audio.parent();
if(audioDomElement) {
audioDomElement.pause();
audioDomElement.src = '';
audioDomElement.load();
}
$audio.remove();
$audio = $('<audio preload="none"></audio>')
$audio.append(originalSource);
var $sources = $audio.find('source')
$.each($sources, function(i, source) {
var $source = $(source);
var bustedSource = cacheBustedSrc($source.attr('data-audio-src'))
$source.attr('src', bustedSource)
})
$parent.append($audio);
audioDomElement = $audio.get(0);
audioBind();
createAudioElementHtml();
logger.log("recreated audio element ")
}
function clearBufferTimeout() {
if(waitForBufferingTimeout) {
logger.debug("clearing buffering timeout");
clearTimeout (waitForBufferingTimeout);
waitForBufferingTimeout = null;
}
}
function clearPlayingTimeout() {
if(waitForPlayingTimeout) {
logger.debug("clearing playing timeout");
clearTimeout (waitForPlayingTimeout);
waitForPlayingTimeout = null;
}
}
function transition(newState) {
logger.log("transitioning from " + playState + " to " + newState);
@ -192,8 +206,15 @@
if(newState != PlayStateStalled) {
clearBufferTimeout();
clearPlayingTimeout();
}
if(newState == PlayStateBuffering) {
// give some time after buffering is seen to let play start
waitForPlayingTimeout = setTimeout(noPlay, WAIT_FOR_PLAYING_TIMEOUT)
}
if( playState == PlayStateNone ||
playState == PlayStateEnded ||
playState == PlayStateFailedStart ||
@ -208,6 +229,9 @@
triggerStateChange();
}
function noPlay() {
noBuffer();
}
function noBuffer() {
waitForBufferingTimeout = null;
@ -224,7 +248,7 @@
checkServer()
.done(function(response) {
if(!response.mount) {
if(!sessionInfo.mount) {
transition(PlayStateSessionOver);
destroy();
}
@ -353,6 +377,10 @@
function checkServer() {
return rest.getSession(musicSessionId)
.done(function(response) {
console.log("assigning sessionInfo")
sessionInfo = response;
})
.fail(function(jqXHR) {
if(jqXHR.status == 404 || jqXHR.status == 403) {
transition(PlayStateSessionOver);
@ -454,7 +482,7 @@
if(refresh) {
checkServer()
.done(function(response) {
if(!response.mount) {
if(!sessionInfo.mount) {
transition(PlayStateSessionOver);
destroy();
}})
@ -649,7 +677,7 @@
function openBubble() {
checkServer().done(function(response) {
var mountId = response.mount ? response.mount.id : null
var mountId = sessionInfo.mount ? sessionInfo.mount.id : null
if(mountId) {
rest.getMount({id: mountId})
@ -705,7 +733,6 @@
function initialize() {
musicSessionId = $parent.attr('data-music-session');
if(!musicSessionId) throw "data-music-session must be specified on $parentElement";
@ -713,14 +740,6 @@
if(fanAccess === null) throw 'fan-access must be specified in $parentElement';
fanAccess = $parent.attr('fan-access') === 'true' // coerce to boolean
if(lazyAudioInit) {
// save the original src element (without any cache bust)
audioSrc = $parent.attr('data-audio-src');
if(audioSrc === null) throw 'data-audio-src must be specified in $parentElement';
audioType = $parent.attr('data-audio-type');
if(audioType === null) throw 'data-audio-type must be specified in $parentElement';
}
bindHoverDetail();
$audio = $('audio', $parent);
@ -733,21 +752,6 @@
throw "more than one <audio> element found";
}
if(!lazyAudioInit) {
var $sources = $audio.find('source')
$.each($sources, function(i, source) {
var $source = $(source);
// save original src value (before cache bust)
$source.attr('data-audio-src', $source.attr('src'))
var bustedSource = cacheBustedSrc($source.attr('data-audio-src'))
$source.attr('src', bustedSource)
})
audioDomElement = $audio.get(0);
audioBind();
}
$parent.bind('play.listenBroadcast', play);
$parent.bind('pause.listenBroadcast', pause);
$parent.bind('destroy.listenBroadcast', destroy);

View File

@ -41,7 +41,8 @@
}
if(data.isEnd) {
$listenText.text('Listen').removeClass('statusing')
//$listenDetails.removeClass('statusing')
//$listenText.text('Listen')
stopPlay($listenLink);
}

View File

@ -73,14 +73,17 @@
}
function startPlay() {
var img = $('.play-icon');
logger.debug("user initiated play")
var img = $('.play-icon', $playButton);
img.attr('src', '/assets/content/icon_pausebutton.png');
$controls.trigger('play.listenBroadcast');
playing = true;
}
function stopPlay() {
var img = $('.play-icon');
logger.debug("user initiated pause")
var img = $('.play-icon', $playButton);
$status.text('LIVE SESSION IN PROGRESS')
img.attr('src', '/assets/content/icon_playbutton.png');
$controls.trigger('pause.listenBroadcast');
playing = false;
@ -98,7 +101,7 @@
}
function initialize(musicSessionId) {
$controls = $('.sessions-page .recording-controls');
$controls = $('.sessions-page .session-controls');
$status = $('.sessions-page .session-status')
$('.timeago').timeago();
@ -106,7 +109,7 @@
$controls.bind('statechange.listenBroadcast', stateChange);
context.JK.prettyPrintElements($('time.duration').show());
context.JK.TickDuration(null);
$playButton.click(startPlay);
$playButton.click(togglePlay);
sessionId = musicSessionId;
@ -130,7 +133,7 @@
$("#btnLike").click(like);
$playButton.trigger('click');
startPlay();
pollForUpdates(musicSessionId);
}

View File

@ -1,6 +1,6 @@
@import "client/common.css.scss";
.feed-entry .recording-controls, .feed-entry .session-controls, .landing-details .recording-controls {
.feed-entry .recording-controls, .feed-entry .session-controls, .landing-details .recording-controls, .landing-details .session-controls {
margin-top:0px;
margin-bottom:5px;
padding:8px 5px 8px 10px;
@ -8,7 +8,7 @@
position:relative;
}
.landing-details .recording-controls, .landing-details .recording-controls {
.landing-details .recording-controls, .landing-details .session-controls {
background-color:#242323;

View File

@ -53,7 +53,7 @@
<% end %>
<br clear="all" />
<div class="w100">
<div class="recording-controls <%= @music_session.is_over? ? 'ended' : 'inprogress' %>" data-music-session="<%=@music_session.id %>">
<div class="session-controls <%= @music_session.is_over? ? 'ended' : 'inprogress' %>" data-music-session="<%=@music_session.id %>">
<a class="left play-button" href="#">
<%= image_tag 'content/icon_pausebutton.png', width:20, height:20, class:'play-icon' %>
<% if @music_session.active_music_session && @music_session.active_music_session.mount %>