1/*
2 * Compile using:
3 * valac --pkg gtk+-2.0 --pkg gdk-x11-2.0 --pkg gstreamer-0.10 --pkg gstreamer-interfaces-0.10 webcam.vala
4 *
5 */
6using Gtk;
7using Gst;
8
9public class Webcam : Gtk.Window
10{
11  private Gtk.DrawingArea drawing_area;
12  private X.ID xid;
13  private Gst.Element camerabin;
14  private int counter = 1;
15  private bool playing;
16
17  public Webcam ()
18  {
19    this.set_title ("Press play to start");
20    this.destroy.connect (Gtk.main_quit);
21
22    var vbox = new Gtk.VBox (false, 0);
23    this.drawing_area = new Gtk.DrawingArea ();
24    this.drawing_area.set_size_request (640, 480);
25    this.drawing_area.realize.connect (on_realize);
26    vbox.pack_start (this.drawing_area, true, true, 0);
27
28    var play_button = new Button.from_stock (Gtk.STOCK_MEDIA_PLAY);
29    play_button.clicked.connect (on_play);
30    var pause_button = new Button.from_stock (Gtk.STOCK_MEDIA_PAUSE);
31    pause_button.clicked.connect (on_pause);
32    var photo_button = new Button.with_label ("Take a picture");
33    photo_button.clicked.connect (on_take_picture);
34    var stop_button = new Button.from_stock (Gtk.STOCK_MEDIA_STOP);
35    stop_button.clicked.connect (on_stop);
36
37    var button_box = new Gtk.HButtonBox ();
38    button_box.add (play_button);
39    button_box.add (pause_button);
40    button_box.add (photo_button);
41    button_box.add (stop_button);
42    vbox.pack_start (button_box, false, true, 5);
43
44    this.add (vbox);
45
46    this.camerabin = Gst.ElementFactory.make ("camerabin", "camera");
47    var bus = this.camerabin.get_bus ();
48    bus.set_sync_handler (on_bus_callback);
49  }
50
51  private Gst.BusSyncReply on_bus_callback (Gst.Bus bus, Gst.Message message)
52  {
53    if (message.get_structure () != null && message.get_structure().has_name("prepare-xwindow-id")) {
54      var xoverlay = message.src as Gst.XOverlay;
55      xoverlay.set_xwindow_id (this.xid);
56      return Gst.BusSyncReply.DROP;
57    }
58
59    return Gst.BusSyncReply.PASS;
60  }
61
62  private void on_realize ()
63  {
64    this.xid = Gdk.x11_drawable_get_xid (this.drawing_area.window);
65    on_play ();
66  }
67
68  private void on_play ()
69  {
70    this.camerabin.set_state (Gst.State.PLAYING);
71    this.playing = true;
72  }
73
74  private void on_pause ()
75  {
76    this.camerabin.set_state (Gst.State.PAUSED);
77    this.playing = false;
78  }
79
80  private void on_stop ()
81  {
82    this.camerabin.set_state (Gst.State.NULL);
83    this.playing = false;
84  }
85
86  private void on_take_picture ()
87  {
88    if (this.playing)
89    {
90      var filename = "photo" + "%d".printf (this.counter) + ".jpg";
91      this.set_title ("%d".printf (this.counter) + " photos taken");
92      this.counter++;
93      this.camerabin.set ("filename", filename);
94      GLib.Signal.emit_by_name (this.camerabin, "capture-start");
95    }
96  }
97
98  public static int main (string[] args)
99  {
100    Gst.init (ref args);
101    Gtk.init (ref args);
102
103    var webcam = new Webcam ();
104    webcam.show_all ();
105
106    Gtk.main ();
107
108    return 0;
109  }
110}
111