I am desperately trying to stream Blender's UI over HTTP:

import bpy

from wsgiref.simple_server import make_server
import threading

def app(environ, start_response): # The routine called by WSGI
    if environ["PATH_INFO"] == "/screen": # If a screenshot is requested
        bpy.ops.screen.screenshot(filepath="/tmp/screen.png", full=True) # Take the screenshot -> RuntimeError: Operator bpy.ops.screen.screenshot.poll() failed, context is incorrect
        start_response('200 OK', [('Content-Type', 'image/png')]) # Send the stuff over
        data = None
        with open("/tmp/screen.png", "rb") as f: # Ugly hack to retrieve the image
            data = f.read()

        return [data,]
    else: # Get the HTML-page that updates the screen
        data = b"""
var oReq = new XMLHttpRequest();
oReq.open("GET", "", true);
oReq.responseType = "arraybuffer";

var onload = function(oEvent) {
  var blob = new Blob([oReq.response], {type: "image/png"});
  var urlCreator = window.URL || window.webkitURL;
  document.getElementById("test").setAttribute("src", urlCreator.createObjectURL( blob ));
  new XMLHttpRequest();
  oReq.open("GET", "", true);
  oReq.responseType = "arraybuffer";
  oReq.onload = onload;

oReq.onload = onload;
<p><img src="" id="test"/></P>
        start_response("200 OK", [("Content-Type", "text/html")])
        return [data,]
httpd = make_server('', 8083, app) # Standart httpd
print('Serving on port 8083...')
thread = threading.Thread(target=httpd.handle_request, args=()) # Run it in the background, kill after one request

I am trying to use Blender's built-in screen.screenshot -operator to get an image of Blender. It works when ran from outside the server. The server does also return valid HTML. However, when I try to combine the two (return the screenshot over http), it breaks down. I get the following message:

RuntimeError: Operator bpy.ops.screen.screenshot.poll() failed, context is incorrect

I can't figure how to avoid this. The code works when taking a screenshot with platform-specific means, but it is much too slow for use (upwards of 200ms). I understand that running a HTTP server inside Blender is not usual.

The whole mess is running on an ArchLinux box (x86_64).

  • $\begingroup$ You can use other libraries such as ImageGrab( effbot.org/imagingbook/imagegrab.htm) or PyScreenshot (pypi.python.org/pypi/pyscreenshot), but if streaming is what you want, dedicated streaming tools and libraries will likely do a better job. After all, there's much more to streaming then just sending out frames (buffering, compression, control over framerate, etc). $\endgroup$
    – TLousky
    Apr 1, 2016 at 10:36
  • $\begingroup$ Yeah, I tried ScreenGrab, but the fps is awful. $\endgroup$
    – Mörkö
    Apr 1, 2016 at 10:43


You must log in to answer this question.

Browse other questions tagged .