first working

This commit is contained in:
kaedwen committed 2023-07-04 19:53:26 +02:00
1 parent b7abd95296
commit 957bf18721
2528 files changed
+787399 -155

No files matched your search

+197 -44
View File
@@ -12,30 +12,60 @@ __webpack_require__.r(__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);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/core */ 2560);
/* harmony import */ var _components_video_video_component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/video/video.component */ 5465);
/* harmony import */ var _components_audio_audio_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/audio/audio.component */ 210);
/* harmony import */ var _services_signaling_service__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./services/signaling.service */ 1759);
const _c0 = ["video"];
const _c1 = ["audio"];
const _c2 = ["start"];
const _c0 = ["vc"];
class AppComponent {
constructor(signaling) {
onClick(_) {
var _this = this;
return (0,_projects_PRIVATE_webrtc_gst_static_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
if (!_this.selfAudioRunning) {
yield _this.startAudio();
}
for (const el of _this.audioList) {
el.instance.toggleMute();
}
})();
}
startAudio() {
var _this2 = this;
return (0,_projects_PRIVATE_webrtc_gst_static_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
const stream = yield navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
_this2.pc.addTrack(stream.getAudioTracks()[0]);
_this2.selfAudioRunning = true;
})();
}
constructor(signaling) {
var _this3 = this;
this.signaling = signaling;
this.audioList = [];
this.selfAudioRunning = false;
//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();
const video = this.vcr.createComponent(_components_video_video_component__WEBPACK_IMPORTED_MODULE_1__.VideoComponent, {});
video.instance.setStream(remoteStream);
video.instance.play();
console.log(video);
} else if (event.track.kind === 'audio') {
this.audioElem.nativeElement.srcObject = remoteStream;
const audio = this.vcr.createComponent(_components_audio_audio_component__WEBPACK_IMPORTED_MODULE_2__.AudioComponent, {});
audio.instance.setStream(remoteStream);
console.log(audio);
this.audioList.push(audio);
}
};
this.pc.oniceconnectionstatechange = e => {
@@ -52,7 +82,7 @@ class AppComponent {
};
// Offer to receive 1 audio, and 1 video track
this.pc.addTransceiver('audio', {
direction: 'recvonly'
direction: 'sendrecv'
});
this.pc.addTransceiver('video', {
direction: 'recvonly'
@@ -63,14 +93,12 @@ class AppComponent {
// 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);
// }
try {
yield _this3.pc.setLocalDescription();
signaling.next(_this3.pc.localDescription);
} catch (err) {
console.error(err);
}
});
return function (_x) {
return _ref.apply(this, arguments);
@@ -83,7 +111,7 @@ class AppComponent {
console.log('Received answer');
try {
// the answer
yield _this.pc.setRemoteDescription(x);
yield _this3.pc.setRemoteDescription(x);
} catch (e) {
console.error(e);
}
@@ -97,38 +125,38 @@ class AppComponent {
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));
return new (t || AppComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdirectiveInject"](_services_signaling_service__WEBPACK_IMPORTED_MODULE_3__.SignalingService));
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineComponent"]({
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵ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);
_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵviewQuery"](_c0, 7, _angular_core__WEBPACK_IMPORTED_MODULE_4__.ViewContainerRef);
}
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);
_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵloadQuery"]()) && (ctx.vcr = _t.first);
}
},
decls: 4,
hostBindings: function AppComponent_HostBindings(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵlistener"]("click", function AppComponent_click_HostBindingHandler($event) {
return ctx.onClick($event.target);
}, false, _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵresolveDocument"]);
}
},
decls: 2,
vars: 0,
consts: [["autoplay", "", "muted", "", "controls", ""], ["video", ""], ["autoplay", "", "controls", ""], ["audio", ""]],
consts: [["vc", ""]],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵelement"](0, "video", 0, 1)(2, "audio", 2, 3);
_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵelementContainer"](0, null, 0);
}
},
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= */"]
styles: ["[_nghost-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n height: 100%;\n width: 100%;\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8uL3NyYy9hcHAvYXBwLmNvbXBvbmVudC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBO0VBQ0UsYUFBQTtFQUNBLG1CQUFBO0VBQ0EsdUJBQUE7RUFDQSxzQkFBQTtFQUNBLFlBQUE7RUFDQSxXQUFBO0FBQUYiLCJzb3VyY2VzQ29udGVudCI6WyJcbjpob3N0IHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGhlaWdodDogMTAwJTtcbiAgd2lkdGg6IDEwMCU7XG59XG5cbiJdLCJzb3VyY2VSb290IjoiIn0= */"]
});
/***/ }),
@@ -143,11 +171,15 @@ __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 _angular_platform_browser__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/platform-browser */ 4497);
/* harmony import */ var _angular_common_http__WEBPACK_IMPORTED_MODULE_6__ = __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);
/* harmony import */ var _components_video_video_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/video/video.component */ 5465);
/* harmony import */ var _components_audio_audio_component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/audio/audio.component */ 210);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/core */ 2560);
@@ -157,23 +189,144 @@ class AppModule {}
AppModule.ɵfac = function AppModule_Factory(t) {
return new (t || AppModule)();
};
AppModule.ɵmod = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineNgModule"]({
AppModule.ɵmod = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineNgModule"]({
type: AppModule,
bootstrap: [_app_component__WEBPACK_IMPORTED_MODULE_0__.AppComponent]
});
AppModule.ɵinj = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjector"]({
AppModule.ɵinj = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵ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]
imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_5__.BrowserModule, _angular_common_http__WEBPACK_IMPORTED_MODULE_6__.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]
(typeof ngJitMode === "undefined" || ngJitMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵsetNgModuleScope"](AppModule, {
declarations: [_app_component__WEBPACK_IMPORTED_MODULE_0__.AppComponent, _components_video_video_component__WEBPACK_IMPORTED_MODULE_2__.VideoComponent, _components_audio_audio_component__WEBPACK_IMPORTED_MODULE_3__.AudioComponent],
imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_5__.BrowserModule, _angular_common_http__WEBPACK_IMPORTED_MODULE_6__.HttpClientModule]
});
})();
/***/ }),
/***/ 210:
/*!*****************************************************!*\
!*** ./src/app/components/audio/audio.component.ts ***!
\*****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "AudioComponent": () => (/* binding */ AudioComponent)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
const _c0 = ["audio"];
class AudioComponent {
ngOnInit() {
this.elem.nativeElement.muted = true;
}
setStream(stream) {
this.elem.nativeElement.srcObject = stream;
}
play() {
this.elem.nativeElement.play();
}
pause() {
this.elem.nativeElement.pause();
}
toggleMute() {
this.elem.nativeElement.muted = !this.elem.nativeElement.muted;
console.log('toggle mute to', this.elem.nativeElement.muted);
if (!this.elem.nativeElement.muted) {
this.play();
}
}
}
AudioComponent.ɵfac = function AudioComponent_Factory(t) {
return new (t || AudioComponent)();
};
AudioComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
type: AudioComponent,
selectors: [["app-audio"]],
viewQuery: function AudioComponent_Query(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c0, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
}
if (rf & 2) {
let _t;
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.elem = _t.first);
}
},
decls: 2,
vars: 0,
consts: [["audio", ""]],
template: function AudioComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "audio", null, 0);
}
},
styles: ["\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZVJvb3QiOiIifQ== */"]
});
/***/ }),
/***/ 5465:
/*!*****************************************************!*\
!*** ./src/app/components/video/video.component.ts ***!
\*****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "VideoComponent": () => (/* binding */ VideoComponent)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
const _c0 = ["video"];
class VideoComponent {
setStream(stream) {
this.elem.nativeElement.srcObject = stream;
this.elem.nativeElement.muted = true;
}
play() {
this.elem.nativeElement.play();
}
pause() {
this.elem.nativeElement.pause();
}
toggleMute() {
this.elem.nativeElement.muted = !this.elem.nativeElement.muted;
console.log('toggle mute to', this.elem.nativeElement.muted);
}
}
VideoComponent.ɵfac = function VideoComponent_Factory(t) {
return new (t || VideoComponent)();
};
VideoComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
type: VideoComponent,
selectors: [["app-video"]],
viewQuery: function VideoComponent_Query(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c0, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
}
if (rf & 2) {
let _t;
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.elem = _t.first);
}
},
decls: 2,
vars: 0,
consts: [["video", ""]],
template: function VideoComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "video", null, 0);
}
},
styles: ["[_nghost-%COMP%] {\n max-height: 90%;\n max-width: 80%;\n height: 90%;\n width: auto;\n}\n\nvideo[_ngcontent-%COMP%] {\n height: 100%;\n width: 100%;\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8uL3NyYy9hcHAvY29tcG9uZW50cy92aWRlby92aWRlby5jb21wb25lbnQuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQTtFQUNFLGVBQUE7RUFDQSxjQUFBO0VBQ0EsV0FBQTtFQUNBLFdBQUE7QUFBRjs7QUFHQTtFQUNFLFlBQUE7RUFDQSxXQUFBO0FBQUYiLCJzb3VyY2VzQ29udGVudCI6WyJcbjpob3N0IHtcbiAgbWF4LWhlaWdodDogOTAlO1xuICBtYXgtd2lkdGg6IDgwJTtcbiAgaGVpZ2h0OiA5MCU7XG4gIHdpZHRoOiBhdXRvO1xufVxuXG52aWRlbyB7XG4gIGhlaWdodDogMTAwJTtcbiAgd2lkdGg6IDEwMCU7XG59Il0sInNvdXJjZVJvb3QiOiIifQ== */"]
});
/***/ }),
/***/ 1759:
/*!***********************************************!*\
!*** ./src/app/services/signaling.service.ts ***!
+1 -1
View File
@@ -1 +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
{"version":3,"file":"main.js","mappings":"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 truncated
+1 -2
View File
@@ -1,2 +1 @@
<video #video autoplay muted controls></video>
<audio #audio autoplay controls></audio>
<ng-container #vc></ng-container>
+1 -6
View File
@@ -5,11 +5,6 @@
justify-content: center;
flex-direction: column;
height: 100%;
width: 100%;
}
video {
max-height: 90%;
max-width: 80%;
height: 90%;
width: auto;
}
+45 -26
View File
@@ -1,4 +1,6 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Component, ComponentRef, HostListener, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { VideoComponent } from './components/video/video.component';
import { AudioComponent } from './components/audio/audio.component';
import { SignalingService } from './services/signaling.service';
@Component({
@@ -7,18 +9,36 @@ import { SignalingService } from './services/signaling.service';
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
@ViewChild("vc", {static: true, read: ViewContainerRef })
public vcr!: ViewContainerRef;
@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 audioList: ComponentRef<AudioComponent>[] = [];
private selfAudioRunning = false;
private readonly pc: RTCPeerConnection;
@HostListener('document:click', ['$event.target'])
async onClick(_: KeyboardEvent) {
if (!this.selfAudioRunning) {
await this.startAudio()
}
for (const el of this.audioList) {
el.instance.toggleMute();
}
}
private async startAudio() {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
this.pc.addTrack(stream.getAudioTracks()[0])
this.selfAudioRunning = true;
}
constructor(private signaling: SignalingService) {
//this.pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]});
this.pc = new RTCPeerConnection();
@@ -27,11 +47,16 @@ export class AppComponent implements OnInit {
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();
const video = this.vcr.createComponent(VideoComponent, {});
video.instance.setStream(remoteStream);
video.instance.play();
console.log(video);
} else if (event.track.kind === 'audio') {
this.audioElem.nativeElement.srcObject = remoteStream;
const audio = this.vcr.createComponent(AudioComponent, {});
audio.instance.setStream(remoteStream);
console.log(audio);
this.audioList.push(audio)
}
}
@@ -48,7 +73,7 @@ export class AppComponent implements OnInit {
};
// Offer to receive 1 audio, and 1 video track
this.pc.addTransceiver('audio', {direction: 'recvonly'})
this.pc.addTransceiver('audio', {direction: 'sendrecv'})
this.pc.addTransceiver('video', {direction: 'recvonly'})
this.pc.createOffer().then(d => this.pc.setLocalDescription(d)).catch((e) => {
console.error(e);
@@ -56,14 +81,12 @@ export class AppComponent implements OnInit {
// 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);
// }
try {
await this.pc.setLocalDescription();
signaling.next(this.pc.localDescription);
} catch (err) {
console.error(err);
}
};
this.signaling.subscribe(async (x) => {
@@ -86,8 +109,4 @@ export class AppComponent implements OnInit {
}
public run(e: MouseEvent): void {
this.videoElem.nativeElement.play();
}
}
+5 -1
View File
@@ -3,10 +3,14 @@ import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { SignalingService } from './services/signaling.service';
import { VideoComponent } from './components/video/video.component';
import { AudioComponent } from './components/audio/audio.component';
@NgModule({
declarations: [
AppComponent
AppComponent,
VideoComponent,
AudioComponent
],
imports: [
BrowserModule,
Whitespace-only changes.
@@ -0,0 +1,36 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
@Component({
selector: 'app-audio',
template: '<audio #audio></audio>',
styleUrls: ['./audio.component.scss']
})
export class AudioComponent implements OnInit {
@ViewChild('audio', { static: true, read: ElementRef })
public elem!: ElementRef<HTMLAudioElement>;
ngOnInit(): void {
this.elem.nativeElement.muted = true;
}
public setStream(stream: MediaStream): void {
this.elem.nativeElement.srcObject = stream;
}
public play(): void {
this.elem.nativeElement.play()
}
public pause(): void {
this.elem.nativeElement.pause()
}
public toggleMute(): void {
this.elem.nativeElement.muted = !this.elem.nativeElement.muted;
console.log('toggle mute to', this.elem.nativeElement.muted);
if (!this.elem.nativeElement.muted) {
this.play();
}
}
}
@@ -0,0 +1,12 @@
:host {
max-height: 90%;
max-width: 80%;
height: 90%;
width: auto;
}
video {
height: 100%;
width: 100%;
}
@@ -0,0 +1,29 @@
import { Component, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'app-video',
template: '<video #video></video>',
styleUrls: ['./video.component.scss']
})
export class VideoComponent {
@ViewChild('video', { static: true, read: ElementRef })
public elem!: ElementRef<HTMLVideoElement>;
public setStream(stream: MediaStream): void {
this.elem.nativeElement.srcObject = stream;
this.elem.nativeElement.muted = true;
}
public play(): void {
this.elem.nativeElement.play()
}
public pause(): void {
this.elem.nativeElement.pause()
}
public toggleMute(): void {
this.elem.nativeElement.muted = !this.elem.nativeElement.muted;
console.log('toggle mute to', this.elem.nativeElement.muted);
}
}