{"id":154,"date":"2021-04-03T22:48:38","date_gmt":"2021-04-03T22:48:38","guid":{"rendered":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/?p=154"},"modified":"2021-04-03T23:42:55","modified_gmt":"2021-04-03T23:42:55","slug":"jacksons-status-report-for-4-3","status":"publish","type":"post","link":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/2021\/04\/03\/jacksons-status-report-for-4-3\/","title":{"rendered":"Jackson&#8217;s Status Report for 4\/3"},"content":{"rendered":"<p>This week, I worked a lot more on monitoring. By the end of last week, I was able to send peer-to-peer text messages between two unique users. This week I extended that to allow for audio streams to be sent, and to work with an arbitrary number of users. These changes required a complete restructuring of all the monitoring code I wrote last week and the week before.<\/p>\n<p>As a reminder, I&#8217;m using the WebRTC (real-time communication) API which comes built-in on your browser. WebRTC uses objects called RTCPeerConnection to communicate. I explained this in detail <a href=\"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/2021\/03\/27\/jacksons-status-report-for-3-27\/\">last week<\/a>, so I won&#8217;t get into it here. The basic idea is that each connection requires both a local RTCPeerConnection object and a remote RTCPeerConnection object. If WebRTC interests you, there are many tutorials online, but <a href=\"https:\/\/www.youtube.com\/watch?v=FExZvpVvYxA\">this one<\/a> has been by far the most helpful to me.<\/p>\n<p><strong>Connections with Multiple Users:<\/strong><\/p>\n<p>Last week, I created one local RTCPeerConnection object and an arbitrary amount of remote RTCPeerConnection objects. This made intuitive sense, since I want to broadcast only one audio stream, while receiving an arbitrary number of audio streams from other users. However, this week I learned that each local connection can only be associated with ONE remote user. To get around this, I created an object class called ConnectionPair. The constructor is simple and will help me explain its use:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-155 size-full\" src=\"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-5.52.03-PM-e1617486896699.png\" alt=\"\" width=\"1576\" height=\"248\" srcset=\"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-5.52.03-PM-e1617486896699.png 1576w, http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-5.52.03-PM-e1617486896699-300x47.png 300w, http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-5.52.03-PM-e1617486896699-768x121.png 768w, http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-5.52.03-PM-e1617486896699-1024x161.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Each peer-to-peer relationship is represented by one of these ConnectionPair objects. Whenever a user chooses to initiate a connection with another user, a ConnectionPair is created with 4 things:<\/p>\n<ol>\n<li>A new local connection object (RTCPeerConnection)<\/li>\n<li>A new remote connection object (RTCPeerConnection)<\/li>\n<li>A gain node object (GainNode from the web audio API) to control how loud you hear the other user)<\/li>\n<li>The other user&#8217;s username (string) which serves as a unique identifier for the ConnectionPair. You can then retrieve any ConnectionPair you&#8217;d like by using another function I wrote, getConnection(&lt;username&gt;), whose meaning is self-evident.<\/li>\n<\/ol>\n<p>So why is this useful? Well, now there can be an arbitrary amount of ConnectionPair objects, and thus you can establish peer-to-peer connections with an arbitrary amount of users!<\/p>\n<p><strong>Sending Audio Over a WebRTC Connection:<\/strong><\/p>\n<p>Since the WebRTC API and the web media API are both browser built-ins, they actually work very nicely with each other.<\/p>\n<p>To access data from a user&#8217;s microphone or camera, the web media API provides you with a function: navigator.MediaDevices.getUserMedia(). This function gives you a MediaStream object, which contains one or more MediaStreamTrack objects (audio and\/or video tracks). Each of these tracks can be added to a local WebRTC connection by the function RTCPeerConnection.addTrack(&lt;track&gt;).<\/p>\n<p>And finally, to receive audio on your remote RTCPeerConnection, you can just use the event handler RTCPeerConnection.ontrack, which is triggered every time the remote connection receives a track. This track can be routed to your browser&#8217;s audio output, any type of AudioNode (for example, a GainNode, which simply changes the volume of an incoming signal), and out.<\/p>\n<p><strong>User Interface Improvements:<\/strong><\/p>\n<p>Finally, I added a little bit to the UI just to test the functionality mentioned above. On the group page, here is how the users are now displayed:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-156 size-full\" src=\"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-6.34.02-PM.png\" alt=\"\" width=\"698\" height=\"554\" srcset=\"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-6.34.02-PM.png 698w, http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-content\/uploads\/sites\/146\/2021\/04\/Screen-Shot-2021-04-03-at-6.34.02-PM-300x238.png 300w\" sizes=\"(max-width: 698px) 100vw, 698px\" \/><\/p>\n<p>In this group, there are 3 members:<\/p>\n<ol>\n<li>Jackson (the user whose screen you&#8217;re looking at in this screenshot)<\/li>\n<li>TestUserFname (a test user, who is currently offline)<\/li>\n<li>OtherTestUserFname (another test user, who is currently online)<\/li>\n<\/ol>\n<p>Next to every online user who isn&#8217;t you, I added a button which says &#8220;send my audio.&#8221; This button initiates a peer-to-peer connection with the user it appears next to. Once the connection is opened, the audio from your microphone is sent to that user.<\/p>\n<p>Lastly, next to each online user, I added a slider for that person&#8217;s volume, allowing users to create their own monitor mixes.<\/p>\n<p>We are still a bit behind schedule, since I thought I would have peer-to-peer audio monitoring working a few weeks ago, but I hope it&#8217;s clear that I&#8217;ve been working very hard, well over 12 hours\/week to get it working! The biggest thing I can do to get us back on schedule is continue working overtime. As I said last week though, I think the hardest part is behind us.<\/p>\n<p>With monitoring finally working, I can move onto testing and really driving the latency down. For next week, I will implement the latency and packet loss tests described in our design review and work on getting the numbers to meet our requirements (&lt;100ms latency and &lt;5% packet loss rate).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This week, I worked a lot more on monitoring. By the end of last week, I was able to send peer-to-peer text messages between two unique users. This week I extended that to allow for audio streams to be sent, and to work with an arbitrary number of users. These changes required a complete restructuring &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/2021\/04\/03\/jacksons-status-report-for-4-3\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Jackson&#8217;s Status Report for 4\/3&#8221;<\/span><\/a><\/p>\n","protected":false},"author":449,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[6],"_links":{"self":[{"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/posts\/154"}],"collection":[{"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/users\/449"}],"replies":[{"embeddable":true,"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/comments?post=154"}],"version-history":[{"count":5,"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/posts\/154\/revisions"}],"predecessor-version":[{"id":163,"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/posts\/154\/revisions\/163"}],"wp:attachment":[{"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/media?parent=154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/categories?post=154"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/course.ece.cmu.edu\/~ece500\/projects\/s21-teamd5\/wp-json\/wp\/v2\/tags?post=154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}