]>
git.proxmox.com Git - mirror_novnc.git/blob - tests/playback.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2012 Joel Martin
4 * Licensed under MPL 2.0 (see LICENSE.txt)
7 import RFB
from '../core/rfb.js';
8 import * as Log
from '../core/util/logging.js';
9 import Base64
from '../core/base64.js';
12 if (setImmediate
=== undefined) {
13 var _immediateIdCounter
= 1;
14 var _immediateFuncs
= {};
16 var setImmediate = function (func
) {
17 var index
= _immediateIdCounter
++;
18 _immediateFuncs
[index
] = func
;
19 window
.postMessage("noVNC immediate trigger:" + index
, "*");
23 window
.clearImmediate = function (id
) {
27 var _onMessage = function (event
) {
28 if ((typeof event
.data
!== "string") ||
29 (event
.data
.indexOf("noVNC immediate trigger:") !== 0)) {
33 var index
= event
.data
.slice("noVNC immediate trigger:".length
);
35 var callback
= _immediateFuncs
[index
];
36 if (callback
=== undefined) {
40 delete _immediateFuncs
[index
];
44 window
.addEventListener("message", _onMessage
);
47 export default function RecordingPlayer (frames
, encoding
, disconnected
, notification
) {
48 this._frames
= frames
;
49 this._encoding
= encoding
;
51 this._disconnected
= disconnected
;
52 this._notification
= notification
;
54 if (this._encoding
=== undefined) {
55 let frame
= this._frames
[0];
56 let start
= frame
.indexOf('{', 1) + 1;
57 if (frame
.slice(start
).startsWith('UkZC')) {
58 this._encoding
= 'base64';
60 this._encoding
= 'binary';
64 this._rfb
= undefined;
65 this._frame_length
= this._frames
.length
;
67 this._frame_index
= 0;
68 this._start_time
= undefined;
69 this._realtime
= true;
70 this._trafficManagement
= true;
72 this._running
= false;
74 this.onfinish = function () {};
77 RecordingPlayer
.prototype = {
78 run: function (realtime
, trafficManagement
) {
79 // initialize a new RFB
80 this._rfb
= new RFB({'target': document
.getElementById('VNC_canvas'),
82 'onDisconnected': this._handleDisconnect
.bind(this),
83 'onNotification': this._notification
});
84 this._enablePlaybackMode();
86 // reset the frame index and timer
87 this._frame_index
= 0;
88 this._start_time
= (new Date()).getTime();
90 this._realtime
= realtime
;
91 this._trafficManagement
= (trafficManagement
=== undefined) ? !realtime
: trafficManagement
;
96 this._rfb
.connect('wss://test');
98 this._queueNextPacket();
101 // _enablePlaybackMode mocks out things not required for running playback
102 _enablePlaybackMode: function () {
103 this._rfb
._sock
.send = function (arr
) {};
104 this._rfb
._sock
.close = function () {};
105 this._rfb
._sock
.flush = function () {};
106 this._rfb
._checkEvents = function () {};
107 this._rfb
.connect = function (url
) {
109 this._rfb_credentials
= {};
110 this._sock
.init('binary', 'ws');
111 this._rfb_connection_state
= 'connecting';
112 this._rfb_init_state
= 'ProtocolVersion';
116 _queueNextPacket: function () {
117 if (!this._running
) { return; }
119 var frame
= this._frames
[this._frame_index
];
122 while (this._frame_index
< this._frame_length
&& frame
.charAt(0) === "}") {
124 frame
= this._frames
[this._frame_index
];
127 if (frame
=== 'EOF') {
128 Log
.Debug('Finished, found EOF');
133 if (this._frame_index
>= this._frame_length
) {
134 Log
.Debug('Finished, no more frames');
139 if (this._realtime
) {
140 let foffset
= frame
.slice(1, frame
.indexOf('{', 1));
141 let toffset
= (new Date()).getTime() - this._start_time
;
142 let delay
= foffset
- toffset
;
143 if (delay
< 1) delay
= 1;
145 setTimeout(this._doPacket
.bind(this), delay
);
147 setImmediate(this._doPacket
.bind(this));
151 _doPacket: function () {
152 // Avoid having excessive queue buildup in non-realtime mode
153 if (this._trafficManagement
&& this._rfb
._flushing
) {
155 let orig
= this._rfb
._display
.get_onFlush();
156 this._rfb
._display
.set_onFlush(function () {
157 player
._rfb
._display
.set_onFlush(orig
);
158 player
._rfb
._onFlush();
164 const frame
= this._frames
[this._frame_index
];
165 var start
= frame
.indexOf('{', 1) + 1;
166 if (this._encoding
=== 'base64') {
167 var u8
= Base64
.decode(frame
.slice(start
));
170 var u8
= new Uint8Array(frame
.length
- start
);
171 for (let i
= 0; i
< frame
.length
- start
; i
++) {
172 u8
[i
] = frame
.charCodeAt(start
+ i
);
176 this._rfb
._sock
._recv_message({'data': u8
});
179 this._queueNextPacket();
183 if (this._rfb
._display
.pending()) {
185 this._rfb
._display
.set_onFlush(function () {
186 if (player
._rfb
._flushing
) {
187 player
._rfb
._onFlush();
191 this._rfb
._display
.flush();
193 this._running
= false;
194 this.onfinish((new Date()).getTime() - this._start_time
);
198 _handleDisconnect(rfb
, reason
) {
199 this._running
= false;
200 this._disconnected(rfb
, reason
, this._frame_index
);