Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 158 lines (123 sloc) 4.756 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
#!/usr/bin/env python
# Pongo, an inexpensive UI lab
# Originally by Andreas Nilsson: http://www.andreasn.se/blog/?p=96
# Requires python and istanbul: http://live.gnome.org/Istanbul


print """
- Default camera video position is bottom right.
To change, use 'top' and 'left' as arguments.
- Disable camera with 'nocam'.
- If you are conducting a RTA (= retrospective thinking aloud),
use 'shift' to set the camera video next to the one already there.
- For a custom filename use 'filename.ogv' as argument.
- Reduce output file resolution with the width in pixels as argument.
"""

import pygtk
pygtk.require("2.0")
import gobject
gobject.threads_init()
import pygst
pygst.require("0.10")
import gst

import signal
import subprocess
import os.path
import sys
import re


def clean_shutdown(p):
    camsrc = p.get_by_name("camsrc")
    xsrc = p.get_by_name("xsrc")
    asrc = p.get_by_name("asrc")
    eos = gst.event_new_eos()

    camsrc.send_event(eos)
    xsrc.send_event(eos)
    asrc.send_event(eos)

    bus = p.get_bus()
    bus.poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR, -1)


def interrupt():
    loop.quit()



# This function takes Bash commands and returns them
# Taken from http://magazine.redhat.com/2008/02/07/python-for-bash-scripters-a-well-kept-secret/
def runBash(cmd):
    p = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE)
    out = p.stdout.read().strip()
    return out


def main(action = None):
    if action is None:
        # Recording name
        out_file = "recording-"
        count = 1
        while(os.path.isfile(out_file + str(count) + ".ogv")):
            count = count + 1
        
        global out_file
        out_file += str(count)
        out_file += ".ogv"

        for arg in sys.argv:
            if re.search(".ogv", arg):
                if(os.path.isfile(arg)):
                    print "File %s already exists!" % arg
                else:
                    out_file = arg


        # Screen dimensions
        out_w = int(runBash("xdpyinfo | grep dimensions | cut -d' ' -f7 | cut -d'x' -f1"))
        out_h = int(runBash("xdpyinfo | grep dimensions | cut -d' ' -f7 | cut -d'x' -f2"))

        for arg in sys.argv:
            if arg.isdigit():
                if int(arg) > out_w:
                    print "Can not scale video up!"
                else:
                    arg = int(arg)
                    out_h = out_h * arg / out_w
                    out_w = arg


        # Camera video
        cam = True
        cam_w = 320
        cam_h = 240
        # TODO: Implement camera video scaling as well
        # v4l2src seems to have problems with other values
        #cam_w = round(out_w / 4)
        #cam_h = round(cam_w * 3/4)
        cam_opacity = 0.8
        v4l_device = "/dev/video0"
        cam_x = out_w - cam_w
        cam_y = out_h - cam_h

        for arg in sys.argv:
            if arg == "left":
                cam_x = 0
            elif arg == "top":
                cam_y = 0
            elif arg == "nocam":
                cam = False
                cam_opacity = 0 # hack, TODO: deactivate cam directly

        for arg in sys.argv:
            if arg == "shift":
                if cam_x == 0:
                    cam_x += cam_w
                else:
                    cam_x -= cam_w

        global p
        # Do it!
        p = gst.parse_launch("""videomixer name = mix ! ffmpegcolorspace ! queue ! theoraenc ! oggmux name = mux ! filesink location = %s
istximagesrc name = xsrc use-damage = false ! videorate ! video/x-raw-rgb,framerate = 10/1 ! ffmpegcolorspace ! videoscale method = 1 ! video/x-raw-yuv,width = %d,height = %d ! mix.sink_0
v4l2src name = camsrc device = %s ! ffmpegcolorspace ! videorate ! video/x-raw-yuv, framerate = 10/1, width = %d, height = %d ! queue ! videoscale ! ffmpegcolorspace ! video/x-raw-yuv,height = %d,height = %d ! mix.sink_1
alsasrc name = asrc ! queue ! audioconvert ! vorbisenc ! mux.""" % \
            (out_file, out_w, out_h, v4l_device, cam_w, cam_h, cam_w, cam_h))

        mix = p.get_by_name("mix")
        cam_pad = mix.get_pad("sink_1")
        cam_pad.set_property("xpos", cam_x)
        cam_pad.set_property("ypos", cam_y)
        cam_pad.set_property("alpha", cam_opacity)
        cam_pad.set_property("zorder", 1)


        p.set_state(gst.STATE_PLAYING)
        print "Capturing %sx%s video to %s ..." % (out_w, out_h, out_file)

        loop = gobject.MainLoop()
        try:
          loop.run()
        except KeyboardInterrupt:
          pass
    else:
        print "Stopping capture ..."
        clean_shutdown(p)
        p.set_state(gst.STATE_NULL)
        print "Successfully saved as %s" % out_file

        

    
    
if __name__ == "__main__":
    main()
Something went wrong with that request. Please try again.