* recording widget working on home page VRFS-1264

This commit is contained in:
Seth Call 2014-03-05 00:15:46 -06:00
parent 5f67ad3290
commit db15ec0a66
6 changed files with 129 additions and 34 deletions

View File

@ -9,6 +9,11 @@
var $description = $('.description', $feedItem);
var $musicians = $('.musician-detail', $feedItem);
var $controls = $('.recording-controls', $feedItem);
var $sliderBar = $('.recording-position', $feedItem);
var $statusBar = $('.recording-status', $feedItem);
var $currentTime = $('.recording-current', $feedItem);
var $status = $('.status-text', $feedItem);
var $playButton = $('.play-button', $feedItem);
var playing = false;
var toggledOpen = false;
@ -44,6 +49,13 @@
function stateChange(e, data) {
if(data.isEnd) stopPlay();
if(data.isError) {
$sliderBar.hide();
$playButton.hide();
$currentTime.hide();
$statusBar.show();
$status.text(data.displayText);
}
}
function toggleDetails() {

View File

@ -20,9 +20,10 @@
var self = this;
var waitForBufferingTimeout = null;
var destroyed = false;
var lastTime = 0;
var lastTime = -1;
var dragging = false;
var loaded = null;
var isPlaying = false;
var PlayStateNone = 'none';
var PlayStateInitializing = 'initializing'; // user clicked play--nothing has happened yet
@ -39,9 +40,18 @@
var canPlay = false;
function waitForLoaded() {
if(!loaded) {
if(needsReloadOnEveryPlay() || !loaded) {
loaded = $.Deferred();
audioDomElement.load();
if(supportsLoadBeforePlay()) {
audioDomElement.load();
}
else {
audioDomElement.play();
audioDomElement.pause();
//loaded.resolve();
}
}
return loaded;
@ -57,15 +67,15 @@
if(!audioDomElement) throw "no audio element supplied; the user should not be able to attempt a play"
waitForLoaded.done(function() {
audioDomElement.currentTime = lastTime;
transition(PlayStateInitializing);
// keep this after transition, because any transition clears this timer
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
waitForLoaded().done(function() {
if(lastTime > -1) {audioDomElement.currentTime = lastTime;}
audioDomElement.play();
transition(PlayStateInitializing);
// keep this after transition, because any transition clears this timer
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
isPlaying = true;
})
}
function pause(e) {
@ -81,7 +91,7 @@
transition(PlayStateNone);
audioDomElement.pause();
//recreateAudioElement();
isPlaying = false;
}
function destroy() {
@ -96,6 +106,7 @@
function noBuffer() {
logger.debug("never received indication of buffering or playing");
alert("never received indication of buffering or playing");
transition(PlayStateFailedStart);
}
@ -125,9 +136,20 @@
function transition(newState) {
logger.debug("transitioning from " + playState + " to " + newState);
if(playState != PlayStateInitializing) {
clearBufferTimeout();
}
playState = newState;
clearBufferTimeout();
// sometimes browsers don't quite make it to 100% if we end at 99%, reset it
var percentComplete = (audioDomElement.currentTime / audioDomElement.duration) * 100;
if(playState == PlayStateEnded && percentComplete > 99) {
updateSliderPosition(0);
$currentTime.html("0:00");
lastTime = 0
}
if( playState == PlayStateNone ||
playState == PlayStateEnded ||
@ -135,6 +157,7 @@
playState == PlayStateFailedPlaying ||
playState == PlayStateNetworkError) {
context.JK.ListenBroadcastCurrentlyPlaying = null;
isPlaying = false;
}
triggerStateChange();
@ -143,7 +166,7 @@
function isNoisyEvent(eventName) {
if(playState == PlayStateNone) {
console.log("ignoring: " + eventName)
logger.log("ignoring: " + eventName)
return true;
}
@ -165,6 +188,11 @@
if(isNoisyEvent('pause')) return;
logger.debug("pause", arguments);
if(treatPauseLikeEnd()) {
transition(PlayStateEnded);
return;
};
transition(PlayStateStalled);
}
@ -176,6 +204,7 @@
transition(PlayStateFailedPlaying);
}
else {
alert("ON ERROR")
transition(PlayStateFailedStart);
}
}
@ -195,6 +224,8 @@
function onAbort() {
if(isNoisyEvent('abort')) return;
logger.debug("abort", arguments);
transition(PlayStateFailedStart);
}
function onStalled() {
@ -212,8 +243,6 @@
if(isNoisyEvent('suspend')) return;
logger.debug("onsuspend", arguments);
// fires in FF on page load
transition(PlayStateStalled);
}
@ -239,7 +268,7 @@
}
function updateSliderPosition(percent) {
console.log("updateSliderPosition", percent)
//logger.log("updateSliderPosition", percent)
$slider.css({'left': percent + '%'});
}
@ -261,7 +290,10 @@
var percent = ui.position.left / $sliderBar.width() * 100;
updateSliderPosition(percent);
audioDomElement.currentTime = percent * audioDomElement.duration;
waitForLoaded()
.done(function() {
audioDomElement.currentTime = percent * audioDomElement.duration / 100;
});
}
function onDrag(e, ui) {
@ -273,6 +305,7 @@
var isEnd = false;
var displayText = null;
var refresh = false;
var isError = false;
if(playState == 'none') {
//$status.text('SESSION IN PROGRESS');
@ -296,14 +329,17 @@
else if(playState == 'failed_start') {
displayText = 'AUDIO DID NOT START';
isEnd = true;
isError = true;
}
else if(playState == 'failed_playing') {
displayText = 'STREAM DISCONNECTED';
isEnd = true;
isError = true;
}
else if(playState == 'network_error') {
displayText = 'NO NETWORK';
isEnd = true;
isError = true;
}
else {
logger.error("unknown state: " + playState)
@ -313,10 +349,24 @@
{
state: playState,
displayText: displayText,
isEnd: isEnd
isEnd: isEnd,
isError: isError
})
}
function supportsLoadBeforePlay() {
// firefox does not need you to call .load to mess with currentTime
return !(navigator.userAgent.toLowerCase().indexOf('firefox') > -1);
}
function needsReloadOnEveryPlay() {
return navigator.userAgent.toLowerCase().indexOf('jamkazam') > -1;
}
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 audioBind() {
$audio.bind('play', onPlay);
$audio.bind('playing', onPlaying);
@ -343,7 +393,6 @@
$audio = $('audio', $parent);
if($audio.length == 0) {
logger.debug("listen_recording: no audio element. deactivating")
return;
}
if($audio.length > 1) {
@ -361,9 +410,11 @@
var offset = e.pageX - $(this).offset().left;
var percent = offset / $sliderBar.width() * 100;
updateSliderPosition(percent);
audioDomElement.currentTime = percent * audioDomElement.duration;
waitForLoaded()
.done(function() {
audioDomElement.currentTime = percent / 100 * audioDomElement.duration;
if(isPlaying) audioDomElement.play();
})
return false;
});

View File

@ -280,9 +280,6 @@
return;
}
if(ignoreStalls()) return;
// fires in Chrome on page load
if(playState == PlayStateBuffering || playState == PlayStatePlaying) {
transition(PlayStateStalled);
}
@ -412,10 +409,6 @@
return playState == PlayStatePlaying && navigator.userAgent.toLowerCase().indexOf('jamkazam') > -1;
}
function ignoreStalls() {
return false;
}
function needsCanPlayGuard() {
var ua = navigator.userAgent.toLowerCase();
@ -461,7 +454,6 @@
$audio = $('audio', $parent);
if($audio.length == 0) {
logger.log("listen_broadcast: no audio element. deactivating")
return;
}
if($audio.length > 1) {

View File

@ -563,7 +563,6 @@
var mixerIds = context.jamClient.SessionGetIDs();
var holder = $.extend(true, {}, {mixers: context.jamClient.SessionGetControlState(mixerIds)});
mixers = holder.mixers;
// Always add a hard-coded simplified 'mixer' for the L2M mix
var l2m_mixer = {
id: '__L2M__',
@ -894,6 +893,7 @@
if (mixer.mute) {
muteClass = "muted";
}
trackData.gainPercent = gainPercent;
trackData.muteClass = muteClass;
trackData.mixerId = mixer.id;
@ -968,6 +968,7 @@
var gainPercent = percentFromMixerValue(
mixer.range_low, mixer.range_high, mixer.volume_left);
var trackSelector = 'div.track[track-id="' + key + '"]';
connectTrackToMixer(trackSelector, key, mixer.id, gainPercent);
var $track = $('div.track[client-id="' + clientId + '"]');
$track.find('.track-icon-mute').attr('mixer-id', mixer.id);
@ -1033,7 +1034,6 @@
var parentSelector = '#session-mytracks-container';
var $destination = $(parentSelector);
if (trackData.clientId !== app.clientId) {
console.log("ADDING REMOTE TRACK: noaudio", trackData.noaudio)
parentSelector = '#session-livetracks-container';
$destination = $(parentSelector);
$('.session-livetracks .when-empty').hide();

View File

@ -26,6 +26,38 @@
text-align: center;
@include border_box_sizing;
height: 36px;
.recording-status {
font-size:15px;
}
.recording-status .recording-duration {
font-family:Arial, Helvetica, sans-serif;
display:inline-block;
font-size:18px;
float:right;
top:3px;
right:4px;
}
&.has-mix {
.recording-status {
display:none;
}
}
&.no-mix {
.play-button {
display:none;
}
.recording-current {
display:none;
}
.recording-position {
display:none;
}
}
}
@ -101,6 +133,10 @@
.recording-time {
display:inline;
vertical-align:top;
time {
vertical-align:top;
}
}
}
}

View File

@ -1,4 +1,4 @@
.feed-entry.recording-entry
.feed-entry.recording-entry{id: feed_item.id, candidate_claimed_recording_id: feed_item.candidate_claimed_recording.id}
/ avatar
.avatar-small.ib
= recording_avatar(feed_item)
@ -17,7 +17,7 @@
/ timeline and controls
.right.w40
/ recording play controls
.recording-controls
.recording-controls{ class: feed_item.candidate_claimed_recording.has_mix? ? 'has-mix' : 'no-mix'}
/ play button
%a.left.play-button{:href => "#"}
= image_tag 'content/icon_playbutton.png', width:20, height:20, class:'play-icon'
@ -25,6 +25,10 @@
%audio{preload: 'none'}
%source{src: claimed_recording_download_url(feed_item.candidate_claimed_recording.id, 'mp3'), type:'audio/mpeg'}
%source{src: claimed_recording_download_url(feed_item.candidate_claimed_recording.id, 'ogg'), type:'audio/ogg'}
.recording-status
%span.status-text STILL MIXING
.recording-duration
= recording_duration(feed_item)
/ playback position
.recording-position
/ start time