video working

This commit is contained in:
kaedwen committed 2023-06-29 20:23:33 +02:00
commit b7abd95296
51 files changed
+68060

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false
+42
View File
@@ -0,0 +1,42 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# Compiled output
#/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db
+4
View File
@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}
+20
View File
@@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "pwa-chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}
+42
View File
@@ -0,0 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}
+27
View File
@@ -0,0 +1,27 @@
# Webrtc
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.2.6.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
+97
View File
@@ -0,0 +1,97 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"webrtc": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "webrtc:build:production"
},
"development": {
"browserTarget": "webrtc:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "webrtc:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": []
}
}
}
}
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Webrtc</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css"></head>
<body>
<app-root></app-root>
<script src="runtime.js" type="module"></script><script src="polyfills.js" type="module"></script><script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body>
</html>
+268
View File
@@ -0,0 +1,268 @@
"use strict";
(self["webpackChunkwebrtc"] = self["webpackChunkwebrtc"] || []).push([["main"],{
/***/ 5041:
/*!**********************************!*\
!*** ./src/app/app.component.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "AppComponent": () => (/* binding */ AppComponent)
/* harmony export */ });
/* harmony import */ var _projects_PRIVATE_webrtc_gst_static_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 1670);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 2560);
/* harmony import */ var _services_signaling_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./services/signaling.service */ 1759);
const _c0 = ["video"];
const _c1 = ["audio"];
const _c2 = ["start"];
class AppComponent {
constructor(signaling) {
var _this = this;
this.signaling = signaling;
//this.pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]});
this.pc = new RTCPeerConnection();
// Once remote track media arrives, show it in remote element.
this.pc.ontrack = event => {
const [remoteStream] = event.streams;
if (event.track.kind === 'video') {
this.videoElem.nativeElement.srcObject = remoteStream;
this.videoElem.nativeElement.muted = true;
this.videoElem.nativeElement.play();
} else if (event.track.kind === 'audio') {
this.audioElem.nativeElement.srcObject = remoteStream;
}
};
this.pc.oniceconnectionstatechange = e => {
console.log(e);
};
// Send any ice candidates to the other peer.
this.pc.onicecandidate = ({
candidate
}) => {
console.log(candidate);
if (candidate == null) {
signaling.next(this.pc.localDescription);
}
};
// Offer to receive 1 audio, and 1 video track
this.pc.addTransceiver('audio', {
direction: 'recvonly'
});
this.pc.addTransceiver('video', {
direction: 'recvonly'
});
this.pc.createOffer().then(d => this.pc.setLocalDescription(d)).catch(e => {
console.error(e);
});
// Let the "negotiationneeded" event trigger offer generation.
this.pc.onnegotiationneeded = /*#__PURE__*/function () {
var _ref = (0,_projects_PRIVATE_webrtc_gst_static_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (e) {
console.log(e);
// try {
// await this.pc.setLocalDescription();
// // Send the offer to the other peer.
// this.api.send({desc: this.pc.localDescription});
// } catch (err) {
// console.error(err);
// }
});
return function (_x) {
return _ref.apply(this, arguments);
};
}();
this.signaling.subscribe( /*#__PURE__*/function () {
var _ref2 = (0,_projects_PRIVATE_webrtc_gst_static_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (x) {
console.log(x);
if (x.type === 'answer') {
console.log('Received answer');
try {
// the answer
yield _this.pc.setRemoteDescription(x);
} catch (e) {
console.error(e);
}
}
});
return function (_x2) {
return _ref2.apply(this, arguments);
};
}());
}
ngOnInit() {
return (0,_projects_PRIVATE_webrtc_gst_static_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {})();
}
run(e) {
this.videoElem.nativeElement.play();
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_services_signaling_service__WEBPACK_IMPORTED_MODULE_1__.SignalingService));
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
viewQuery: function AppComponent_Query(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵviewQuery"](_c0, 7, _angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef);
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵviewQuery"](_c1, 7, _angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef);
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵviewQuery"](_c2, 7, _angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef);
}
if (rf & 2) {
let _t;
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵloadQuery"]()) && (ctx.videoElem = _t.first);
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵloadQuery"]()) && (ctx.audioElem = _t.first);
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵloadQuery"]()) && (ctx.startElem = _t.first);
}
},
decls: 4,
vars: 0,
consts: [["autoplay", "", "muted", "", "controls", ""], ["video", ""], ["autoplay", "", "controls", ""], ["audio", ""]],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵelement"](0, "video", 0, 1)(2, "audio", 2, 3);
}
},
styles: ["[_nghost-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n height: 100%;\n}\n\nvideo[_ngcontent-%COMP%] {\n max-height: 90%;\n max-width: 80%;\n height: 90%;\n width: auto;\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8uL3NyYy9hcHAvYXBwLmNvbXBvbmVudC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBO0VBQ0UsYUFBQTtFQUNBLG1CQUFBO0VBQ0EsdUJBQUE7RUFDQSxzQkFBQTtFQUNBLFlBQUE7QUFBRjs7QUFHQTtFQUNFLGVBQUE7RUFDQSxjQUFBO0VBQ0EsV0FBQTtFQUNBLFdBQUE7QUFBRiIsInNvdXJjZXNDb250ZW50IjpbIlxuOmhvc3Qge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG52aWRlbyB7XG4gIG1heC1oZWlnaHQ6IDkwJTtcbiAgbWF4LXdpZHRoOiA4MCU7XG4gIGhlaWdodDogOTAlO1xuICB3aWR0aDogYXV0bztcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0= */"]
});
/***/ }),
/***/ 6747:
/*!*******************************!*\
!*** ./src/app/app.module.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "AppModule": () => (/* binding */ AppModule)
/* harmony export */ });
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/platform-browser */ 4497);
/* harmony import */ var _angular_common_http__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/common/http */ 8987);
/* harmony import */ var _app_component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app.component */ 5041);
/* harmony import */ var _services_signaling_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./services/signaling.service */ 1759);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 2560);
class AppModule {}
AppModule.ɵfac = function AppModule_Factory(t) {
return new (t || AppModule)();
};
AppModule.ɵmod = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineNgModule"]({
type: AppModule,
bootstrap: [_app_component__WEBPACK_IMPORTED_MODULE_0__.AppComponent]
});
AppModule.ɵinj = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjector"]({
providers: [_services_signaling_service__WEBPACK_IMPORTED_MODULE_1__.SignalingService],
imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.BrowserModule, _angular_common_http__WEBPACK_IMPORTED_MODULE_4__.HttpClientModule]
});
(function () {
(typeof ngJitMode === "undefined" || ngJitMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵsetNgModuleScope"](AppModule, {
declarations: [_app_component__WEBPACK_IMPORTED_MODULE_0__.AppComponent],
imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.BrowserModule, _angular_common_http__WEBPACK_IMPORTED_MODULE_4__.HttpClientModule]
});
})();
/***/ }),
/***/ 1759:
/*!***********************************************!*\
!*** ./src/app/services/signaling.service.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SignalingService": () => (/* binding */ SignalingService)
/* harmony export */ });
/* harmony import */ var rxjs_webSocket__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs/webSocket */ 3526);
/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! uuid */ 2535);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 2560);
class SignalingService extends rxjs_webSocket__WEBPACK_IMPORTED_MODULE_0__.WebSocketSubject {
constructor() {
const config = {
url: `${location.origin.replace("http", "ws")}/signaling/${(0,uuid__WEBPACK_IMPORTED_MODULE_1__["default"])()}`
};
super(config);
}
}
SignalingService.ɵfac = function SignalingService_Factory(t) {
return new (t || SignalingService)();
};
SignalingService.ɵprov = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
token: SignalingService,
factory: SignalingService.ɵfac,
providedIn: 'root'
});
/***/ }),
/***/ 2340:
/*!*****************************************!*\
!*** ./src/environments/environment.ts ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "environment": () => (/* binding */ environment)
/* harmony export */ });
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
const environment = {
production: false
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
/***/ }),
/***/ 4431:
/*!*********************!*\
!*** ./src/main.ts ***!
\*********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/platform-browser */ 4497);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 2560);
/* harmony import */ var _app_app_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app/app.module */ 6747);
/* harmony import */ var _environments_environment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./environments/environment */ 2340);
if (_environments_environment__WEBPACK_IMPORTED_MODULE_1__.environment.production) {
(0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.enableProdMode)();
}
_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.platformBrowser().bootstrapModule(_app_app_module__WEBPACK_IMPORTED_MODULE_0__.AppModule).catch(err => console.error(err));
/***/ })
},
/******/ __webpack_require__ => { // webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
/******/ __webpack_require__.O(0, ["vendor"], () => (__webpack_exec__(4431)));
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ }
]);
//# sourceMappingURL=main.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"main.js","mappings":"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","sources":["./src/app/app.component.ts","./src/app/app.component.html","./src/app/app.module.ts","./src/app/services/signaling.service.ts","./src/environments/environment.ts","./src/main.ts"],"sourcesContent":["import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';\nimport { SignalingService } from './services/signaling.service';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.scss']\n})\nexport class AppComponent implements OnInit {\n\n @ViewChild('video', { static: true, read: ElementRef })\n public videoElem!: ElementRef<HTMLVideoElement>;\n\n @ViewChild('audio', { static: true, read: ElementRef })\n public audioElem!: ElementRef<HTMLAudioElement>;\n\n @ViewChild('start', { static: true, read: ElementRef })\n public startElem!: ElementRef<HTMLButtonElement>;\n\n private readonly pc: RTCPeerConnection;\n\n constructor(private signaling: SignalingService) {\n //this.pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]});\n this.pc = new RTCPeerConnection();\n\n // Once remote track media arrives, show it in remote element.\n this.pc.ontrack = (event) => {\n const [remoteStream] = event.streams;\n if (event.track.kind === 'video') {\n this.videoElem.nativeElement.srcObject = remoteStream;\n this.videoElem.nativeElement.muted = true;\n this.videoElem.nativeElement.play();\n } else if (event.track.kind === 'audio') {\n this.audioElem.nativeElement.srcObject = remoteStream;\n }\n }\n\n this.pc.oniceconnectionstatechange = (e) => {\n console.log(e);\n };\n\n // Send any ice candidates to the other peer.\n this.pc.onicecandidate = ({candidate}) => {\n console.log(candidate);\n if (candidate == null) {\n signaling.next(this.pc.localDescription)\n }\n };\n\n // Offer to receive 1 audio, and 1 video track\n this.pc.addTransceiver('audio', {direction: 'recvonly'})\n Line truncated
+2797
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"polyfills.js","mappings":"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 truncated
+163
View File
@@ -0,0 +1,163 @@
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({});
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/chunk loaded */
/******/ (() => {
/******/ var deferred = [];
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
/******/ if(chunkIds) {
/******/ priority = priority || 0;
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
/******/ deferred[i] = [chunkIds, fn, priority];
/******/ return;
/******/ }
/******/ var notFulfilled = Infinity;
/******/ for (var i = 0; i < deferred.length; i++) {
/******/ var [chunkIds, fn, priority] = deferred[i];
/******/ var fulfilled = true;
/******/ for (var j = 0; j < chunkIds.length; j++) {
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
/******/ chunkIds.splice(j--, 1);
/******/ } else {
/******/ fulfilled = false;
/******/ if(priority < notFulfilled) notFulfilled = priority;
/******/ }
/******/ }
/******/ if(fulfilled) {
/******/ deferred.splice(i--, 1)
/******/ var r = fn();
/******/ if (r !== undefined) result = r;
/******/ }
/******/ }
/******/ return result;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/jsonp chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ "runtime": 0
/******/ };
/******/
/******/ // no chunk on demand loading
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/
/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
/******/
/******/ // install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ return __webpack_require__.O(result);
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["webpackChunkwebrtc"] = self["webpackChunkwebrtc"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ })();
/******/
/************************************************************************/
/******/
/******/
/******/ })()
;
//# sourceMappingURL=runtime.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"runtime.js","mappings":";;;;UAAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;UAEA;UACA;;;;;WCzBA;WACA;WACA;WACA;WACA,+BAA+B,wCAAwC;WACvE;WACA;WACA;WACA;WACA,iBAAiB,qBAAqB;WACtC;WACA;WACA,kBAAkB,qBAAqB;WACvC;WACA;WACA,KAAK;WACL;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;WC3BA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM,qBAAqB;WAC3B;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA","sources":["webpack/bootstrap","webpack/runtime/chunk loaded","webpack/runtime/compat get default export","webpack/runtime/define property getters","webpack/runtime/hasOwnProperty shorthand","webpack/runtime/make namespace object","webpack/runtime/jsonp chunk loading","webpack/before-startup","webpack/startup","webpack/after-startup"],"sourcesContent":["// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"runtime\": 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.lenLine truncated
+15
View File
@@ -0,0 +1,15 @@
/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].rules[0].oneOf[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[6].rules[0].oneOf[0].use[2]!./node_modules/resolve-url-loader/index.js??ruleSet[1].rules[6].rules[1].use[0]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].rules[1].use[1]!./src/styles.scss?ngGlobalStyle ***!
\***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* You can add global styles to this file, and also import other style files */
html, body {
width: 100%;
height: 100%;
margin: 0;
}
body {
background-color: rgb(46, 46, 46);
}
/*# sourceMappingURL=styles.css.map*/
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"styles.css","mappings":";;;AAAA;AAEA;EACE;EACA;EACA;AAAF;;AAGA;EACE;AAAF,C","sources":["./src/styles.scss"],"sourcesContent":["/* You can add global styles to this file, and also import other style files */\n\nhtml, body {\n width: 100%;\n height: 100%;\n margin: 0;\n}\n\nbody {\n background-color: rgb(46, 46, 46);\n}"],"names":[],"sourceRoot":"webpack:///","x_google_ignoreList":[]}
+42535
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"vendor.js","mappings":"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 truncated
+44
View File
@@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/webrtc'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};
+20464
View File
File diff suppressed because it is too large. Load diff
+40
View File
@@ -0,0 +1,40 @@
{
"name": "webrtc",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^15.2.9",
"@angular/common": "^15.2.9",
"@angular/compiler": "^15.2.9",
"@angular/core": "^15.2.9",
"@angular/forms": "^15.2.9",
"@angular/platform-browser": "^15.2.9",
"@angular/platform-browser-dynamic": "^15.2.9",
"@angular/router": "^15.2.9",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"uuid": "^9.0.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^15.2.8",
"@angular/cli": "~15.2.8",
"@angular/compiler-cli": "^15.2.9",
"@types/jasmine": "~4.0.0",
"@types/uuid": "^9.0.1",
"jasmine-core": "~4.3.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"typescript": "~4.9.5"
}
}
+2
View File
@@ -0,0 +1,2 @@
<video #video autoplay muted controls></video>
<audio #audio autoplay controls></audio>
+15
View File
@@ -0,0 +1,15 @@
:host {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100%;
}
video {
max-height: 90%;
max-width: 80%;
height: 90%;
width: auto;
}
+25
View File
@@ -0,0 +1,25 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('webrtc app is running!');
});
});
+93
View File
@@ -0,0 +1,93 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { SignalingService } from './services/signaling.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
@ViewChild('video', { static: true, read: ElementRef })
public videoElem!: ElementRef<HTMLVideoElement>;
@ViewChild('audio', { static: true, read: ElementRef })
public audioElem!: ElementRef<HTMLAudioElement>;
@ViewChild('start', { static: true, read: ElementRef })
public startElem!: ElementRef<HTMLButtonElement>;
private readonly pc: RTCPeerConnection;
constructor(private signaling: SignalingService) {
//this.pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]});
this.pc = new RTCPeerConnection();
// Once remote track media arrives, show it in remote element.
this.pc.ontrack = (event) => {
const [remoteStream] = event.streams;
if (event.track.kind === 'video') {
this.videoElem.nativeElement.srcObject = remoteStream;
this.videoElem.nativeElement.muted = true;
this.videoElem.nativeElement.play();
} else if (event.track.kind === 'audio') {
this.audioElem.nativeElement.srcObject = remoteStream;
}
}
this.pc.oniceconnectionstatechange = (e) => {
console.log(e);
};
// Send any ice candidates to the other peer.
this.pc.onicecandidate = ({candidate}) => {
console.log(candidate);
if (candidate == null) {
signaling.next(this.pc.localDescription)
}
};
// Offer to receive 1 audio, and 1 video track
this.pc.addTransceiver('audio', {direction: 'recvonly'})
this.pc.addTransceiver('video', {direction: 'recvonly'})
this.pc.createOffer().then(d => this.pc.setLocalDescription(d)).catch((e) => {
console.error(e);
});
// Let the "negotiationneeded" event trigger offer generation.
this.pc.onnegotiationneeded = async (e) => {
console.log(e);
// try {
// await this.pc.setLocalDescription();
// // Send the offer to the other peer.
// this.api.send({desc: this.pc.localDescription});
// } catch (err) {
// console.error(err);
// }
};
this.signaling.subscribe(async (x) => {
console.log(x);
if (x.type === 'answer') {
console.log('Received answer');
try {
// the answer
await this.pc.setRemoteDescription(x);
} catch(e) {
console.error(e);
}
}
});
}
public async ngOnInit(): Promise<void> {
}
public run(e: MouseEvent): void {
this.videoElem.nativeElement.play();
}
}
+18
View File
@@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { SignalingService } from './services/signaling.service';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
],
providers: [SignalingService],
bootstrap: [AppComponent]
})
export class AppModule { }
@@ -0,0 +1,16 @@
import { WebSocketSubject, WebSocketSubjectConfig } from 'rxjs/webSocket';
import { Injectable } from '@angular/core';
import { v4 } from 'uuid';
@Injectable({
providedIn: 'root'
})
export class SignalingService extends WebSocketSubject<any> {
constructor() {
const config: WebSocketSubjectConfig<any> = {
url: `${location.origin.replace("http", "ws")}/signaling/${v4()}`,
};
super(config);
}
}
View File
Whitespace-only changes.
@@ -0,0 +1,3 @@
export const environment = {
production: true
};
+16
View File
@@ -0,0 +1,16 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Webrtc</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
+12
View File
@@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
+53
View File
@@ -0,0 +1,53 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes recent versions of Safari, Chrome (including
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
+11
View File
@@ -0,0 +1,11 @@
/* You can add global styles to this file, and also import other style files */
html, body {
width: 100%;
height: 100%;
margin: 0;
}
body {
background-color: rgb(46, 46, 46);
}
+14
View File
@@ -0,0 +1,14 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(),
);
+15
View File
@@ -0,0 +1,15 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}
+33
View File
@@ -0,0 +1,33 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "es2020",
"lib": [
"es2020",
"dom"
],
"useDefineForClassFields": false
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
+18
View File
@@ -0,0 +1,18 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}