From 9c9f192dc3b8ce1b798fcca98f208a3fb8d26cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20B=C5=82aszk=C3=B3w?= Date: Thu, 5 May 2022 16:57:19 +0200 Subject: [PATCH 1/3] Repo cleanup --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 190 +++++++++++++++++++++++++++++++++++---- assets/package-lock.json | 28 +++--- 3 files changed, 190 insertions(+), 28 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 603976014ad2cd7311d7cc61d5ddd99c5c608cc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~&u-H|5XNU)Q#L_}2qDps|64hyu+DlbMJJRg8e`eO&U$R~=5sB_3*(7Qak%Y5)O%#_HkF#H} z72DH*3Z7#xQ~fwoG1@$#Ge^J?xZMPJ?|Kx`gbEri?B7=y+xVkRFJc}Sm*Zo*&wt0q zSvoE{ol~*0>fKqpD`itQ?>9e&Lsf=FR7}R*Xtd9*w^1>SZT+26*}NXb@6$oqYdw0c z@*+y}!AK{k$p9e-AJRNgWmiq|WUS{2&482*+32;_r_-%xJ8gfvvomY^(-&Kvw*Ped z`E1sZkDqM5+&et_{AK!e_U*g*9Ryxf+8$W_CqGb`FYqKB<(bMqp^xJq(g~%M(0~+; z;EIl@2WScUBg(0dk)#e!oFVT#yerMItYELS_yy=|R03-Z;05*TaOoG|{yg{3ti>)X z#M&YkV1dW=&29yG@A|1O!x3-7(;w<{2Q;u+ z8AT6Fm{h1q750iD?9D-#bc_c!zA|dkN$4kI9{XfrZz#fEJcO^qNd!h+=?FLibporV z+2Zs6&HwNJ^(5DF1RQ~-A|SloaJP#k*|YV+;`prf;fHWGj;oC76cqM2))hXA*WubQ Y=5qxaSgnkr2j)HmGzM2V0yj$FFY6);)c^nh diff --git a/.gitignore b/.gitignore index 552ede65..2e674956 100644 --- a/.gitignore +++ b/.gitignore @@ -4,31 +4,187 @@ priv/certs/*.pem priv/integrated_turn_cert.pem priv/static/assets -# The directory Mix will write compiled artifacts to. -/_build/ +# Ignore package tarball (built via "mix hex.build"). +videoroom-*.tar -# If you run "mix test --cover", coverage assets end up here. -/cover/ +node_modules -# The directory Mix downloads your dependencies sources to. -/deps/ +compile_commands.json +.gdb_history +bundlex.sh +bundlex.bat -# Where third-party dependencies like ExDoc output generated docs. -/doc/ +# Dir generated by tmp_dir ExUnit tag +/tmp/ -# Ignore .fetch files in case you like to edit your project deps locally. -/.fetch +# Created by https://www.gitignore.io/api/c,vim,linux,macos,elixir,windows,visualstudiocode +# Edit at https://www.gitignore.io/?templates=c,vim,linux,macos,elixir,windows,visualstudiocode -# If the VM crashes, it generates a dump, let's ignore it too. -erl_crash.dump +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib -# Also ignore archive artifacts (built via "mix archive.build"). +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### Elixir ### +/_build +/cover +/deps +/doc +/.fetch +erl_crash.dump *.ez +*.beam +/config/*.secret.exs +.elixir_ls/ -# Ignore package tarball (built via "mix hex.build"). -videoroom-*.tar +### Elixir Patch ### -.elixir_ls +### Linux ### +*~ -node_modules +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk +# End of https://www.gitignore.io/api/c,vim,linux,macos,elixir,windows,visualstudiocode diff --git a/assets/package-lock.json b/assets/package-lock.json index ee7986be..6e9ca603 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -28,7 +28,7 @@ "license": "Apache 2.0" }, "../deps/phoenix": { - "version": "1.6.6", + "version": "1.6.7", "integrity": "sha512-KLNHVlrZH8UAoEzeCS1XBI9z5juWz0gZ/+No7j5p/byVINnd+del9H5vtBMzQgZa3ZcUjVVZcQR8bKdnH/FmMg==", "license": "MIT" }, @@ -408,14 +408,20 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001278", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz", - "integrity": "sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==", + "version": "1.0.30001336", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001336.tgz", + "integrity": "sha512-/YxSlBmL7iKXTbIJ48IQTnAOBk7XmWsxhBF1PZLOko5Dt9qc4Pl+84lfqG3Tc4EuavurRn1QLoVJGxY2iSycfw==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, "node_modules/chalk": { "version": "4.1.2", @@ -2341,9 +2347,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001278", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz", - "integrity": "sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==", + "version": "1.0.30001336", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001336.tgz", + "integrity": "sha512-/YxSlBmL7iKXTbIJ48IQTnAOBk7XmWsxhBF1PZLOko5Dt9qc4Pl+84lfqG3Tc4EuavurRn1QLoVJGxY2iSycfw==", "dev": true }, "chalk": { From e5f560b0ab4668d989adb4cd4adbecb796db0d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20B=C5=82aszk=C3=B3w?= Date: Fri, 6 May 2022 11:59:25 +0200 Subject: [PATCH 2/3] Fix overconstrained error, adjust constraints --- assets/src/consts.ts | 18 +++++++----- assets/src/room.ts | 69 ++++++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/assets/src/consts.ts b/assets/src/consts.ts index 3389b155..a05de558 100644 --- a/assets/src/consts.ts +++ b/assets/src/consts.ts @@ -1,16 +1,20 @@ -export const AUDIO_MEDIA_CONSTRAINTS: MediaStreamConstraints = { - audio: true, - video: false, +export const AUDIO_TRACK_CONSTRAINTS: MediaTrackConstraints = { + advanced: [ + { autoGainControl: true }, + { noiseSuppression: true }, + { echoCancellation: true }, + ], }; -export const VIDEO_MEDIA_CONSTRAINTS: MediaStreamConstraints = { - audio: false, - video: { width: 1280, height: 720, frameRate: 24 }, +export const VIDEO_TRACK_CONSTRAINTS: MediaTrackConstraints = { + width: { max: 1280, ideal: 1280, min: 640 }, + height: { max: 720, ideal: 720, min: 320 }, + frameRate: { max: 30, ideal: 24 }, }; export const SCREENSHARING_MEDIA_CONSTRAINTS: DisplayMediaStreamConstraints = { video: { - frameRate: { ideal: 20, max: 25 }, + frameRate: { ideal: 10, max: 15 }, }, }; diff --git a/assets/src/room.ts b/assets/src/room.ts index 79ba5be5..c69ca856 100644 --- a/assets/src/room.ts +++ b/assets/src/room.ts @@ -1,32 +1,31 @@ import { + AUDIO_TRACK_CONSTRAINTS, LOCAL_PEER_ID, - AUDIO_MEDIA_CONSTRAINTS, - VIDEO_MEDIA_CONSTRAINTS, SCREENSHARING_MEDIA_CONSTRAINTS, - BANDWIDTH_LIMITS, + VIDEO_TRACK_CONSTRAINTS, } from "./consts"; +import { + MembraneWebRTC, + Peer, + SerializedMediaEvent, + TrackContext, + TrackEncoding, +} from "membrane_rtc_engine"; +import { Push, Socket } from "phoenix"; import { addVideoElement, + attachScreensharing, + attachStream, + detachScreensharing, getRoomId, removeVideoElement, setErrorMessage, setParticipantsList, - attachStream, setupControls, - terminateScreensharing, - attachScreensharing, - detachScreensharing, toggleScreensharing, updateTrackEncoding, } from "./room_ui"; -import { - MembraneWebRTC, - Peer, - SerializedMediaEvent, - TrackContext, - TrackEncoding, -} from "membrane_rtc_engine"; -import { Push, Socket } from "phoenix"; + import { parse } from "query-string"; export class Room { @@ -68,7 +67,7 @@ export class Room { this.webrtcChannel.push("mediaEvent", { data: mediaEvent }); }, onConnectionError: setErrorMessage, - onJoinSuccess: (peerId, peersInRoom) => { + onJoinSuccess: (_peerId, peersInRoom) => { this.localAudioStream ?.getTracks() .forEach((track) => @@ -80,7 +79,7 @@ export class Room { track, this.localVideoStream!, {}, - {enabled: true, active_encodings: ["l", "m"]} + { enabled: true, active_encodings: ["l", "m"] } ); }); @@ -94,7 +93,7 @@ export class Room { }); this.updateParticipantsList(); }, - onJoinError: (metadata) => { + onJoinError: (_metadata) => { throw `Peer denied.`; }, onTrackReady: (ctx) => { @@ -112,7 +111,7 @@ export class Room { } this.tracks.get(ctx.peer.id)?.push(ctx); }, - onTrackAdded: (ctx) => {}, + onTrackAdded: (_ctx) => {}, onTrackRemoved: (ctx) => { if (ctx.metadata.type === "screensharing") { detachScreensharing(ctx.peer.id); @@ -137,10 +136,10 @@ export class Room { removeVideoElement(peer.id); this.updateParticipantsList(); }, - onPeerUpdated: (ctx) => {}, + onPeerUpdated: (_ctx) => {}, onTrackEncodingChanged: ( peerId: string, - trackId: string, + _trackId: string, encoding: string ) => { updateTrackEncoding(peerId, encoding); @@ -154,13 +153,15 @@ export class Room { } public init = async () => { - try { - this.localAudioStream = await navigator.mediaDevices.getUserMedia( - AUDIO_MEDIA_CONSTRAINTS - ); - } catch (error) { - console.error("Error while getting local audio stream", error); - } + const hasVideoInput: boolean = ( + await navigator.mediaDevices.enumerateDevices() + ).some((device) => device.kind === "videoinput"); + + // Ask browser for permissions + await navigator.mediaDevices.getUserMedia({ + audio: true, + video: hasVideoInput, + }); const mediaDevices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = mediaDevices.filter( @@ -168,11 +169,9 @@ export class Room { ); for (const device of videoDevices) { - const video = VIDEO_MEDIA_CONSTRAINTS.video as MediaTrackConstraints; const constraints = { - ...VIDEO_MEDIA_CONSTRAINTS, video: { - ...video, + ...VIDEO_TRACK_CONSTRAINTS, deviceId: { exact: device.deviceId }, }, }; @@ -188,6 +187,14 @@ export class Room { } } + try { + this.localAudioStream = await navigator.mediaDevices.getUserMedia({ + audio: AUDIO_TRACK_CONSTRAINTS, + }); + } catch (error) { + console.error("Error while getting local audio stream", error); + } + addVideoElement(LOCAL_PEER_ID, "Me", true, { onSelectLocalEncoding: this.onSelectLocalEncoding, onSelectRemoteEncoding: null, From e794fbab42eb792c2dc344f933417f2fd79b0261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20B=C5=82aszk=C3=B3w?= Date: Fri, 6 May 2022 16:53:01 +0200 Subject: [PATCH 3/3] Add more comments --- assets/src/room.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/src/room.ts b/assets/src/room.ts index c69ca856..3e9b95a7 100644 --- a/assets/src/room.ts +++ b/assets/src/room.ts @@ -157,12 +157,14 @@ export class Room { await navigator.mediaDevices.enumerateDevices() ).some((device) => device.kind === "videoinput"); - // Ask browser for permissions + // Ask user for permissions if required await navigator.mediaDevices.getUserMedia({ audio: true, video: hasVideoInput, }); + // Refresh mediaDevices list after ensuring permissions are granted + // Before that, enumerateDevices() call would not return deviceIds const mediaDevices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = mediaDevices.filter( (device) => device.kind === "videoinput"