0
$\begingroup$

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"""
<html>
<head>
<script>
var oReq = new XMLHttpRequest();
oReq.open("GET", "http://172.24.31.145:8083/screen.png", 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", "http://172.24.31.145:8083/screen.png", true);
  oReq.responseType = "arraybuffer";
  oReq.onload = onload;
  oReq.send();
};

oReq.onload = onload;
oReq.send();
</script>
</head>
<body>
<p><img src="" id="test"/></P>
</body>
</html>
        """
        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
thread.start()

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).

$\endgroup$
  • $\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 '16 at 10:36
  • $\begingroup$ Yeah, I tried ScreenGrab, but the fps is awful. $\endgroup$ – Mörkö Apr 1 '16 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.