/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ (function initExamplePlayer() { /** * The URL of the Guacamole session recording which should be played back. * * @constant * @type String */ var RECORDING_URL = 'recording.guac'; /** * The element representing the session recording player. * * @type Element */ var player = document.getElementById('player'); /** * The element which will contain the recording display. * * @type Element */ var display = document.getElementById('display'); /** * Play/pause toggle button. * * @type Element */ var playPause = document.getElementById('play-pause'); /** * Button for cancelling in-progress seek operations. * * @type Element */ var cancelSeek = document.getElementById('cancel-seek'); /** * Text status display indicating the current playback position within the * recording. * * @type Element */ var position = document.getElementById('position'); /** * Slider indicating the current playback position within the recording, * and allowing the user to change the playback position. * * @type Element */ var positionSlider = document.getElementById('position-slider'); /** * Text status display indicating the current length of the recording. * * @type Element */ var duration = document.getElementById('duration'); /** * The tunnel which should be used to download the Guacamole session * recording. * * @type Guacamole.Tunnel */ var tunnel = new Guacamole.StaticHTTPTunnel(RECORDING_URL); /** * Guacamole.SessionRecording instance to be used to playback the session * recording. * * @type Guacamole.SessionRecording */ var recording = new Guacamole.SessionRecording(tunnel); /** * The Guacamole.Display which displays the recording during playback. * * @type Guacamole.Display */ var recordingDisplay = recording.getDisplay(); /** * Converts the given number to a string, adding leading zeroes as necessary * to reach a specific minimum length. * * @param {Numer} num * The number to convert to a string. * * @param {Number} minLength * The minimum length of the resulting string, in characters. * * @returns {String} * A string representation of the given number, with leading zeroes * added as necessary to reach the specified minimum length. */ var zeroPad = function zeroPad(num, minLength) { // Convert provided number to string var str = num.toString(); // Add leading zeroes until string is long enough while (str.length < minLength) str = '0' + str; return str; }; /** * Converts the given millisecond timestamp into a human-readable string in * MM:SS format. * * @param {Number} millis * An arbitrary timestamp, in milliseconds. * * @returns {String} * A human-readable string representation of the given timestamp, in * MM:SS format. */ var formatTime = function formatTime(millis) { // Calculate total number of whole seconds var totalSeconds = Math.floor(millis / 1000); // Split into seconds and minutes var seconds = totalSeconds % 60; var minutes = Math.floor(totalSeconds / 60); // Format seconds and minutes as MM:SS return zeroPad(minutes, 2) + ':' + zeroPad(seconds, 2); }; // Add playback display to DOM display.appendChild(recordingDisplay.getElement()); // Begin downloading the recording recording.connect(); // If playing, the play/pause button should read "Pause" recording.onplay = function() { playPause.textContent = 'Pause'; }; // If paused, the play/pause button should read "Play" recording.onpause = function() { playPause.textContent = 'Play'; }; // Toggle play/pause when display or button are clicked display.onclick = playPause.onclick = function() { if (!recording.isPlaying()) recording.play(); else recording.pause(); }; // Resume playback when cancel button is clicked cancelSeek.onclick = function cancelSeekOperation(e) { recording.play(); player.className = ''; e.stopPropagation(); }; // Fit display within containing div recordingDisplay.onresize = function displayResized(width, height) { // Do not scale if display has no width if (!width) return; // Scale display to fit width of container recordingDisplay.scale(display.offsetWidth / width); }; // Update slider and status when playback position changes recording.onseek = function positionChanged(millis) { position.textContent = formatTime(millis); positionSlider.value = millis; }; // Update slider and status when duration changes recording.onprogress = function durationChanged(millis) { duration.textContent = formatTime(millis); positionSlider.max = millis; }; // Seek within recording if slider is moved positionSlider.onchange = function sliderPositionChanged() { // Request seek recording.seek(positionSlider.value, function seekComplete() { // Seek has completed player.className = ''; }); // Seek is in progress player.className = 'seeking'; }; })();