How to use remoteVideo method in wpt

Best JavaScript code snippet using wpt

VideoLayout.js

Source:VideoLayout.js Github

copy

Full Screen

1/* global APP */2import Logger from 'jitsi-meet-logger';3import { MEDIA_TYPE, VIDEO_TYPE } from '../../../react/features/base/media';4import {5 getLocalParticipant as getLocalParticipantFromStore,6 getPinnedParticipant,7 getParticipantById,8 pinParticipant9} from '../../../react/features/base/participants';10import { getTrackByMediaTypeAndParticipant } from '../../../react/features/base/tracks';11import UIEvents from '../../../service/UI/UIEvents';12import { SHARED_VIDEO_CONTAINER_TYPE } from '../shared_video/SharedVideo';13import SharedVideoThumb from '../shared_video/SharedVideoThumb';14import LargeVideoManager from './LargeVideoManager';15import LocalVideo from './LocalVideo';16import RemoteVideo from './RemoteVideo';17import { VIDEO_CONTAINER_TYPE } from './VideoContainer';18const logger = Logger.getLogger(__filename);19const remoteVideos = {};20let localVideoThumbnail = null;21let eventEmitter = null;22let largeVideo;23/**24 * flipX state of the localVideo25 */26let localFlipX = null;27/**28 * Handler for local flip X changed event.29 * @param {Object} val30 */31function onLocalFlipXChanged(val) {32 localFlipX = val;33 if (largeVideo) {34 largeVideo.onLocalFlipXChange(val);35 }36}37/**38 * Returns an array of all thumbnails in the filmstrip.39 *40 * @private41 * @returns {Array}42 */43function getAllThumbnails() {44 return [45 ...localVideoThumbnail ? [ localVideoThumbnail ] : [],46 ...Object.values(remoteVideos)47 ];48}49/**50 * Private helper to get the redux representation of the local participant.51 *52 * @private53 * @returns {Object}54 */55function getLocalParticipant() {56 return getLocalParticipantFromStore(APP.store.getState());57}58const VideoLayout = {59 init(emitter) {60 eventEmitter = emitter;61 localVideoThumbnail = new LocalVideo(62 VideoLayout,63 emitter,64 this._updateLargeVideoIfDisplayed.bind(this));65 this.registerListeners();66 },67 /**68 * Registering listeners for UI events in Video layout component.69 *70 * @returns {void}71 */72 registerListeners() {73 eventEmitter.addListener(UIEvents.LOCAL_FLIPX_CHANGED,74 onLocalFlipXChanged);75 },76 /**77 * Cleans up state of this singleton {@code VideoLayout}.78 *79 * @returns {void}80 */81 reset() {82 this._resetLargeVideo();83 this._resetFilmstrip();84 },85 initLargeVideo() {86 this._resetLargeVideo();87 largeVideo = new LargeVideoManager(eventEmitter);88 if (localFlipX) {89 largeVideo.onLocalFlipXChange(localFlipX);90 }91 largeVideo.updateContainerSize();92 },93 /**94 * Sets the audio level of the video elements associated to the given id.95 *96 * @param id the video identifier in the form it comes from the library97 * @param lvl the new audio level to update to98 */99 setAudioLevel(id, lvl) {100 const smallVideo = this.getSmallVideo(id);101 if (smallVideo) {102 smallVideo.updateAudioLevelIndicator(lvl);103 }104 if (largeVideo && id === largeVideo.id) {105 largeVideo.updateLargeVideoAudioLevel(lvl);106 }107 },108 changeLocalVideo(stream) {109 const localId = getLocalParticipant().id;110 this.onVideoTypeChanged(localId, stream.videoType);111 localVideoThumbnail.changeVideo(stream);112 this._updateLargeVideoIfDisplayed(localId);113 },114 /**115 * Get's the localID of the conference and set it to the local video116 * (small one). This needs to be called as early as possible, when muc is117 * actually joined. Otherwise events can come with information like email118 * and setting them assume the id is already set.119 */120 mucJoined() {121 // FIXME: replace this call with a generic update call once SmallVideo122 // only contains a ReactElement. Then remove this call once the123 // Filmstrip is fully in React.124 localVideoThumbnail.updateIndicators();125 },126 /**127 * Shows/hides local video.128 * @param {boolean} true to make the local video visible, false - otherwise129 */130 setLocalVideoVisible(visible) {131 localVideoThumbnail.setVisible(visible);132 },133 onRemoteStreamAdded(stream) {134 const id = stream.getParticipantId();135 const remoteVideo = remoteVideos[id];136 logger.debug(`Received a new ${stream.getType()} stream for ${id}`);137 if (!remoteVideo) {138 logger.debug('No remote video element to add stream');139 return;140 }141 remoteVideo.addRemoteStreamElement(stream);142 // Make sure track's muted state is reflected143 if (stream.getType() !== 'audio') {144 this.onVideoMute(id);145 remoteVideo.updateView();146 }147 },148 onRemoteStreamRemoved(stream) {149 const id = stream.getParticipantId();150 const remoteVideo = remoteVideos[id];151 // Remote stream may be removed after participant left the conference.152 if (remoteVideo) {153 remoteVideo.removeRemoteStreamElement(stream);154 remoteVideo.updateView();155 }156 this.updateMutedForNoTracks(id, stream.getType());157 },158 /**159 * FIXME get rid of this method once muted indicator are reactified (by160 * making sure that user with no tracks is displayed as muted )161 *162 * If participant has no tracks will make the UI display muted status.163 * @param {string} participantId164 * @param {string} mediaType 'audio' or 'video'165 */166 updateMutedForNoTracks(participantId, mediaType) {167 const participant = APP.conference.getParticipantById(participantId);168 if (participant && !participant.getTracksByMediaType(mediaType).length) {169 if (mediaType === 'audio') {170 APP.UI.setAudioMuted(participantId, true);171 } else if (mediaType === 'video') {172 APP.UI.setVideoMuted(participantId);173 } else {174 logger.error(`Unsupported media type: ${mediaType}`);175 }176 }177 },178 /**179 * Return the type of the remote video.180 * @param id the id for the remote video181 * @returns {String} the video type video or screen.182 */183 getRemoteVideoType(id) {184 const state = APP.store.getState();185 const participant = getParticipantById(state, id);186 if (participant?.isFakeParticipant) {187 return SHARED_VIDEO_CONTAINER_TYPE;188 }189 const videoTrack = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);190 return videoTrack?.videoType;191 },192 isPinned(id) {193 return id === this.getPinnedId();194 },195 getPinnedId() {196 const { id } = getPinnedParticipant(APP.store.getState()) || {};197 return id || null;198 },199 /**200 * Triggers a thumbnail to pin or unpin itself.201 *202 * @param {number} videoNumber - The index of the video to toggle pin on.203 * @private204 */205 togglePin(videoNumber) {206 const videos = getAllThumbnails();207 const videoView = videos[videoNumber];208 videoView && videoView.togglePin();209 },210 /**211 * Callback invoked to update display when the pin participant has changed.212 *213 * @paramn {string|null} pinnedParticipantID - The participant ID of the214 * participant that is pinned or null if no one is pinned.215 * @returns {void}216 */217 onPinChange(pinnedParticipantID) {218 getAllThumbnails().forEach(thumbnail =>219 thumbnail.focus(pinnedParticipantID === thumbnail.getId()));220 },221 /**222 * Creates a participant container for the given id.223 *224 * @param {Object} participant - The redux representation of a remote225 * participant.226 * @returns {void}227 */228 addRemoteParticipantContainer(participant) {229 if (!participant || participant.local) {230 return;231 } else if (participant.isFakeParticipant) {232 const sharedVideoThumb = new SharedVideoThumb(233 participant,234 SHARED_VIDEO_CONTAINER_TYPE,235 VideoLayout);236 this.addRemoteVideoContainer(participant.id, sharedVideoThumb);237 return;238 }239 const id = participant.id;240 const jitsiParticipant = APP.conference.getParticipantById(id);241 const remoteVideo = new RemoteVideo(jitsiParticipant, VideoLayout);242 this._setRemoteControlProperties(jitsiParticipant, remoteVideo);243 this.addRemoteVideoContainer(id, remoteVideo);244 this.updateMutedForNoTracks(id, 'audio');245 this.updateMutedForNoTracks(id, 'video');246 },247 /**248 * Adds remote video container for the given id and <tt>SmallVideo</tt>.249 *250 * @param {string} the id of the video to add251 * @param {SmallVideo} smallVideo the small video instance to add as a252 * remote video253 */254 addRemoteVideoContainer(id, remoteVideo) {255 remoteVideos[id] = remoteVideo;256 // Initialize the view257 remoteVideo.updateView();258 },259 /**260 * On video muted event.261 */262 onVideoMute(id) {263 if (APP.conference.isLocalId(id)) {264 localVideoThumbnail && localVideoThumbnail.updateView();265 } else {266 const remoteVideo = remoteVideos[id];267 if (remoteVideo) {268 remoteVideo.updateView();269 }270 }271 // large video will show avatar instead of muted stream272 this._updateLargeVideoIfDisplayed(id, true);273 },274 /**275 * Display name changed.276 */277 onDisplayNameChanged(id) {278 if (id === 'localVideoContainer'279 || APP.conference.isLocalId(id)) {280 localVideoThumbnail.updateDisplayName();281 } else {282 const remoteVideo = remoteVideos[id];283 if (remoteVideo) {284 remoteVideo.updateDisplayName();285 }286 }287 },288 /**289 * On dominant speaker changed event.290 *291 * @param {string} id - The participant ID of the new dominant speaker.292 * @returns {void}293 */294 onDominantSpeakerChanged(id) {295 getAllThumbnails().forEach(thumbnail =>296 thumbnail.showDominantSpeakerIndicator(id === thumbnail.getId()));297 },298 /**299 * Shows/hides warning about a user's connectivity issues.300 *301 * @param {string} id - The ID of the remote participant(MUC nickname).302 * @returns {void}303 */304 onParticipantConnectionStatusChanged(id) {305 if (APP.conference.isLocalId(id)) {306 return;307 }308 // We have to trigger full large video update to transition from309 // avatar to video on connectivity restored.310 this._updateLargeVideoIfDisplayed(id, true);311 const remoteVideo = remoteVideos[id];312 if (remoteVideo) {313 remoteVideo.updateView();314 }315 },316 /**317 * On last N change event.318 *319 * @param endpointsLeavingLastN the list currently leaving last N320 * endpoints321 * @param endpointsEnteringLastN the list currently entering last N322 * endpoints323 */324 onLastNEndpointsChanged(endpointsLeavingLastN, endpointsEnteringLastN) {325 if (endpointsLeavingLastN) {326 endpointsLeavingLastN.forEach(this._updateRemoteVideo, this);327 }328 if (endpointsEnteringLastN) {329 endpointsEnteringLastN.forEach(this._updateRemoteVideo, this);330 }331 },332 /**333 * Updates remote video by id if it exists.334 * @param {string} id of the remote video335 * @private336 */337 _updateRemoteVideo(id) {338 const remoteVideo = remoteVideos[id];339 if (remoteVideo) {340 remoteVideo.updateView();341 this._updateLargeVideoIfDisplayed(id);342 }343 },344 /**345 * Hides all the indicators346 */347 hideStats() {348 for (const video in remoteVideos) { // eslint-disable-line guard-for-in349 const remoteVideo = remoteVideos[video];350 if (remoteVideo) {351 remoteVideo.removeConnectionIndicator();352 }353 }354 localVideoThumbnail.removeConnectionIndicator();355 },356 removeParticipantContainer(id) {357 // Unlock large video358 if (this.getPinnedId() === id) {359 logger.info('Focused video owner has left the conference');360 APP.store.dispatch(pinParticipant(null));361 }362 const remoteVideo = remoteVideos[id];363 if (remoteVideo) {364 // Remove remote video365 logger.info(`Removing remote video: ${id}`);366 delete remoteVideos[id];367 remoteVideo.remove();368 } else {369 logger.warn(`No remote video for ${id}`);370 }371 },372 onVideoTypeChanged(id, newVideoType) {373 const remoteVideo = remoteVideos[id];374 if (!remoteVideo) {375 return;376 }377 logger.info('Peer video type changed: ', id, newVideoType);378 remoteVideo.updateView();379 },380 /**381 * Resizes the video area.382 */383 resizeVideoArea() {384 if (largeVideo) {385 largeVideo.updateContainerSize();386 largeVideo.resize(false);387 }388 },389 getSmallVideo(id) {390 if (APP.conference.isLocalId(id)) {391 return localVideoThumbnail;392 }393 return remoteVideos[id];394 },395 changeUserAvatar(id, avatarUrl) {396 const smallVideo = VideoLayout.getSmallVideo(id);397 if (smallVideo) {398 smallVideo.initializeAvatar();399 } else {400 logger.warn(401 `Missed avatar update - no small video yet for ${id}`402 );403 }404 if (this.isCurrentlyOnLarge(id)) {405 largeVideo.updateAvatar(avatarUrl);406 }407 },408 isLargeVideoVisible() {409 return this.isLargeContainerTypeVisible(VIDEO_CONTAINER_TYPE);410 },411 /**412 * @return {LargeContainer} the currently displayed container on large413 * video.414 */415 getCurrentlyOnLargeContainer() {416 return largeVideo.getCurrentContainer();417 },418 isCurrentlyOnLarge(id) {419 return largeVideo && largeVideo.id === id;420 },421 /**422 * Triggers an update of remote video and large video displays so they may423 * pick up any state changes that have occurred elsewhere.424 *425 * @returns {void}426 */427 updateAllVideos() {428 const displayedUserId = this.getLargeVideoID();429 if (displayedUserId) {430 this.updateLargeVideo(displayedUserId, true);431 }432 Object.keys(remoteVideos).forEach(video => {433 remoteVideos[video].updateView();434 });435 },436 updateLargeVideo(id, forceUpdate) {437 if (!largeVideo) {438 return;439 }440 const currentContainer = largeVideo.getCurrentContainer();441 const currentContainerType = largeVideo.getCurrentContainerType();442 const isOnLarge = this.isCurrentlyOnLarge(id);443 const state = APP.store.getState();444 const videoTrack = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);445 const videoStream = videoTrack?.jitsiTrack;446 if (isOnLarge && !forceUpdate447 && LargeVideoManager.isVideoContainer(currentContainerType)448 && videoStream) {449 const currentStreamId = currentContainer.getStreamID();450 const newStreamId = videoStream?.getId() || null;451 // FIXME it might be possible to get rid of 'forceUpdate' argument452 if (currentStreamId !== newStreamId) {453 logger.debug('Enforcing large video update for stream change');454 forceUpdate = true; // eslint-disable-line no-param-reassign455 }456 }457 if (!isOnLarge || forceUpdate) {458 const videoType = this.getRemoteVideoType(id);459 largeVideo.updateLargeVideo(460 id,461 videoStream,462 videoType || VIDEO_TYPE.CAMERA463 ).catch(() => {464 // do nothing465 });466 }467 },468 addLargeVideoContainer(type, container) {469 largeVideo && largeVideo.addContainer(type, container);470 },471 removeLargeVideoContainer(type) {472 largeVideo && largeVideo.removeContainer(type);473 },474 /**475 * @returns Promise476 */477 showLargeVideoContainer(type, show) {478 if (!largeVideo) {479 return Promise.reject();480 }481 const isVisible = this.isLargeContainerTypeVisible(type);482 if (isVisible === show) {483 return Promise.resolve();484 }485 const currentId = largeVideo.id;486 let oldSmallVideo;487 if (currentId) {488 oldSmallVideo = this.getSmallVideo(currentId);489 }490 let containerTypeToShow = type;491 // if we are hiding a container and there is focusedVideo492 // (pinned remote video) use its video type,493 // if not then use default type - large video494 if (!show) {495 const pinnedId = this.getPinnedId();496 if (pinnedId) {497 containerTypeToShow = this.getRemoteVideoType(pinnedId);498 } else {499 containerTypeToShow = VIDEO_CONTAINER_TYPE;500 }501 }502 return largeVideo.showContainer(containerTypeToShow)503 .then(() => {504 if (oldSmallVideo) {505 oldSmallVideo && oldSmallVideo.updateView();506 }507 });508 },509 isLargeContainerTypeVisible(type) {510 return largeVideo && largeVideo.state === type;511 },512 /**513 * Returns the id of the current video shown on large.514 * Currently used by tests (torture).515 */516 getLargeVideoID() {517 return largeVideo && largeVideo.id;518 },519 /**520 * Returns the the current video shown on large.521 * Currently used by tests (torture).522 */523 getLargeVideo() {524 return largeVideo;525 },526 /**527 * Sets the flipX state of the local video.528 * @param {boolean} true for flipped otherwise false;529 */530 setLocalFlipX(val) {531 this.localFlipX = val;532 },533 /**534 * Handles user's features changes.535 */536 onUserFeaturesChanged(user) {537 const video = this.getSmallVideo(user.getId());538 if (!video) {539 return;540 }541 this._setRemoteControlProperties(user, video);542 },543 /**544 * Sets the remote control properties (checks whether remote control545 * is supported and executes remoteVideo.setRemoteControlSupport).546 * @param {JitsiParticipant} user the user that will be checked for remote547 * control support.548 * @param {RemoteVideo} remoteVideo the remoteVideo on which the properties549 * will be set.550 */551 _setRemoteControlProperties(user, remoteVideo) {552 APP.remoteControl.checkUserRemoteControlSupport(user)553 .then(result => remoteVideo.setRemoteControlSupport(result))554 .catch(error =>555 logger.warn(`could not get remote control properties for: ${user.getJid()}`, error));556 },557 /**558 * Returns the wrapper jquery selector for the largeVideo559 * @returns {JQuerySelector} the wrapper jquery selector for the largeVideo560 */561 getLargeVideoWrapper() {562 return this.getCurrentlyOnLargeContainer().$wrapper;563 },564 /**565 * Returns the number of remove video ids.566 *567 * @returns {number} The number of remote videos.568 */569 getRemoteVideosCount() {570 return Object.keys(remoteVideos).length;571 },572 /**573 * Sets the remote control active status for a remote participant.574 *575 * @param {string} participantID - The id of the remote participant.576 * @param {boolean} isActive - The new remote control active status.577 * @returns {void}578 */579 setRemoteControlActiveStatus(participantID, isActive) {580 remoteVideos[participantID].setRemoteControlActiveStatus(isActive);581 },582 /**583 * Sets the remote control active status for the local participant.584 *585 * @returns {void}586 */587 setLocalRemoteControlActiveChanged() {588 Object.values(remoteVideos).forEach(589 remoteVideo => remoteVideo.updateRemoteVideoMenu()590 );591 },592 /**593 * Helper method to invoke when the video layout has changed and elements594 * have to be re-arranged and resized.595 *596 * @returns {void}597 */598 refreshLayout() {599 localVideoThumbnail && localVideoThumbnail.updateDOMLocation();600 VideoLayout.resizeVideoArea();601 // Rerender the thumbnails since they are dependant on the layout because of the tooltip positioning.602 localVideoThumbnail && localVideoThumbnail.rerender();603 Object.values(remoteVideos).forEach(remoteVideoThumbnail => remoteVideoThumbnail.rerender());604 },605 /**606 * Cleans up any existing largeVideo instance.607 *608 * @private609 * @returns {void}610 */611 _resetLargeVideo() {612 if (largeVideo) {613 largeVideo.destroy();614 }615 largeVideo = null;616 },617 /**618 * Cleans up filmstrip state. While a separate {@code Filmstrip} exists, its619 * implementation is mainly for querying and manipulating the DOM while620 * state mostly remains in {@code VideoLayout}.621 *622 * @private623 * @returns {void}624 */625 _resetFilmstrip() {626 Object.keys(remoteVideos).forEach(remoteVideoId => {627 this.removeParticipantContainer(remoteVideoId);628 delete remoteVideos[remoteVideoId];629 });630 if (localVideoThumbnail) {631 localVideoThumbnail.remove();632 localVideoThumbnail = null;633 }634 },635 /**636 * Triggers an update of large video if the passed in participant is637 * currently displayed on large video.638 *639 * @param {string} participantId - The participant ID that should trigger an640 * update of large video if displayed.641 * @param {boolean} force - Whether or not the large video update should642 * happen no matter what.643 * @returns {void}644 */645 _updateLargeVideoIfDisplayed(participantId, force = false) {646 if (this.isCurrentlyOnLarge(participantId)) {647 this.updateLargeVideo(participantId, force);648 }649 },650 /**651 * Handles window resizes.652 */653 onResize() {654 VideoLayout.resizeVideoArea();655 }656};...

Full Screen

Full Screen

App.js

Source:App.js Github

copy

Full Screen

1import { useEffect, useRef, useState } from "react";2import { io } from "socket.io-client";3import Peer from 'peerjs';4let socket = null;5let peer = null;6let currentCall = null;7function Loading() {8 return (9 <svg10 className="spinner"11 xmlns="http://www.w3.org/2000/svg"12 fill="none"13 viewBox="0 0 24 24"14 >15 <path16 fill="#FFFFFF"17 d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"18 />19 </svg>20 )21}22function App() {23 const myVideo = useRef();24 const remoteVideo = useRef()25 const [started, setStarted] = useState(null);26 const [peerId, setPeerId] = useState(null);27 const [isTalking, setIsTalking] = useState(false);28 const [permission, setPermission] = useState(false);29 useEffect(() => {30 navigator.mediaDevices.getUserMedia({ video: true, audio: { echoCancellation: true, noiseSuppression: true } })31 .then(stream => {32 myVideo.current.srcObject = stream;33 myVideo.current.volume = 0;34 myVideo.current.muted = true;35 myVideo.current.play();36 setPermission(true);37 socket = io();38 socket.on("new-user", ({ peer_id, remote_peer_id }) => {39 setStarted(true);40 setPeerId(peer_id);41 peer = new Peer(peer_id);42 peer.on("open", id => {43 if(remote_peer_id != null) {44 callPeer(stream, remote_peer_id)45 }46 })47 peer.on("call", function(call) {48 call.answer(stream);49 call.on('stream', function(remoteStream) {50 remoteVideo.current.srcObject = remoteStream;51 remoteVideo.current.play();52 });53 setIsTalking(true);54 currentCall = call 55 });56 })57 socket.on("peer-disconnected", ({ new_remote_peer_id }) => {58 currentCall?.close();59 remoteVideo.current.pause();60 remoteVideo.current.removeAttribute('src'); // empty source61 remoteVideo.current.load();62 setIsTalking(false);63 if(new_remote_peer_id !== null) {64 callPeer(stream, new_remote_peer_id);65 }66 })67 socket.on("new-peer", ({ new_remote_peer_id }) => {68 setStarted(true);69 if(new_remote_peer_id !== null) {70 callPeer(stream, new_remote_peer_id);71 }72 })73 })74 .catch(error => {75 console.log(error);76 setPermission(false);77 })78 return () => socket.disconnect(); //cleanup79 }, [])80 const onClickStart = () => {81 if(!permission) return;82 if(!started && peerId === null) {83 socket.emit("new-user");84 }85 else if(!started && peerId !== null) {86 socket.emit("start");87 }88 else if(started && peerId !== null) {89 currentCall?.close();90 remoteVideo.current.pause();91 remoteVideo.current.removeAttribute('src');92 remoteVideo.current.load();93 setIsTalking(false);94 socket.emit("next");95 }96 }97 const onClickStop = () => {98 if(!started) return;99 currentCall?.close();100 remoteVideo.current.pause();101 remoteVideo.current.removeAttribute('src');102 remoteVideo.current.load();103 setIsTalking(false);104 setStarted(false);105 socket.emit("stop");106 }107 const callPeer = (stream, peer_id) => {108 var call = peer.call(peer_id, stream);109 call.on('stream', remoteStream => { 110 remoteVideo.current.srcObject = remoteStream;111 remoteVideo.current.play();112 setIsTalking(true);113 });114 }115 return (116 <div className="container">117 <div className="leftSection">118 <div className="video">119 <video muted ref={myVideo} />120 {!started && <span style={{textAlign: "center", color: "white"}}>To get started, please allow camera and microphone access. Then click to start button.</span>}121 </div>122 <div className="buttons">123 <button onClick={onClickStart} className="btnNext">{!started ? "Start" : "Next"}</button>124 <button onClick={onClickStop} disabled={!started} className="btnStop">Stop</button>125 </div>126 </div>127 <div className="rightSection">128 <div className="video">129 <video ref={remoteVideo} />130 {started === true && isTalking === false ? <Loading/> : null}131 </div>132 </div>133 </div>134 );135}...

Full Screen

Full Screen

script.js

Source:script.js Github

copy

Full Screen

1window.addEventListener("load", function(e) {2 let header = document.querySelector("h3");3 let peerID = document.querySelector("#peer-id");4 let callBtn = document.querySelector("#call-peer");5 let remoteVideo = document.querySelector("#remote-video");6 let connectBtn = this.document.querySelector("#connect-btn");7 8 let peer = new Peer({9 config: {10 'iceServers': [11 { url: 'stun:stun1.l.google.com:19302' },12 {13 url: 'turn:numb.viagenie.ca',14 credential: 'muazkh',15 username: 'webrtc@live.com'16 }17 ]18 }19 });20 peer.on("open", function(id) {21 header.textContent = id;22 })23 peer.on("connection", function(connection) {24 alert(`Connection success with ${connection.peer}`);25 })26 connectBtn.addEventListener("click", function(e) {27 if (peerID.value) {28 header.textContent = `Connecting to peer...${peerID.value}`;29 peer.connect(peerID.value);30 }31 else {32 alert("Enter ID to connect with peer..");33 }34 })35 peer.on("call", function(call) {36 navigator.mediaDevices.getUserMedia({37 video: true,38 auido: true39 })40 .then(function(videoStream) {41 call.answer(videoStream);42 call.on("stream", function(stream) {43 addVideoToStream(stream);44 })45 })46 .catch(function(err) {47 console.log(err, "..media connection failed!!");48 })49 })50 callBtn.addEventListener("click",function(e) {51 navigator.mediaDevices.getDisplayMedia({52 video: true53 })54 .then(function(screenStream) {55 navigator.mediaDevices.getUserMedia({56 audio: true57 })58 .then(function(audioStream) {59 let [videoTrack] = screenStream.getVideoTracks();60 let [audioTrack] = audioStream.getAudioTracks();61 62 let combinedStream = new MediaStream([ videoTrack, audioTrack ]);63 64 let call = peer.call(peerID.value, combinedStream);65 call.on("stream", function(stream) {66 addVideoToStream(stream);67 })68 })69 }) 70 })71 function addVideoToStream(stream) {72 remoteVideo.srcObject = stream;73 remoteVideo.load();74 remoteVideo.addEventListener('loadedmetadata', function () {75 if (remoteVideo.duration === Infinity) {76 remoteVideo.currentTime = 1e101;77 remoteVideo.ontimeupdate = function () {78 remoteVideo.currentTime = 0;79 remoteVideo.ontimeupdate = function () {80 delete remoteVideo.ontimeupdate;81 let isPlaying = (remoteVideo.currentTime > 0) && 82 (!remoteVideo.paused) && (!remoteVideo.ended) && (remoteVideo.readyState > 2);83 if (isPlaying) {84 remoteVideo.play();85 }86 };87 };88 }89 });90 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1});2});3});4});5});6});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var test = new wpt('API_KEY');3}, function(err, data) {4 if (err) {5 console.log(err);6 } else {7 console.log(data);8 }9});10var wpt = require('webpagetest');11var test = new wpt('API_KEY');12}, function(err, data) {13 if (err) {14 console.log(err);15 } else {16 console.log(data);17 }18});19var wpt = require('webpagetest');20var test = new wpt('API_KEY');21}, function(err, data) {22 if (err) {23 console.log(err);24 } else {25 console.log(data);26 }27});28var wpt = require('webpagetest');29var test = new wpt('API_KEY');30}, function(err, data) {31 if (err) {32 console.log(err);33 } else {34 console.log(data);35 }36});37var wpt = require('webpagetest');38var test = new wpt('API_KEY');39}, function(err, data) {40 if (err) {41 console.log(err);42 } else {43 console.log(data);44 }45});46var wpt = require('web

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var wp = new wptools('India');3wp.remoteVideo()4 .then(function(result){5 console.log(result);6 })7 .catch(function(err){8 console.log(err);9 });10[ { id: '2Z4m4lnjxk8',11 { id: 'x9hU5m5n5aA',12 { id: 'w2d1Kl3tq8o',13 { id: 'IzY7sZ8WJZs',

Full Screen

Using AI Code Generation

copy

Full Screen

1 if (err) {2 console.log(err);3 } else {4 console.log(video);5 }6});7 if (err) {8 console.log(err);9 } else {10 console.log(video);11 }12});13 if (err) {14 console.log(err);15 } else {16 console.log(video);17 }18});19 if (err) {20 console.log(err);21 } else {22 console.log(video);23 }24});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var test = wpt('www.webpagetest.org', 'A.1e5c9e9b5f0b5c0d5f5e5c5c5e5b5c5f5');3test.runTest(url, {4}, function(err, data) {5 if (err) {6 console.error(err);7 } else {8 console.log(data);9 }10});11var wpt = require('webpagetest');12var test = wpt('www.webpagetest.org', 'A.1e5c9e9b5f0b5c0d5f5e5c5c5e5b5c5f5');13test.runTest(url, {14}, function(err, data) {15 if (err) {16 console.error(err);17 } else {18 console.log(data);19 }20});21var wpt = require('webpagetest');22var test = wpt('www.webpagetest.org', 'A.1e5c9e9b5f0b5c0d5f5e5c5c5e5b5c5f5');23test.runTest(url, {24}, function(err, data) {25 if (err) {26 console.error(err);27 } else {28 console.log(data);29 }30});31var wpt = require('webpagetest');32var test = wpt('www.webpagetest.org', 'A.1e5c9e9b5f0b5c0d5f5e5c5c5e5b5c5f5');33test.runTest(url, {

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var remoteVideo = wptools.remoteVideo;3var options = {4};5remoteVideo(options, function(err, resp) {6 if (err) {7 console.log(err);8 } else {9 console.log(resp);10 }11});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org', 'A.31e4d4c4a8a9c1d1b4d4c4a8a9c1d1b4');3 if (err) return console.log(err);4 console.log('Test Status: ' + data.statusText);5 console.log('Test ID: ' + data.data.testId);6 console.log('Test URL: ' + data.data.summary);7 console.log('View Test: ' + data.data.userUrl);8 wpt.getTestResults(data.data.testId, function(err, data) {9 if (err) return console.log(err);10 var video = data.data.runs[1].firstView.videoFrames;11 console.log('Video Frames: ' + video);12 });13});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var options = {3};4var wpt = new WebPageTest('www.webpagetest.org', options.key);5var runTest = function (url) {6 wpt.runTest(url, function (err, data) {7 if (err) {8 console.log(err);9 } else {10 console.log(data);11 }12 });13};14module.exports = {15};16var wpt = require('webpagetest');17var options = {18};19var wpt = new WebPageTest('www.webpagetest.org', options.key);20var runTest = function (url) {21 wpt.runTest(url, function (err, data) {22 if (err) {23 console.log(err);24 } else {25 console.log(data);26 }27 });28};29module.exports = {30};31var wpt = require('webpagetest');32var options = {33};34var wpt = new WebPageTest('www.webpagetest.org', options.key);35var runTest = function (url) {36 wpt.runTest(url, function (err, data) {37 if (err) {38 console.log(err);39 } else {40 console.log(data);41 }42 });43};44module.exports = {

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run wpt automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful