title: WEBRTC remote video stops streaming after 2 seconds
body: <p>I am facing a very weird behavior with this WEBRTC peer to peer app. the app would stream audio form one peer to the other, but when it comes to stream video, it actually stream video but just for the first 2 seconds, then it would stop streaming video, but the audio continues to stream. Here is some of the code that handles the remote video:</p>
  
  <pre><code>var webrtc_capable = true;
  var rtc_peer_connection = null;
  var rtc_session_description = null;
  var get_user_media = null;
  var connect_stream_to_src = null;
  var stun_server = null;
  
  if (navigator.getUserMedia) { 
    rtc_peer_connection = RTCPeerConnection;
    rtc_session_description = RTCSessionDescription;
    get_user_media = navigator.getUserMedia.bind(navigator);
    connect_stream_to_src = function(media_stream, media_element) {
      media_element.srcObject = window.URL.createObjectURL(media_stream);
      media_element.play();
    };
  } else if (navigator.mozGetUserMedia) { 
    rtc_peer_connection = mozRTCPeerConnection;
    rtc_session_description = mozRTCSessionDescription;
    get_user_media = navigator.mozGetUserMedia.bind(navigator);
    connect_stream_to_src = function(media_stream, media_element) {
      media_element.srcObject = window.URL.createObjectURL(media_stream);
      media_element.play();
    };
    stun_server = null;
  } else if (navigator.webkitGetUserMedia) { 
    rtc_peer_connection = webkitRTCPeerConnection;
    rtc_session_description = RTCSessionDescription;
    get_user_media = navigator.webkitGetUserMedia.bind(navigator);
    connect_stream_to_src = function(media_stream, media_element) {
      media_element.src = webkitURL.createObjectURL(media_stream);
    };
  } else {
    alert("This browser does not support WebRTC - visit WebRTC.org for more info");
    webrtc_capable = false;
  }
  &lt;/script&gt;
  &lt;script&gt;
  
  
  var call_token; 
  var signaling_server; 
  var peer_connection; 
  
  function start() {
    // create the WebRTC peer connection object
    peer_connection = new rtc_peer_connection({ 
      "iceServers": [ // information about ice servers
        { "url": "stun:"+stun_server }, 
      ]
    });
  
    // generic handler that sends any ice candidates to the other peer
    peer_connection.onicecandidate = function (ice_event) {
      console.log(ice_event.candidate);
      if (ice_event.candidate){
        console.log("true");
      }
      if (ice_event.candidate) {
        signaling_server.send(
          JSON.stringify({
            token:call_token,
            type: "new_ice_candidate",
            candidate: ice_event.candidate ,
          })
        );
      }
    };
  
  
    peer_connection.onaddstream = function (event) {
      var video = document.querySelector("#remote_video");
  
      video.src = webkitURL.createObjectURL(event.stream);
  
      document.getElementById("loading_state").style.display = "none";
      document.getElementById("open_call_state").style.display = "block";
    };
  
  
  
    setup_video();
  
  
    signaling_server = new WebSocket("ws://localhost:1234");
  
    if (document.location.hash === "" || document.location.hash === undefined) { 
  
  
      var token = Date.now()+"-"+Math.round(Math.random()*10000);
      call_token = "#"+token;
  
  
      document.location.hash = token;
  
      signaling_server.onopen = function() {
  
        signaling_server.onmessage = caller_signal_handler;
  
  
        signaling_server.send(
          JSON.stringify({ 
            token:call_token,
            type:"join",
          })
        );
      }
  
      document.title = "You are the Caller";
      document.getElementById("loading_state").innerHTML = "Ready for a call...ask your friend to visit:&lt;br/&gt;&lt;br/&gt;"+document.location;
  
    } else { // you have a hash fragment so you must be the Callee 
  
      // get the unique token for this call from location.hash
      call_token = document.location.hash;
  
      signaling_server.onopen = function() {
        // setup caller signal handler
        signaling_server.onmessage = callee_signal_handler;
  
        // tell the signaling server you have joined the call 
        signaling_server.send(
          JSON.stringify({ 
            token:call_token,
            type:"join",
          })
        );
  
        // let the caller know you have arrived so they can start the call
        signaling_server.send(
          JSON.stringify({ 
            token:call_token,
            type:"callee_arrived",
          })
        );
      }
  
      document.title = "You are the Callee";
      document.getElementById("loading_state").innerHTML = "One moment please...connecting your call...";
    }
  
    // setup message bar handlers
    document.getElementById("message_input").onkeydown = send_chat_message;
    document.getElementById("message_input").onfocus = function() { this.value = ""; }
  }
  
  
  
  // handler to process new descriptions
  function new_description_created(description) {
    peer_connection.setLocalDescription(
      description, 
      function () {
        signaling_server.send(
          JSON.stringify({
            token:call_token,
            type:"new_description",
            sdp:description 
          })
        );
      }, 
      log_error
    );
  }
  
  // handle signals as a caller
  function caller_signal_handler(event) {
    var signal = JSON.parse(event.data);
    if (signal.type === "callee_arrived") {
      peer_connection.createOffer(
        new_description_created, 
        log_error
      );
    } else if (signal.type === "new_ice_candidate") {
      peer_connection.addIceCandidate(new RTCIceCandidate(signal.candidate));
    } else if (signal.type === "new_description") {
      peer_connection.setRemoteDescription(
        new rtc_session_description(signal.sdp), 
        function () {
          if (peer_connection.remoteDescription.type == "answer") {
            peer_connection.createOffer(new_description_created, log_error);
          }
        },
        log_error
      );
    } else if (signal.type === "new_chat_message") {
      add_chat_message(signal);
    } else {
      // extend with your own signal types here
    }
  }
  
  // handle signals as a callee
  function callee_signal_handler(event) {
    var signal = JSON.parse(event.data);
    if (signal.type === "new_ice_candidate") {
      peer_connection.addIceCandidate(
        new RTCIceCandidate(signal.candidate)
      );
    } else if (signal.type === "new_description") {
      peer_connection.setRemoteDescription(
        new rtc_session_description(signal.sdp), 
        function () {
          if (peer_connection.remoteDescription.type == "offer") {
            peer_connection.createAnswer(new_description_created, log_error);
          }
        },
        log_error
      );
    } else if (signal.type === "new_chat_message") {
      add_chat_message(signal);
    } else {
      // extend with your own signal types here
    }
  }
  
  // add new chat message to messages list
  function add_chat_message(signal) {
    var messages = document.getElementById("messages");
    var user = signal.user || "them"; 
    messages.innerHTML = user+": "+signal.message+"&lt;br/&gt;\n"+messages.innerHTML;
  }
  
  // send new chat message to the other browser
  function send_chat_message(e) {
    if (e.keyCode == 13) {
      var new_message = this.value;
      this.value = ""; 
      signaling_server.send(
        JSON.stringify({
          token:call_token,
          type: "new_chat_message",
          message: new_message 
        })
      );
      add_chat_message({ user: "you", message: new_message }); 
    }
  }
  
  // setup stream from the local camera 
  function setup_video() {
    get_user_media(
      { 
        "audio": true, // request access to local microphone
        "video": true  // request access to local camera
      }, 
      function (local_stream) { 
        &lt;video&gt; MediaElement
  
        connect_stream_to_src(local_stream, document.getElementById("local_video"));
  
        peer_connection.addStream(local_stream);
      },
      log_error
    );
  }
  
  
  function log_error(error) {
    console.log(error);
  }
  
  &lt;/script&gt;
  </code></pre>
  
  <p>Additional Info:</p>
  
  <ul>
  <li>Windows 8 x64</li>
  <li>opera version is 27.0.1689.76</li>
  <li>Localvideo plays fine</li>
  <li>This call is between two peers on the same network(no nat traversal)</li>
  </ul>