Robert Ayrapetyan 2023-09-03 17:07:04 +00:00
parent 029fa9b8dc
commit 18967dadbf
14 changed files with 1393 additions and 3549 deletions

View file

@ -21,12 +21,6 @@ https://github.com/webrtcHacks/adapter/blob/master/LICENSE.md
Webrtc-adapter is Copyright (c) 2014, The WebRTC project authors, All rights reserved.<br> Webrtc-adapter is Copyright (c) 2014, The WebRTC project authors, All rights reserved.<br>
Copyright (c) 2018, The adapter.js project authors, All rights reserved. Copyright (c) 2018, The adapter.js project authors, All rights reserved.
It also includes Keyboard.js source code from the Apache [guacamole-client](https://github.com/apache/guacamole-client)
that is embedded with the API to enable remote control of the webrtcsink producer.
Keyboard.js is released under the Apache 2.0 license available at:
https://github.com/apache/guacamole-client/blob/master/LICENSE
## Building the API ## Building the API
The GstWebRTC API uses [Webpack](https://webpack.js.org/) to bundle all source files and dependencies together. The GstWebRTC API uses [Webpack](https://webpack.js.org/) to bundle all source files and dependencies together.

View file

@ -1,6 +1,6 @@
{ {
"name": "gstwebrtc-api", "name": "gstwebrtc-api",
"version": "1.0.0", "version": "1.0.1",
"description": "Javascript API to integrate GStreamer WebRTC streams (webrtcsrc/webrtcsink) in a web browser", "description": "Javascript API to integrate GStreamer WebRTC streams (webrtcsrc/webrtcsink) in a web browser",
"keywords": [ "keywords": [
"webrtc", "webrtc",
@ -25,27 +25,31 @@
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git", "url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git",
"directory": "net/webrtc/gstwebrtc-api" "directory": "net/webrtc/gstwebrtc-api"
}, },
"type": "module",
"browser": "dist/gstwebrtc-api-${npm_package_version}.min.js", "browser": "dist/gstwebrtc-api-${npm_package_version}.min.js",
"files": [ "files": [
"dist/", "dist/",
"docs/", "docs/",
"src/", "src/",
"third-party/", "test/",
"index.html", "index.html",
"webpack.config.js" "LICENSE-MPL-2.0",
"webpack.config.cjs"
], ],
"devDependencies": { "devDependencies": {
"eslint": "8.37.0", "chai": "4.3.8",
"html-webpack-plugin": "5.5.0", "eslint": "8.49.0",
"html-webpack-plugin": "5.5.3",
"jsdoc": "4.0.2", "jsdoc": "4.0.2",
"rimraf": "4.4.1", "mocha": "10.2.0",
"terser-webpack-plugin": "5.3.7", "rimraf": "5.0.1",
"webpack": "5.77.0", "terser-webpack-plugin": "5.3.9",
"webpack-cli": "5.0.1", "webpack": "5.88.2",
"webpack-dev-server": "4.13.1" "webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1"
}, },
"dependencies": { "dependencies": {
"webrtc-adapter": "8.2.2" "webrtc-adapter": "8.2.3"
}, },
"scripts": { "scripts": {
"check": "eslint src", "check": "eslint src",
@ -53,7 +57,8 @@
"build": "rimraf dist && webpack", "build": "rimraf dist && webpack",
"docs": "rimraf docs && jsdoc src/*.js -d docs/ -p package.json -R README.md", "docs": "rimraf docs && jsdoc src/*.js -d docs/ -p package.json -R README.md",
"make": "npm run check && npm run build && npm run docs", "make": "npm run check && npm run build && npm run docs",
"prepack": "npm run make", "test": "mocha --node-env=test --exit",
"prepack": "npm run test && npm run make",
"start": "webpack serve" "start": "webpack serve"
} }
} }

View file

@ -9,8 +9,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import ConsumerSession from "./consumer-session"; import ConsumerSession from "./consumer-session.js";
import ProducerSession from "./producer-session"; import ProducerSession from "./producer-session.js";
const SignallingServerMessageType = Object.freeze({ const SignallingServerMessageType = Object.freeze({
welcome: "welcome", welcome: "welcome",

View file

@ -9,9 +9,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import WebRTCSession from "./webrtc-session"; import WebRTCSession from "./webrtc-session.js";
import SessionState from "./session-state"; import SessionState from "./session-state.js";
import RemoteController from "./remote-controller"; import RemoteController from "./remote-controller.js";
/** /**
* Event name: "streamsChanged".<br> * Event name: "streamsChanged".<br>

View file

@ -9,9 +9,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import defaultConfig from "./config"; import defaultConfig from "./config.js";
import ComChannel from "./com-channel"; import ComChannel from "./com-channel.js";
import SessionState from "./session-state"; import SessionState from "./session-state.js";
const apiState = { const apiState = {
config: null, config: null,

View file

@ -10,7 +10,7 @@
*/ */
import "webrtc-adapter"; import "webrtc-adapter";
import { gstWebRTCAPI, start } from "./gstwebrtc-api"; import { gstWebRTCAPI, start } from "./gstwebrtc-api.js";
/** /**
* @external MediaStream * @external MediaStream

File diff suppressed because it is too large Load diff

View file

@ -9,8 +9,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import WebRTCSession from "./webrtc-session"; import WebRTCSession from "./webrtc-session.js";
import SessionState from "./session-state"; import SessionState from "./session-state.js";
/** /**
* @class gstWebRTCAPI.ClientSession * @class gstWebRTCAPI.ClientSession

View file

@ -9,8 +9,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import Guacamole from "../third-party/Keyboard"; import getKeysymString from "./keysyms.js";
import getKeysymString from "./keysyms";
const eventsNames = Object.freeze([ const eventsNames = Object.freeze([
"wheel", "wheel",
@ -21,7 +20,9 @@ const eventsNames = Object.freeze([
"touchstart", "touchstart",
"touchend", "touchend",
"touchmove", "touchmove",
"touchcancel" "touchcancel",
"keyup",
"keydown"
]); ]);
const mouseEventsNames = Object.freeze({ const mouseEventsNames = Object.freeze({
@ -37,10 +38,15 @@ const touchEventsNames = Object.freeze({
touchcancel: "TouchUp" touchcancel: "TouchUp"
}); });
const keyboardEventsNames = Object.freeze({
keydown: "KeyPress",
keyup: "KeyRelease"
});
function getModifiers(event) { function getModifiers(event) {
const modifiers = []; const modifiers = [];
if (event.altKey) { if (event.altKey) {
modifiers.push("alt-mask"); modifiers.push("mod1-mask");
} }
if (event.ctrlKey) { if (event.ctrlKey) {
@ -153,22 +159,6 @@ export default class RemoteController extends EventTarget {
this._videoElement = element; this._videoElement = element;
this._videoElementComputedStyle = window.getComputedStyle(element); this._videoElementComputedStyle = window.getComputedStyle(element);
this._videoElementKeyboard = new Guacamole.Keyboard(element);
this._videoElementKeyboard.onkeydown = (keysym, modifierState) => {
this._sendGstNavigationEvent({
event: "KeyPress",
key: getKeysymString(keysym),
modifier_state: modifierState // eslint-disable-line camelcase
});
};
this._videoElementKeyboard.onkeyup = (keysym, modifierState) => {
this._sendGstNavigationEvent({
event: "KeyRelease",
key: getKeysymString(keysym),
modifier_state: modifierState // eslint-disable-line camelcase
});
};
for (const eventName of eventsNames) { for (const eventName of eventsNames) {
element.addEventListener(eventName, this); element.addEventListener(eventName, this);
} }
@ -181,11 +171,6 @@ export default class RemoteController extends EventTarget {
this._videoElement = null; this._videoElement = null;
this._videoElementComputedStyle = null; this._videoElementComputedStyle = null;
this._videoElementKeyboard.onkeydown = null;
this._videoElementKeyboard.onkeyup = null;
this._videoElementKeyboard.reset();
this._videoElementKeyboard = null;
this._lastTouchEventTimestamp = 0; this._lastTouchEventTimestamp = 0;
for (const eventName of eventsNames) { for (const eventName of eventsNames) {
@ -355,6 +340,18 @@ export default class RemoteController extends EventTarget {
}); });
} }
break; break;
case "keyup":
case "keydown":
event.preventDefault();
{
const data = {
event: keyboardEventsNames[event.type],
key: getKeysymString(event.key, event.code),
modifier_state: getModifiers(event) // eslint-disable-line camelcase
};
this._sendGstNavigationEvent(data);
}
break;
} }
} }
} }

View file

@ -9,7 +9,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import SessionState from "./session-state"; import SessionState from "./session-state.js";
/** /**
* Event name: "error".<br> * Event name: "error".<br>

View file

@ -0,0 +1,40 @@
import { expect } from "chai";
import getKeysymString from "../src/keysyms.js";
describe("getKeysymString tests", () => {
it("should return mapped keySym value from codesToKeySyms", () => {
const key = "Shift";
const code = "ShiftLeft";
const result = getKeysymString(key, code);
expect(result).to.equal("Shift_L");
});
it("should return the keysym for a single-character key from uniToKeySyms", () => {
const key = "A";
const code = "KeyA";
const result = getKeysymString(key, code);
expect(result).to.equal("A");
});
it("should handle non-ASCII characters from uniToKeySyms", () => {
const key = "ф";
const code = "KeyA";
const result = getKeysymString(key, code);
expect(result).to.equal("Cyrillic_ef");
});
it("should return the valid keySym from knownKeysyms", () => {
const key = "Tab";
const code = "Tab";
const result = getKeysymString(key, code);
expect(result).to.equal(code);
});
it("should return the default keySym if no match is found", () => {
const key = "InvalidKey";
const code = "InvalidCode";
const result = getKeysymString(key, code);
expect(result).to.equal("Unidentified");
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,33 +0,0 @@
Keyboard.js is released under the Apache 2.0 license and downloaded from:
https://github.com/apache/guacamole-client/tree/master/guacamole-common-js/src/main/webapp/modules/Keyboard.js
```javascript
/*
* 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.
*/
```
Line 20 has been modified to allow importation with webpack, from:
```javascript
var Guacamole = Guacamole || {};
```
to:
```javascript
const Guacamole = {};
export { Guacamole as default };
```

View file

@ -14,7 +14,7 @@ const config = {
mode: isDevServer ? "development" : "production", mode: isDevServer ? "development" : "production",
devtool: isDevServer ? "eval" : "source-map", devtool: isDevServer ? "eval" : "source-map",
entry: { "gstwebrtc-api": "./src" }, entry: { "gstwebrtc-api": "./src/index.js" },
output: { filename: isDevServer ? "[name]-[contenthash].min.js" : `[name]-${packageVersion}.min.js` }, output: { filename: isDevServer ? "[name]-[contenthash].min.js" : `[name]-${packageVersion}.min.js` },
devServer: { devServer: {
@ -40,8 +40,7 @@ const config = {
output: { output: {
comments: false, comments: false,
preamble: "/*! gstwebrtc-api (https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/tree/main/net/webrtc/gstwebrtc-api), MPL-2.0 License, Copyright (C) 2022 Igalia S.L. <info@igalia.com>, Author: Loïc Le Page <llepage@igalia.com> */\n" + preamble: "/*! gstwebrtc-api (https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/tree/main/net/webrtc/gstwebrtc-api), MPL-2.0 License, Copyright (C) 2022 Igalia S.L. <info@igalia.com>, Author: Loïc Le Page <llepage@igalia.com> */\n" +
"/*! Contains embedded adapter from webrtc-adapter (https://github.com/webrtcHacks/adapter), BSD 3-Clause License, Copyright (c) 2014, The WebRTC project authors. All rights reserved. Copyright (c) 2018, The adapter.js project authors. All rights reserved. */\n" + "/*! Contains embedded adapter from webrtc-adapter (https://github.com/webrtcHacks/adapter), BSD 3-Clause License, Copyright (c) 2014, The WebRTC project authors. All rights reserved. Copyright (c) 2018, The adapter.js project authors. All rights reserved. */\n"
"/*! Contains embedded Keyboard.js from guacamole-client (https://github.com/apache/guacamole-client), Apache 2.0 License */"
} }
} }
}) })