title: Streaming from webcam to server using flask-socketio
body: <p>I am trying to build a web application where images are streamed from a client's webcam to a server, the server performs some computations on the images, and the results of those computations are sent back to the client, all in real time.</p>
  
  <p>So far, I have tried it with <strong>flask-socketio</strong>, adapting this code:</p>
  
  <p><a href="https://github.com/dxue2012/python-webcam-flask" rel="nofollow noreferrer">https://github.com/dxue2012/python-webcam-flask</a></p>
  
  <p>which is again I think adapted from this example:</p>
  
  <p><a href="https://github.com/miguelgrinberg/flask-video-streaming" rel="nofollow noreferrer">https://github.com/miguelgrinberg/flask-video-streaming</a></p>
  
  <p>Relevant code bits on the client's side are:</p>
  
  <pre class="lang-js prettyprint-override"><code>function sendSnapshot() {
    if (!localMediaStream) {
      return;
    }
  
    ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, 300, 150);
  
      let dataURL = canvas.toDataURL('image/jpeg');
        socket.emit('input image', dataURL);
    }
  
    navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
      video.srcObject = stream;
      localMediaStream = stream;
  
      setInterval(function () {
        sendSnapshot();
      }, 50);
    }).catch(function(error) {
      console.log(error);
    });
  </code></pre>
  
  <p>And on the server:  </p>
  
  <pre class="lang-py prettyprint-override"><code>app = Flask(__name__)
  
  app.config['SECRET_KEY'] = 'secret!'
  app.config['DEBUG'] = True
  
  socketio = SocketIO(app)
  
  
  val = 0
  
  @socketio.on('input image', namespace='/test')
  def test_message(input):
      input = input.split(",")[1]
  
      global val
      val = do_stuff(input)
  
  @socketio.on('get value', namespace='/test')
  def send_stuff_back():
  
      global val
  
      emit("val ready", val)
  </code></pre>
  
  <p>Other than in the GitHub example I don't need to send images back to the client, only much smaller data.</p>
  
  <p>The problem is, even so, everything is extremely laggy unless the images sent to the server are impermissibly small, i.e., to the point where it really defeats the purpose of sending them to a server in the first place.</p>
  
  <p>The problem persists if the image computations are skipped, the problem seems to lie in sending the images.</p>
  
  <p>Now I'm wondering whether that's expected behavior of this canvas/toDataURL method of streaming or if I'm doing something wrong.</p>
  
  <p>If this is expected, maybe someone could point me in the direction of a more practical way of achieving what I'm trying to do.</p>
  
  <p>(eventlet is definitely installed; I'm using heroku to deploy in case that's relevant.)</p>
  
  <p>Any help is appreciated!  </p>
  
  <p><strong>Edit 1</strong>:</p>
  
  <p>I've already increased 'max_decode_packets' so that's not the source of the problem.</p>
  
  <p><strong>Edit 2</strong>:</p>
  
  <p>Network:<a href="https://i.stack.imgur.com/HwW6p.png" rel="nofollow noreferrer">1</a></p>
  
  <p><strong>Edit 3</strong>:</p>
  
  <p>More screenshots:
  Network, websocket message <a href="https://i.stack.imgur.com/P3Koj.png" rel="nofollow noreferrer">2</a>
  server->client<a href="https://i.stack.imgur.com/VzYaj.png" rel="nofollow noreferrer">3</a></p>