Search code examples
phplinuxbashscreenshot

How to capture x screen using PHP, shell_exe and scrot


I'm building a web page screen capture application for an internal R&D project.

Environment: Ubuntu 9.04 (default desktop install), Apache, PHP.

So far I've got a bash script that takes one parameter (URL), fires up firefox, grabs the screen and saves it as a PNG. I've tried running this from terminal and it works fine.

Here's the Bash script:

#!/bin/bash
firefox $1 # Start firefox and go to the passed in URL
scrot -d 5 test.png # Take screen grab with 5 second delay

Next I created a simple PHP page that uses shell_exec to run the script:

<?
  // Sample URL
  $url = 'http://www.google.com'; 
  // Run the script
  shell_exec('sh script.sh ' . $url);
  // Out put HTML to display image
  echo '<img src="test.png" />';
?>

However, when the PHP page is called the screen is not captured. A quick look in the apache error logs show the following message:

Error: no display specified
giblib error: Can't open X display. It *is* running, yeah

I'm guessing this is because apache is running as a different user and hasn't got access to my X display.

So, can anyone shed any light on what I'm doing wrong or how I can capture the current user display.

Thanks.


Solution

  • Launching firefox from PHP running under Apache seems to me like a bad idea (it definitly feels wrong).

    The way I would do that :

    • a PHP webpage (which runs under Apache) that receives the URL ; something like a form, for instance
      • that page inserts the URL in a database-like system, that will be used as a queue
      • this URL is marked as "to process"
    • a PHP (or another language) script, totally independant from Apache ; for instance, launched by the crontab
      • this scripts selects an URL from the queue in the database (least recent one, for instance), and marks it as "processing"
      • it then lauches your shell-script, which launches firefox and does the screenshot
      • one the screenshot is done, the URL in the queue is marked as "done", and the screenshot's path is associated to the URL
      • this will work, as it is independant from Apache
    • another web page displays the queue, and the status of each URL ("to process", "processing", "done + path to the screenshot"
      • you can even imagine having an association betwen a user and an URL, to not display every URL+screenshot to everyone.

    With this system, several advantages :

    • php+apache for the webpages
    • php outside of apache for the "system" parts
    • you can have the webpages on one server
    • and you can have several machines (linux, windows, mac -- maybe using virtual machines) to make the screenshots
      • allow you to get screenshots from different OSes
      • scales way better ^^

    It's not really an answer to the question, but I think it's a better way... Hope this helps !