{"id":321,"date":"2018-02-26T17:27:19","date_gmt":"2018-02-26T17:27:19","guid":{"rendered":"https:\/\/blog.mozilla.org\/webrtc\/?p=321"},"modified":"2018-03-23T19:18:53","modified_gmt":"2018-03-23T19:18:53","slug":"when-should-you-display-incoming-webrtc-video","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/","title":{"rendered":"When should you display incoming WebRTC video?"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">The WebRTC specification has changed quite a bit since the first version in 2011. Jan-Ivar gave a great summary of how it has evolved over the years in a <a href=\"https:\/\/blog.mozilla.org\/webrtc\/the-evolution-of-webrtc\/\">previous blog post<\/a>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">One of the central questions for web developers is when to display an incoming video stream.<!--more--> <\/span><\/p>\n<p><span style=\"font-weight: 400;\">In its first iteration, the specification had an <code>addstream<\/code> event (since removed) which was triggered when a remote description was set. The addstream event had a stream object and you would set the video element&#8217;s <code>srcObject<\/code> property to that stream object like shown in this fiddle (which uses the more modern but similar <code>track<\/code> event):<\/span><\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/jsfiddle.net\/kz2khbjv\/12\/embedded\/js,result,html\/\" allow=\"camera; microphone\" width=\"100%\" height=\"480px\" frameborder=\"0\"><\/iframe><\/p>\n<p><span style=\"font-weight: 400;\">For demonstration purposes, this fiddle does not complete a WebRTC connection between the two local objects. It never wires up the ICE candidates. The &#8220;Result&#8221; tab shows we get the <code>track<\/code> event, even though the connection never succeeds. In the early days of WebRTC, there were a lot of cases like this of \u201cthe remote video is a black box\u201d. In particular, this happened when the peer-to-peer connection failed. Such as when a firewall is blocking something:<\/span><\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"500\" data-dnt=\"true\">\n<p lang=\"en\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/janl?ref_src=twsrc%5Etfw\">@janl<\/a> <a href=\"https:\/\/twitter.com\/HenrikJoreteg?ref_src=twsrc%5Etfw\">@HenrikJoreteg<\/a> \ud83d\ude42 I have a slide about \u201cthings we\u2019ve learned from <a href=\"https:\/\/twitter.com\/usetalky?ref_src=twsrc%5Etfw\">@usetalky<\/a>\u201d that says, \u201cJan Lehnardt is always behind a firewall.\u201d<\/p>\n<p>&mdash; Adam Brault (@adambrault) <a href=\"https:\/\/twitter.com\/adambrault\/status\/454658083159941120?ref_src=twsrc%5Etfw\">April 11, 2014<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p><span style=\"font-weight: 400;\">In order to detect this, one has to listen for the <code>iceconnectionstatechange<\/code> event and evaluate it. The <a href=\"https:\/\/webrtc.github.io\/samples\/src\/content\/peerconnection\/states\/\">states demo<\/a> shows how to listen for this state change.\u00a0<\/span><span style=\"font-weight: 400;\">You would show the video when the <code>iceConnectionState<\/code> property of the peer connection changes to <code>\"connected\"<\/code> or <code>\"completed\"<\/code>. This works quite well in simple cases where there is only a single stream.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">With multiple streams, and when adding streams to a connection already in progress, this no longer works. The user might experience a very short period of blackness at the beginning of the new stream. Also, our video element now has to have access to the peer-connection state and that state it not even representing the right thing.<\/span><\/p>\n<h3>Track muted attribute to the rescue<\/h3>\n<p><span style=\"font-weight: 400;\">In the latest iteration of the spec &#8211; the transceiver model that is implemented in Firefox 59 &#8211; the MediaStreamTrack has a <code>muted<\/code> attribute. This attribute is initially set to <code>true<\/code> and will change to <code>false<\/code> once\u00a0media starts arriving. See the <a href=\"http:\/\/w3c.github.io\/webrtc-pc\/#dom-rtcrtpreceiver\">specification of the RTCRtpReceiver<\/a> for details.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This allows for a much better decision on when to show the video element and when to hide it by listening for the <code>unmute<\/code> and <code>mute<\/code> events on the MediaStreamTrack as shown in this fiddle:<\/span><\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/jsfiddle.net\/jib1\/kn609zdo\/embedded\/js,result,html\/\" allow=\"camera; microphone\" width=\"100%\" height=\"520px\" frameborder=\"0\"><\/iframe><\/p>\n<p><span style=\"font-weight: 400;\">What we see in the logged output in the &#8220;Result&#8221; tab above, is that the track is initially muted and only becomes unmuted once video packets arrive, after the peer-to-peer connection becomes connected.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Unfortunately, this only works in Firefox 59 and up. There is a <\/span><a href=\"https:\/\/bugs.chromium.org\/p\/webrtc\/issues\/detail?id=8730\"><span style=\"font-weight: 400;\">Chrome\/WebRTC bug<\/span><\/a><span style=\"font-weight: 400;\"> and similar issues exist in Microsoft Edge\u2019s <\/span><a href=\"https:\/\/github.com\/w3c\/ortc\/pull\/807\"><span style=\"font-weight: 400;\">ORTC implementation<\/span><\/a><span style=\"font-weight: 400;\">. Hopefully the bugs around this get will\u00a0fixed soon (the comments on the Chrome issue look positive), it is a small but crucial detail in the transition to WebRTC 1.0.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"The WebRTC specification has changed quite a bit since the first version in 2011. Jan-Ivar gave a great summary of how it has evolved over the years in a previous blog post. One of the central questions for web developers is when to display an incoming video stream.","protected":false},"author":1556,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"coauthors":[301114],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>When should you display incoming WebRTC video? - Advancing WebRTC<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"When should you display incoming WebRTC video? - Advancing WebRTC\" \/>\n<meta property=\"og:description\" content=\"The WebRTC specification has changed quite a bit since the first version in 2011. Jan-Ivar gave a great summary of how it has evolved over the years in a previous blog post. One of the central questions for web developers is when to display an incoming video stream.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/\" \/>\n<meta property=\"og:site_name\" content=\"Advancing WebRTC\" \/>\n<meta property=\"article:published_time\" content=\"2018-02-26T17:27:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-03-23T19:18:53+00:00\" \/>\n<meta name=\"author\" content=\"Philipp Hancke\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Hancke\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/\",\"name\":\"When should you display incoming WebRTC video? - Advancing WebRTC\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\"},\"datePublished\":\"2018-02-26T17:27:19+00:00\",\"dateModified\":\"2018-03-23T19:18:53+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/9cd9cda27de7fa106e0e6086e9f6d719\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/webrtc\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"When should you display incoming WebRTC video?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/\",\"name\":\"Advancing WebRTC\",\"description\":\"Committed to moving Firefox and WebRTC forward\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/9cd9cda27de7fa106e0e6086e9f6d719\",\"name\":\"Philipp Hancke\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/a77b011660700c2a15f7ba3ed28eb0d2\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1fc135621aa5023f2ae958e170508dfc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1fc135621aa5023f2ae958e170508dfc?s=96&d=mm&r=g\",\"caption\":\"Philipp Hancke\"},\"description\":\"doing things webrtc at appear.in\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/author\/fippoappear-in\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"When should you display incoming WebRTC video? - Advancing WebRTC","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/","og_locale":"en_US","og_type":"article","og_title":"When should you display incoming WebRTC video? - Advancing WebRTC","og_description":"The WebRTC specification has changed quite a bit since the first version in 2011. Jan-Ivar gave a great summary of how it has evolved over the years in a previous blog post. One of the central questions for web developers is when to display an incoming video stream.","og_url":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/","og_site_name":"Advancing WebRTC","article_published_time":"2018-02-26T17:27:19+00:00","article_modified_time":"2018-03-23T19:18:53+00:00","author":"Philipp Hancke","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Philipp Hancke","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/","url":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/","name":"When should you display incoming WebRTC video? - Advancing WebRTC","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#website"},"datePublished":"2018-02-26T17:27:19+00:00","dateModified":"2018-03-23T19:18:53+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/9cd9cda27de7fa106e0e6086e9f6d719"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/webrtc\/when-should-you-display-incoming-webrtc-video\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/webrtc\/"},{"@type":"ListItem","position":2,"name":"When should you display incoming WebRTC video?"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/webrtc\/#website","url":"https:\/\/blog.mozilla.org\/webrtc\/","name":"Advancing WebRTC","description":"Committed to moving Firefox and WebRTC forward","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/9cd9cda27de7fa106e0e6086e9f6d719","name":"Philipp Hancke","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/a77b011660700c2a15f7ba3ed28eb0d2","url":"https:\/\/secure.gravatar.com\/avatar\/1fc135621aa5023f2ae958e170508dfc?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1fc135621aa5023f2ae958e170508dfc?s=96&d=mm&r=g","caption":"Philipp Hancke"},"description":"doing things webrtc at appear.in","url":"https:\/\/blog.mozilla.org\/webrtc\/author\/fippoappear-in\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/321"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/users\/1556"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/comments?post=321"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/321\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/media?parent=321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/categories?post=321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/tags?post=321"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/coauthors?post=321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}