diff options
-rw-r--r-- | tests/playback-ui.js | 54 | ||||
-rw-r--r-- | tests/playback.js | 38 |
2 files changed, 51 insertions, 41 deletions
diff --git a/tests/playback-ui.js b/tests/playback-ui.js index 012eebc..9492c0e 100644 --- a/tests/playback-ui.js +++ b/tests/playback-ui.js @@ -2,9 +2,9 @@ import * as WebUtil from '../app/webutil.js'; import RecordingPlayer from './playback.js'; +import Base64 from '../core/base64.js'; let frames = null; -let encoding = null; function message(str) { const cell = document.getElementById('messages'); @@ -19,7 +19,7 @@ function loadFile() { return Promise.reject("Must specify data=FOO in query string."); } - message("Loading " + fname); + message("Loading " + fname + "..."); return new Promise((resolve, reject) => { const script = document.createElement("script"); @@ -41,21 +41,62 @@ function enableUI() { document.getElementById('mode1').checked = true; } - message("VNC_frame_data.length: " + VNC_frame_data.length); + message("Loaded " + VNC_frame_data.length + " frames"); const startButton = document.getElementById('startButton'); startButton.disabled = false; startButton.addEventListener('click', start); + message("Converting..."); + frames = VNC_frame_data; + + let encoding; // Only present in older recordings if (window.VNC_frame_encoding) { encoding = VNC_frame_encoding; + } else { + let frame = frames[0]; + let start = frame.indexOf('{', 1) + 1; + if (frame.slice(start).startsWith('UkZC')) { + encoding = 'base64'; + } else { + encoding = 'binary'; + } + } + + for (let i = 0;i < frames.length;i++) { + let frame = frames[i]; + + if (frame === "EOF") { + frames.splice(i); + break; + } + + let dataIdx = frame.indexOf('{', 1) + 1; + + let time = parseInt(frame.slice(1, dataIdx - 1)); + + let u8; + if (encoding === 'base64') { + u8 = Base64.decode(frame.slice(dataIdx)); + } else { + u8 = new Uint8Array(frame.length - dataIdx); + for (let j = 0; j < frame.length - dataIdx; j++) { + u8[j] = frame.charCodeAt(dataIdx + j); + } + } + + frames[i] = { fromClient: frame[0] === '}', + timestamp: time, + data: u8 }; } + + message("Ready"); } class IterationPlayer { - constructor(iterations, frames, encoding) { + constructor(iterations, frames) { this._iterations = iterations; this._iteration = undefined; @@ -64,7 +105,6 @@ class IterationPlayer { this._start_time = undefined; this._frames = frames; - this._encoding = encoding; this._state = 'running'; @@ -84,7 +124,7 @@ class IterationPlayer { } _nextIteration() { - const player = new RecordingPlayer(this._frames, this._encoding, this._disconnected.bind(this)); + const player = new RecordingPlayer(this._frames, this._disconnected.bind(this)); player.onfinish = this._iterationFinish.bind(this); if (this._state !== 'running') { return; } @@ -147,7 +187,7 @@ function start() { mode = 'realtime'; } - const player = new IterationPlayer(iterations, frames, encoding); + const player = new IterationPlayer(iterations, frames); player.oniterationfinish = (evt) => { message(`Iteration ${evt.number} took ${evt.duration}ms`); }; diff --git a/tests/playback.js b/tests/playback.js index acaef74..5bd8103 100644 --- a/tests/playback.js +++ b/tests/playback.js @@ -6,7 +6,6 @@ import RFB from '../core/rfb.js'; import * as Log from '../core/util/logging.js'; -import Base64 from '../core/base64.js'; // Immediate polyfill if (window.setImmediate === undefined) { @@ -44,22 +43,11 @@ if (window.setImmediate === undefined) { } export default class RecordingPlayer { - constructor(frames, encoding, disconnected) { + constructor(frames, disconnected) { this._frames = frames; - this._encoding = encoding; this._disconnected = disconnected; - if (this._encoding === undefined) { - const frame = this._frames[0]; - const start = frame.indexOf('{', 1) + 1; - if (frame.slice(start).startsWith('UkZC')) { - this._encoding = 'base64'; - } else { - this._encoding = 'binary'; - } - } - this._rfb = undefined; this._frame_length = this._frames.length; @@ -112,17 +100,11 @@ export default class RecordingPlayer { let frame = this._frames[this._frame_index]; // skip send frames - while (this._frame_index < this._frame_length && frame.charAt(0) === "}") { + while (this._frame_index < this._frame_length && frame.fromClient) { this._frame_index++; frame = this._frames[this._frame_index]; } - if (frame === 'EOF') { - Log.Debug('Finished, found EOF'); - this._finish(); - return; - } - if (this._frame_index >= this._frame_length) { Log.Debug('Finished, no more frames'); this._finish(); @@ -130,9 +112,8 @@ export default class RecordingPlayer { } if (this._realtime) { - const foffset = frame.slice(1, frame.indexOf('{', 1)); const toffset = (new Date()).getTime() - this._start_time; - let delay = foffset - toffset; + let delay = frame.timestamp - toffset; if (delay < 1) delay = 1; setTimeout(this._doPacket.bind(this), delay); @@ -154,19 +135,8 @@ export default class RecordingPlayer { } const frame = this._frames[this._frame_index]; - let start = frame.indexOf('{', 1) + 1; - let u8; - if (this._encoding === 'base64') { - u8 = Base64.decode(frame.slice(start)); - start = 0; - } else { - u8 = new Uint8Array(frame.length - start); - for (let i = 0; i < frame.length - start; i++) { - u8[i] = frame.charCodeAt(start + i); - } - } - this._rfb._sock._recv_message({'data': u8}); + this._rfb._sock._recv_message({'data': frame.data}); this._frame_index++; this._queueNextPacket(); |