import React, {Component} from 'react'; import Guacamole from "guacamole-common-js"; import {server} from "../../common/env"; import {Button, Col, Row, Select, Slider, Typography} from "antd"; import {PauseCircleOutlined, PlayCircleOutlined} from '@ant-design/icons'; import {Tooltip} from "antd/lib/index"; import {getToken} from "../../utils/utils"; const {Text} = Typography; let timer; class Playback extends Component { state = { playPauseIcon: , playPauseIconTitle: '播放', recording: undefined, percent: 0, max: 0, speed: 1, } componentDidMount() { let sessionId = this.props.sessionId; this.initPlayer(sessionId); } componentWillMount() { } initPlayer(sessionId) { const RECORDING_URL = `${server}/sessions/${sessionId}/recording?X-Auth-Token=${getToken()}`; const display = document.getElementById('display'); const tunnel = new Guacamole.StaticHTTPTunnel(RECORDING_URL); const recording = new Guacamole.SessionRecording(tunnel); const 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. */ const 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. */ const 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 = () => { // 暂停 this.setState({ playPauseIcon: , playPauseIconTitle: '暂停', }) }; // If paused, the play/pause button should read "Play" recording.onpause = () => { // 播放 this.setState({ playPauseIcon: , playPauseIconTitle: '播放', }) }; // Toggle play/pause when display or button are clicked display.onclick = this.handlePlayPause; // 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); }; recording.onseek = (millis) => { this.setState({ percent: millis, position: formatTime(millis) }) }; recording.onprogress = (millis) => { this.setState({ max: millis, duration: formatTime(millis) }) }; this.setState({ recording: recording }, () => { this.handlePlayPause(); }); } startSpeedUp = () => { let speed = this.state.speed; if (speed === 1) { return; } let recording = this.state.recording; if (!recording.isPlaying()) { return; } const add_time = 100; let delay = 1000 / (1000 / add_time) / (speed - 1); let max = recording.getDuration(); let current = recording.getPosition(); if (current >= max) { this.stopSpeedUp(); return; } recording.seek(current + add_time, () => { timer = setTimeout(this.startSpeedUp, delay); }); } stopSpeedUp = () => { clearTimeout(timer) } handlePlayPause = () => { let recording = this.state.recording; if (recording) { if (this.state.percent === this.state.max) { // 重播 this.setState({ percent: 0 }, () => { recording.seek(0, () => { recording.play(); this.startSpeedUp(); }); }); } if (!recording.isPlaying()) { recording.play(); this.startSpeedUp(); } else { recording.pause(); this.stopSpeedUp(); } } } handleProgressChange = (value) => { let recording = this.state.recording; if (recording) { // Request seek recording.seek(value, () => { console.log('complete'); }); } } render() { return (
); } } export default Playback;