/** * Playback widget (play, pause , etc) */ (function(context, $) { "use strict"; var PlaybackMode = { NoPlayback: 0, EveryWhere: 1, PrivatePreview: 2, PreviewToAll: 3, LastPbMode: 4 }; context.JK = context.JK || {}; context.JK.PlaybackControls = function($parentElement, options){ options = $.extend(false, {playmodeControlsVisible:false}, options); var logger = context.JK.logger; if($parentElement.length == 0) { logger.debug("no $parentElement specified in PlaybackControls"); } var $playButton = $('.play-button img.playbutton', $parentElement); var $pauseButton = $('.play-button img.pausebutton', $parentElement); var $currentTime = $('.recording-current', $parentElement); var $duration = $('.duration-time', $parentElement); var $sliderBar = $('.recording-playback', $parentElement); var $slider = $('.recording-slider', $parentElement); var $playmodeButton = $('.playback-mode-buttons.icheckbuttons input', $parentElement); var $self = $(this); var playbackPlaying = false; var playbackDurationMs = 0; var playbackPositionMs = 0; var durationChanged = false; var endReached = false; var dragging = false; var playingWhenDragStart = false; var draggingUpdateTimer = null; var canUpdateBackend = false; var playbackMode = PlaybackMode.EveryWhere; var monitorPlaybackTimeout = null; function startPlay() { updateIsPlaying(true); if(endReached) { update(0, playbackDurationMs, playbackPlaying); } $self.triggerHandler('play', {playbackMode: playbackMode}); } function stopPlay() { updateIsPlaying(false); $self.triggerHandler('pause'); } function updateOffsetBasedOnPosition(offsetLeft) { var sliderBarWidth = $sliderBar.width(); playbackPositionMs = parseInt((offsetLeft / sliderBarWidth) * playbackDurationMs); updateCurrentTimeText(playbackPositionMs); if(canUpdateBackend) { $self.triggerHandler('change-position', {positionMs: playbackPositionMs}); canUpdateBackend = false; } } function startDrag(e, ui) { dragging = true; playingWhenDragStart = playbackPlaying; draggingUpdateTimer = setInterval(function() { canUpdateBackend = true; }, 333); // only call backend up to 3 times a second while dragging if(playingWhenDragStart) { stopPlay(); } } function stopDrag(e, ui) { dragging = false; clearInterval(draggingUpdateTimer); canUpdateBackend = true; updateOffsetBasedOnPosition(ui.position.left); if(playingWhenDragStart) { playingWhenDragStart = false; startPlay(); } } function onDrag(e, ui) { updateOffsetBasedOnPosition(ui.position.left); } $playButton.on('click', function(e) { startPlay(); return false; }); $pauseButton.on('click', function(e) { stopPlay(); return false; }); $sliderBar.on('click', function(e) { var offset = e.pageX - $(this).offset().left; canUpdateBackend = true; updateOffsetBasedOnPosition(offset); updateSliderPosition(playbackPositionMs); return false; }); $slider.draggable({ axis: 'x', containment: $sliderBar, start: startDrag, stop: stopDrag, drag: onDrag }); if(options.playmodeControlsVisible) { $('.playback-mode-buttons.icheckbuttons', $parentElement).show(); } $playmodeButton.iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal', inheritClass: true }); $playmodeButton.on('ifChecked', function(e) { var playmode = $(this).val(); console.log("set new playmode", playmode); setPlaybackMode(playmode); }); function monitorRecordingPlayback() { var isPlaying = context.jamClient.isSessionTrackPlaying(); var positionMs = context.jamClient.SessionCurrrentPlayPosMs(); var durationMs = context.jamClient.SessionGetTracksPlayDurationMs(); update(positionMs, durationMs, isPlaying); monitorPlaybackTimeout = setTimeout(monitorRecordingPlayback, 500); } function update(currentTimeMs, durationTimeMs, isPlaying) { if(dragging) { return; } // at the end of the play, the duration sets to 0, as does currentTime. but isPlaying does not reset to console.log("currentTimeMs, durationTimeMs", currentTimeMs, durationTimeMs); if(currentTimeMs == 0 && durationTimeMs == 0) { if(isPlaying) { isPlaying = false; durationTimeMs = playbackDurationMs; currentTimeMs = playbackDurationMs; stopPlay(); endReached = true; console.log("end reached"); } else { return; } } updateDurationTime(durationTimeMs); updateCurrentTime(currentTimeMs); updateIsPlaying(isPlaying); durationChanged = false; } function updateDurationTime(timeMs) { if(timeMs != playbackDurationMs) { $duration.text(context.JK.prettyPrintSeconds(parseInt(timeMs / 1000))); playbackDurationMs = timeMs; durationChanged = true; } } function updateCurrentTimeText(timeMs) { $currentTime.text(context.JK.prettyPrintSeconds(parseInt(timeMs / 1000))); } function updateSliderPosition(timeMs) { var slideWidthPx = $sliderBar.width(); var xPos = Math.ceil(timeMs / playbackDurationMs * slideWidthPx); $slider.css('left', xPos); } function updateCurrentTime(timeMs) { if(timeMs != playbackPositionMs || durationChanged) { updateCurrentTimeText(timeMs); updateSliderPosition(timeMs); playbackPositionMs = timeMs; } } function updateIsPlaying(isPlaying) { if(isPlaying != playbackPlaying) { if(isPlaying) { $playButton.hide(); $pauseButton.show(); } else { $playButton.show(); $pauseButton.hide(); } playbackPlaying = isPlaying; } } function setPlaybackMode(mode) { if(mode == 'preview-to-all') { playbackMode = PlaybackMode.PreviewToAll; } else if(mode == 'preview-to-me') { playbackMode = PlaybackMode.PrivatePreview; } else if(mode == 'eveywhere') { playbackMode = PlaybackMode.EveryWhere; } else { logger.error("unable to set playback mode", mode); } // let the mode change immediately affect the behavior of the stream if(playbackPlaying) { stopPlay(); startPlay(); } } function startMonitor() { monitorRecordingPlayback(); } function stopMonitor() { if(monitorPlaybackTimeout!= null) { clearTimeout(monitorPlaybackTimeout); monitorPlaybackTimeout = null; } } this.update = update; this.setPlaybackMode = setPlaybackMode; this.startMonitor = startMonitor; this.stopMonitor = stopMonitor; return this; } })(window, jQuery);