#!/usr/bin/env python
import sys, os
import pango
import pygtk, gtk, gobject
import pygst
pygst.require("0.10")
import gst
class GTK_Main:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Webcam Streamer")
window.set_default_size(600, 400)
window.connect("destroy", gtk.main_quit, "WM destroy")
self.sstate = 'preparing'
red=gtk.gdk.color_parse('grey')
eb=gtk.EventBox()
eb.modify_bg(gtk.STATE_NORMAL, red)
window.add(eb)
windows = gtk.ScrolledWindow()
windows.set_size_request(600, 400)
eb.add(windows)
hbox0 = gtk.HBox(True)
windows.add_with_viewport(hbox0)
vbox = gtk.VBox()
vbox.set_border_width(10)
self.movie_window = gtk.DrawingArea()
vbox.add(self.movie_window)
hbox = gtk.HBox()
vbox.pack_start(hbox, False)
hbox.set_border_width(10)
hbox.pack_start(gtk.Label())
self.button = gtk.Button("Start Stream")
self.button.connect("clicked", self.start_stop)
hbox.pack_start(self.button, False)
self.button2 = gtk.Button("Quit")
self.button2.connect("clicked", self.exit)
hbox.pack_start(self.button2, False)
self.statuslabel = gtk.Label()
self.statuslabel.modify_font(pango.FontDescription("sans bold 14"))
self.statuslabel.set_justify(gtk.JUSTIFY_RIGHT);
self.statuslabel.set_markup("Camera started...Ready to stream")
vbox.pack_start(self.statuslabel, False)
hbox0.pack_start(vbox, False)
vbox2 = gtk.VBox()
vbox2.set_border_width(10)
self.devlabel = gtk.Label("Input devices")
self.devlabel.modify_font(pango.FontDescription("sans bold 10"))
self.devlabel.set_justify(gtk.JUSTIFY_RIGHT);
vbox2.pack_start(self.devlabel, False)
vbox2.pack_start(gtk.HSeparator(), False)
hbox2 = gtk.HBox(True)
vbox2.pack_start(hbox2, False)
self.combodevice = gtk.combo_box_new_text()
self.combodevice.append_text("/dev/video0")
self.combodevice.append_text("/dev/video1")
self.combodevice.append_text("/dev/video2")
self.combodevice.append_text("/dev/video3")
self.combodevice.set_active(0)
hbox2.pack_start(gtk.Label("Video device : "), True)
hbox2.pack_start(self.combodevice, True)
hbox21 = gtk.HBox(True)
vbox2.pack_start(hbox21, False)
self.vdevicetype = gtk.combo_box_new_text()
self.vdevicetype.append_text("v4l")
self.vdevicetype.append_text("v4l2")
self.vdevicetype.set_active(1)
hbox21.pack_start(gtk.Label("Driver type : "), True)
hbox21.pack_start(self.vdevicetype, True)
hbox3 = gtk.HBox(True)
vbox2.pack_start(hbox3, False)
hbox3.pack_start(gtk.Label("Audio device : "), True)
self.comboadevice = gtk.combo_box_new_text()
self.comboadevice.append_text("/dev/dsp")
self.comboadevice.append_text("/dev/dsp1")
self.comboadevice.append_text("/dev/dsp2")
self.comboadevice.append_text("/dev/dsp3")
self.comboadevice.set_active(0)
hbox3.pack_start(self.comboadevice, True)
self.vparamslabel = gtk.Label("Video parameters")
self.vparamslabel.set_justify(gtk.JUSTIFY_RIGHT);
self.vparamslabel.modify_font(pango.FontDescription("sans bold 10"))
vbox2.pack_start(self.vparamslabel, False)
vbox2.pack_start(gtk.HSeparator(), False)
hbox4 = gtk.HBox(True)
vbox2.pack_start(hbox4, False)
self.combovsize = gtk.combo_box_new_text()
self.combovsize.append_text("160x128")
self.combovsize.append_text("320x240")
self.combovsize.append_text("360x288")
self.combovsize.append_text("640x480")
self.combovsize.append_text("720x576")
self.combovsize.set_active(1)
hbox4.pack_start(gtk.Label("Video size : "), True)
hbox4.pack_start(self.combovsize, True)
hbox5 = gtk.HBox(True)
vbox2.pack_start(hbox5, False)
hbox5.pack_start(gtk.Label("Framerate : "), True)
self.comboframerate = gtk.combo_box_new_text()
self.comboframerate.append_text("25")
self.comboframerate.append_text("25:2")
self.comboframerate.append_text("25:3")
self.comboframerate.append_text("25:4")
self.comboframerate.append_text("25:5")
self.comboframerate.set_active(1)
hbox5.pack_start(self.comboframerate, True)
hbox6 = gtk.HBox(True)
vbox2.pack_start(hbox6, False)
hbox6.pack_start(gtk.Label("Video quality : "), True)
self.combovquality = gtk.combo_box_new_text()
self.combovquality.append_text("0")
self.combovquality.append_text("1")
self.combovquality.append_text("2")
self.combovquality.append_text("3")
self.combovquality.append_text("4")
self.combovquality.append_text("5")
self.combovquality.append_text("6")
self.combovquality.append_text("7")
self.combovquality.append_text("8")
self.combovquality.append_text("9")
self.combovquality.append_text("10")
self.combovquality.append_text("11")
self.combovquality.append_text("12")
self.combovquality.append_text("13")
self.combovquality.append_text("14")
self.combovquality.append_text("15")
self.combovquality.append_text("16")
self.combovquality.append_text("17")
self.combovquality.append_text("18")
self.combovquality.append_text("19")
self.combovquality.append_text("20")
self.combovquality.append_text("21")
self.combovquality.append_text("22")
self.combovquality.append_text("23")
self.combovquality.append_text("24")
self.combovquality.append_text("25")
self.combovquality.append_text("26")
self.combovquality.append_text("27")
self.combovquality.append_text("28")
self.combovquality.append_text("29")
self.combovquality.append_text("30")
self.combovquality.append_text("31")
self.combovquality.append_text("32")
self.combovquality.append_text("33")
self.combovquality.append_text("34")
self.combovquality.append_text("35")
self.combovquality.append_text("36")
self.combovquality.append_text("37")
self.combovquality.append_text("38")
self.combovquality.append_text("39")
self.combovquality.append_text("40")
self.combovquality.append_text("41")
self.combovquality.append_text("42")
self.combovquality.append_text("43")
self.combovquality.append_text("44")
self.combovquality.append_text("45")
self.combovquality.append_text("46")
self.combovquality.append_text("47")
self.combovquality.append_text("48")
self.combovquality.append_text("49")
self.combovquality.append_text("50")
self.combovquality.append_text("51")
self.combovquality.append_text("52")
self.combovquality.append_text("53")
self.combovquality.append_text("54")
self.combovquality.append_text("55")
self.combovquality.append_text("56")
self.combovquality.append_text("57")
self.combovquality.append_text("58")
self.combovquality.append_text("59")
self.combovquality.append_text("60")
self.combovquality.append_text("61")
self.combovquality.append_text("62")
self.combovquality.append_text("63")
self.combovquality.set_active(16)
hbox6.pack_start(self.combovquality, True)
self.aparamslabel = gtk.Label("Audio parameters")
self.aparamslabel.set_justify(gtk.JUSTIFY_RIGHT);
self.aparamslabel.modify_font(pango.FontDescription("sans bold 10"))
vbox2.pack_start(self.aparamslabel, False)
vbox2.pack_start(gtk.HSeparator(), False)
hbox7 = gtk.HBox(True)
vbox2.pack_start(hbox7, False)
self.comboaquality = gtk.combo_box_new_text()
self.comboaquality.append_text("-0.1")
self.comboaquality.append_text("0")
self.comboaquality.append_text("0.1")
self.comboaquality.append_text("0.2")
self.comboaquality.append_text("0.3")
self.comboaquality.append_text("0.4")
self.comboaquality.append_text("0.5")
self.comboaquality.append_text("0.6")
self.comboaquality.append_text("0.7")
self.comboaquality.append_text("0.8")
self.comboaquality.append_text("0.9")
self.comboaquality.append_text("1.0")
self.comboaquality.set_active(3)
hbox7.pack_start(gtk.Label("Audio quality : "), True)
hbox7.pack_start(self.comboaquality, True)
hbox8 = gtk.HBox(True)
vbox2.pack_start(hbox8, False)
hbox8.pack_start(gtk.Label("Audio channels : "), True)
self.comboachannels = gtk.combo_box_new_text()
self.comboachannels.append_text("1")
self.comboachannels.append_text("2")
self.comboachannels.set_active(0)
hbox8.pack_start(self.comboachannels, True)
hbox9 = gtk.HBox(True)
vbox2.pack_start(hbox9, False)
hbox9.pack_start(gtk.Label("Audio rate : "), True)
self.comboarate = gtk.combo_box_new_text()
self.comboarate.append_text("11025")
self.comboarate.append_text("22050")
self.comboarate.append_text("44100")
self.comboarate.append_text("48000")
self.comboarate.set_active(1)
hbox9.pack_start(self.comboarate, True)
self.sconfiglabel = gtk.Label("Server Configuration")
self.sconfiglabel.set_justify(gtk.JUSTIFY_RIGHT);
self.sconfiglabel.modify_font(pango.FontDescription("sans bold 10"))
vbox2.pack_start(self.sconfiglabel, False)
vbox2.pack_start(gtk.HSeparator(), False)
hbox10 = gtk.HBox(True)
vbox2.pack_start(hbox10, False)
hbox10.pack_start(gtk.Label("Server : "), True)
self.servername = gtk.Entry()
self.servername.set_text("www.giss.tv")
hbox10.pack_start(self.servername, True)
hbox11 = gtk.HBox(True)
vbox2.pack_start(hbox11, False)
hbox11.pack_start(gtk.Label("Port : "), True)
self.portnumber = gtk.Entry()
self.portnumber.set_text("8000")
hbox11.pack_start(self.portnumber, True)
hbox12 = gtk.HBox(True)
vbox2.pack_start(hbox12, False)
hbox12.pack_start(gtk.Label("Mountpoint : "), True)
self.mountpoint = gtk.Entry()
self.mountpoint.set_text("mountpoint.ogg")
hbox12.pack_start(self.mountpoint, True)
hbox13 = gtk.HBox(True)
vbox2.pack_start(hbox13, False)
hbox13.pack_start(gtk.Label("Password : "), True)
self.password = gtk.Entry()
self.password.set_text("xxxxx")
hbox13.pack_start(self.password, True)
self.smdatalabel = gtk.Label("Icecast Meta Data")
self.smdatalabel.set_justify(gtk.JUSTIFY_RIGHT);
self.smdatalabel.modify_font(pango.FontDescription("sans bold 10"))
vbox2.pack_start(self.smdatalabel, False)
vbox2.pack_start(gtk.HSeparator(), False)
hbox14 = gtk.HBox(True)
vbox2.pack_start(hbox14, False)
hbox14.pack_start(gtk.Label("Name : "), True)
self.name = gtk.Entry()
self.name.set_text("")
hbox14.pack_start(self.name, True)
hbox15 = gtk.HBox(True)
vbox2.pack_start(hbox15, False)
hbox15.pack_start(gtk.Label("Description : "), True)
self.description = gtk.Entry()
self.description.set_text("")
hbox15.pack_start(self.description, True)
hbox16 = gtk.HBox(True)
vbox2.pack_start(hbox16, False)
hbox16.pack_start(gtk.Label("Genre : "), True)
self.genre = gtk.Entry()
self.genre.set_text("")
hbox16.pack_start(self.genre, True)
hbox17 = gtk.HBox(True)
vbox2.pack_start(hbox17, False)
hbox17.pack_start(gtk.Label("Url : "), True)
self.url = gtk.Entry()
self.url.set_text("")
hbox17.pack_start(self.url, True)
self.srecordlabel = gtk.Label("Recording")
self.srecordlabel.set_justify(gtk.JUSTIFY_RIGHT);
self.srecordlabel.modify_font(pango.FontDescription("sans bold 10"))
vbox2.pack_start(self.srecordlabel, False)
vbox2.pack_start(gtk.HSeparator(), False)
hbox18 = gtk.HBox(True)
vbox2.pack_start(hbox18, False)
hbox18.pack_start(gtk.Label("Dump to file : "), True)
self.recfile = gtk.Entry()
self.recfile.set_text(".ogg")
hbox18.pack_start(self.recfile, True)
self.fcbutton = gtk.Button("Browse")
self.fcbutton.connect("clicked", self.on_file_dialog)
hbox18.pack_start(self.fcbutton, True)
hbox0.pack_start(vbox2, False)
window.show_all()
# Set up the gstreamer pipeline
devname = self.combodevice.get_active_text()
if self.vdevicetype.get_active_text() == "v4l":
self.player = gst.parse_launch ("v4lsrc device="+devname+" ! video/x-raw-yuv,width=320,height=240 ! autovideosink")
else:
self.player = gst.parse_launch ("v4l2src device="+devname+" ! video/x-raw-yuv,width=320,height=240 ! autovideosink")
bus = self.player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect("message", self.on_message)
bus.connect("sync-message::element", self.on_sync_message)
self.player.set_state(gst.STATE_PLAYING)
def stop_stream(self):
self.button.set_label("Start Stream")
self.player.set_state(gst.STATE_NULL)
devname = self.combodevice.get_active_text()
if self.vdevicetype.get_active_text() == "v4l":
self.player = gst.parse_launch ("v4lsrc device="+devname+" ! video/x-raw-yuv,width=320,height=240 ! autovideosink")
else:
self.player = gst.parse_launch ("v4l2src device="+devname+" ! video/x-raw-yuv,width=320,height=240 ! autovideosink")
bus = self.player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect("message", self.on_message)
bus.connect("sync-message::element", self.on_sync_message)
self.player.set_state(gst.STATE_PLAYING)
def stop_cam(self):
self.button.set_label("Start Stream")
self.player.set_state(gst.STATE_NULL)
def start_stop(self, w):
if self.button.get_label() == "Start Stream":
self.button.set_label("Stop Stream")
self.player.set_state(gst.STATE_NULL)
dumpfile = self.recfile.get_text()
if dumpfile == ".ogg":
print "No dump file"
else:
print "Dumping to :", dumpfile
pipelist= []
devname = self.combodevice.get_active_text()
if self.vdevicetype.get_active_text() == "v4l":
pipelist.append("v4lsrc device="+devname)
else:
pipelist.append("v4l2src device="+devname)
pipelist.append("video/x-raw-yuv,width=320,height=240")
pipelist.append("queue")
pipelist.append("videorate")
framerate=self.comboframerate.get_active_text()
framerate=framerate.replace(":","/")
pipelist.append("video/x-raw-yuv,framerate="+framerate)
pipelist.append("videoscale")
size=self.combovsize.get_active_text()
sizes=size.split("x");
pipelist.append("video/x-raw-yuv,width="+sizes[0]+",height="+sizes[1])
pipelist.append("ffmpegcolorspace")
pipelist.append("tee name=tscreen")
pipelist.append("queue")
pipelist.append("autovideosink tscreen.")
pipelist.append("queue")
vquality = self.combovquality.get_active_text()
pipelist.append("theoraenc quality="+vquality)
pipelist.append("queue")
#audio input
adevice=self.comboadevice.get_active_text()
pipelist.append("oggmux name=mux osssrc device="+adevice)
arate=self.comboarate.get_active_text()
achannels=self.comboachannels.get_active_text()
pipelist.append("audio/x-raw-int,rate="+arate+",channels="+achannels)
pipelist.append("queue")
pipelist.append("audioconvert")
aquality=self.comboaquality.get_active_text()
pipelist.append("vorbisenc quality="+aquality)
pipelist.append("queue")
pipelist.append("mux. mux.")
pipelist.append("queue")
#recording part
if dumpfile != ".ogg":
pipelist.append("tee name= tfile")
pipelist.append("queue")
pipelist.append("filesink location="+dumpfile+" tfile.")
pipelist.append("queue")
#last but not least streaming
server=self.servername.get_text()
port=self.portnumber.get_text()
mount=self.mountpoint.get_text()
password=self.password.get_text()
sname=self.name.get_text()
sdesc=self.description.get_text()
sgenre=self.genre.get_text()
surl=self.url.get_text()
pipelist.append("shout2send ip="+server+" port="+port+" mount="+mount+" password="+password+" streamname="+sname+" description="+sdesc+" genre="+sgenre+" url="+surl)
# ouf!
pipeline = " ! ".join(pipelist)
print "gstreamer command : ", pipeline
self.player = gst.parse_launch (pipeline)
bus = self.player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect("message", self.on_message)
bus.connect("sync-message::element", self.on_sync_message)
self.player.set_state(gst.STATE_PLAYING)
self.statuslabel.set_markup("Streaming at "+framerate+" frames per second")
self.sstate = 'running'
else:
self.statuslabel.set_markup("Camera started...Ready to stream")
self.stop_stream()
self.sstate = 'preparing'
def exit(self, widget, data=None):
gtk.main_quit()
def on_file_dialog(self, w):
self.fchooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
self.fchooser.set_default_response(gtk.RESPONSE_OK)
response = self.fchooser.run()
if response == gtk.RESPONSE_OK:
self.recfile.set_text(self.fchooser.get_filename())
response = self.fchooser.destroy()
def on_message(self, bus, message):
t = message.type
if t == gst.MESSAGE_ERROR:
if self.sstate == 'preparing':
self.statuslabel.set_markup("Error initializing camera...Check your devices")
self.stop_cam()
if self.sstate == 'running':
self.statuslabel.set_markup("Error starting stream...Check your parameters")
self.stop_stream()
self.sstate = 'preparing'
err, debug = message.parse_error()
print "Error: %s" % err, debug
def on_sync_message(self, bus, message):
if message.structure is None:
return
message_name = message.structure.get_name()
if message_name == "prepare-xwindow-id":
# Assign the viewport
imagesink = message.src
imagesink.set_property("force-aspect-ratio", True)
imagesink.set_xwindow_id(self.movie_window.window.xid)
GTK_Main()
gtk.gdk.threads_init()
gtk.main()