zaheer - in flumotion/branches/newoverlay-1: .
flumotion/component/converters/overlay
flumotion-commit at lists.fluendo.com
flumotion-commit at lists.fluendo.com
Fri Feb 23 20:13:23 CET 2007
Author: zaheer
Date: Fri Feb 23 20:13:20 2007
New Revision: 4521
Added:
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/admin_gtk.py
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/osdparser.py
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/osdparsertest.py
Modified:
flumotion/branches/newoverlay-1/ChangeLog
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/Makefile.am
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/__init__.py
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/genimg.py
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.py
flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.xml
Log:
2007-02-23 Zaheer Abbas Merali <zaheerabbas at merali dot org>
* flumotion/component/converters/overlay/Makefile.am:
* flumotion/component/converters/overlay/__init__.py:
* flumotion/component/converters/overlay/admin_gtk.py:
* flumotion/component/converters/overlay/genimg.py:
* flumotion/component/converters/overlay/osdparser.py:
* flumotion/component/converters/overlay/osdparsertest.py:
* flumotion/component/converters/overlay/overlay.py:
* flumotion/component/converters/overlay/overlay.xml:
Start of rich overlay port.
Modified: flumotion/branches/newoverlay-1/ChangeLog
==============================================================================
--- flumotion/branches/newoverlay-1/ChangeLog (original)
+++ flumotion/branches/newoverlay-1/ChangeLog Fri Feb 23 20:13:20 2007
@@ -1,3 +1,15 @@
+2007-02-23 Zaheer Abbas Merali <zaheerabbas at merali dot org>
+
+ * flumotion/component/converters/overlay/Makefile.am:
+ * flumotion/component/converters/overlay/__init__.py:
+ * flumotion/component/converters/overlay/admin_gtk.py:
+ * flumotion/component/converters/overlay/genimg.py:
+ * flumotion/component/converters/overlay/osdparser.py:
+ * flumotion/component/converters/overlay/osdparsertest.py:
+ * flumotion/component/converters/overlay/overlay.py:
+ * flumotion/component/converters/overlay/overlay.xml:
+ Start of rich overlay port.
+
2007-02-22 Andy Wingo <wingo at pobox.com>
* bin/flumotion-tester.in (main): Fix bogus log statement, thanks
Modified: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/Makefile.am
==============================================================================
--- flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/Makefile.am (original)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/Makefile.am Fri Feb 23 20:13:20 2007
@@ -1,6 +1,6 @@
include $(top_srcdir)/common/python.mk
-component_PYTHON = __init__.py genimg.py overlay.py
+component_PYTHON = __init__.py genimg.py overlay.py osdparser.py
componentdir = $(libdir)/flumotion/python/flumotion/component/converters/overlay
component_DATA = \
Vera.ttf \
Modified: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/__init__.py
==============================================================================
--- flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/__init__.py (original)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/__init__.py Fri Feb 23 20:13:20 2007
@@ -1,9 +1,10 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
+# flumotion/component/converters/overlay/__init__.py
+#
# Flumotion - a streaming media server
-# Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
-# All rights reserved.
+# Copyright (C) 2004 Fluendo, S.L. (www.fluendo.com). All rights reserved.
# This file may be distributed and/or modified under the terms of
# the GNU General Public License version 2 as published by
Added: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/admin_gtk.py
==============================================================================
--- (empty file)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/admin_gtk.py Fri Feb 23 20:13:20 2007
@@ -0,0 +1,492 @@
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+#
+# flumotion/component/converters/hujjatoverlayadmin_gtk.py
+# admin client-side code for hujjatoverlay
+#
+# Flumotion - a streaming media server
+# Copyright (C) 2004,2005 Fluendo, S.L. (www.fluendo.com). All rights reserved.
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+# Licensees having purchased or holding a valid Flumotion Advanced
+# Streaming Server license may use this file in accordance with the
+# Flumotion Advanced Streaming Server Commercial License Agreement.
+# See "LICENSE.Flumotion" in the source distribution for more information.
+
+# Headers in this file shall remain intact.
+
+import os
+import gtk
+
+from flumotion.common import errors
+
+from flumotion.component.base.admin_gtk import BaseAdminGtk, BaseAdminGtkNode
+from flumotion.component.converters.hujjatoverlay import osdparser
+
+class ManipulateNode(BaseAdminGtkNode):
+ dragtarget = [ ( "application/x-fluosd-text", 0, 80) ]
+
+ def render(self):
+ gladeFile = os.path.join('flumotion', 'component', 'converters',
+ 'hujjatoverlay', 'hujjatoverlay.glade')
+ d = self.loadGladeFile(gladeFile)
+ d.addCallback(self._loadGladeFileCallback)
+ return d
+
+ def _loadGladeFileCallback(self, widgetTree):
+ self.wtree = widgetTree
+ self.labels = {}
+ self.overlayWidget = self.wtree.get_widget('hujjatoverlay-widget')
+ self.previewImage = self.wtree.get_widget('image-preview')
+ removeButton = self.wtree.get_widget('button-remove')
+
+ self.callRemote('notifyState')
+ imageEventBox = self.wtree.get_widget('eventbox-preview')
+ self.width = None
+ self.height = None
+ self.textboxes = None
+ imageEventBox.connect('button-press-event', self._image_clicked_cb)
+ # make image track motion of mouse so coords can be printed
+ imageEventBox.add_events(gtk.gdk.POINTER_MOTION_MASK)
+ imageEventBox.connect('motion-notify-event', self._image_motion_cb)
+ # make image a drag source and drag dest so text objects
+ # can be dragged around
+ imageEventBox.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_DROP, self.dragtarget,
+ gtk.gdk.ACTION_COPY)
+ imageEventBox.drag_source_set(gtk.gdk.BUTTON1_MASK, self.dragtarget,
+ gtk.gdk.ACTION_COPY)
+ self.dragsignal = [0,0,0,0]
+ self.dragsignal[0] = imageEventBox.connect("drag-data-get", self._drag_send_data_cb)
+ self.dragsignal[1] = imageEventBox.connect("drag-begin", self._drag_begin_cb)
+ self.dragsignal[2] = imageEventBox.connect("drag-data-received", self._drag_receive_data_cb)
+ self.dragsignal[3] = imageEventBox.connect("drag-drop", self._drag_drop_cb)
+ imageEventBox.connect("drag-motion", self._drag_motion_cb)
+
+ applyButton = self.wtree.get_widget('button-apply')
+ applyButton.connect('clicked', self._apply_button_clicked_cb)
+ selectButton = self.wtree.get_widget('button-select')
+ #selectButton.connect('toggled', self._select_button_toggled_cb)
+ textButton = self.wtree.get_widget('button-text')
+ self.textsignal = textButton.connect('toggled', self._text_button_toggled_cb)
+ self.selectsignal = 0
+ self.currenttool = "select"
+ self.overlayWidget.show_all()
+ self.shown = True
+ self.textentry_signalid = self.fontsize_signalid = self.fontcolor_signalid = self.rect_signalid = self.rectcolor_signalid = 0
+
+ # add signal to textbox remove
+ removeButton.connect('clicked', self._remove_button_clicked_cb)
+
+ return self.overlayWidget
+
+ def overlayChanged(self, overlayxml, width, height):
+ flu = osdparser.FluOsdParser()
+ flu.parse(overlayxml)
+ flu.set_values(width, height, True)
+ rawimg = flu.generate_image()
+ self.width = width
+ self.height = height
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, width, height, 4 * width)
+ #pixbufloader = gtk.gdk.PixbufLoader()
+ #pixbufloader.write(rawimgdata)
+ #self.pixbuf = pixbufloader.get_pixbuf()
+ #pixbufloader.close()
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+ # get the textboxes so that they can be used when people click in
+ # the image
+ self.textboxes = flu.get_text_boxes()
+
+ # make the text items insensitive
+ textentry = self.wtree.get_widget('entry-text')
+ fontsize = self.wtree.get_widget('spinbutton-fontsize')
+ fontcolor = self.wtree.get_widget('colorbutton-text')
+ rect = self.wtree.get_widget('checkbutton-rectangle')
+ rectcolor = self.wtree.get_widget('colorbutton-rectangle')
+ removebutton = self.wtree.get_widget('button-remove')
+
+ textentry.set_sensitive(0)
+ textentry.disconnect(self.textentry_signalid)
+ fontsize.set_sensitive(0)
+ fontsize.disconnect(self.fontsize_signalid)
+ fontcolor.set_sensitive(0)
+ fontcolor.disconnect(self.fontcolor_signalid)
+ rect.set_sensitive(0)
+ rect.disconnect(self.rect_signalid)
+ rectcolor.set_sensitive(0)
+ rectcolor.disconnect(self.rectcolor_signalid)
+ removebutton.set_sensitive(0)
+
+
+
+
+ def _image_clicked_cb(self, widget, event):
+ if event.button == 1 and self.currenttool == 'select':
+ # left click
+ # check if x pos and y pos of click inside image is inside any text
+ textbox = self._get_text_box_for_location(event.x, event.y)
+ self.lastx = event.x
+ self.lasty = event.y
+ if textbox != None:
+ self.current_textbox = textbox
+
+ textentry = self.wtree.get_widget('entry-text')
+ fontsize = self.wtree.get_widget('spinbutton-fontsize')
+ fontcolor = self.wtree.get_widget('colorbutton-text')
+ rect = self.wtree.get_widget('checkbutton-rectangle')
+ rectcolor = self.wtree.get_widget('colorbutton-rectangle')
+ removebutton = self.wtree.get_widget('button-remove')
+ # disconnect signals
+ textentry.set_sensitive(0)
+ textentry.disconnect(self.textentry_signalid)
+ fontsize.disconnect(self.fontsize_signalid)
+ fontcolor.disconnect(self.fontcolor_signalid)
+ rect.disconnect(self.rect_signalid)
+ rectcolor.disconnect(self.rectcolor_signalid)
+
+ # make the text items sensitive
+ textentry.set_sensitive(1)
+ textentry.set_text(textbox['text'])
+ self.textentry_signalid = textentry.connect('changed', self._entry_changed_cb)
+ fontsize.set_sensitive(1)
+ fontsize.set_value(textbox['fontsize'])
+ self.fontsize_signalid = fontsize.connect('changed', self._fontsize_changed_cb)
+ fontcolor.set_sensitive(1)
+ fontcolor.set_color(gtk.gdk.color_parse(textbox['fontcolour']))
+ self.fontcolor_signalid = fontcolor.connect('color-set',
+ self._font_color_changed_cb)
+ rect.set_sensitive(1)
+ rect.set_active(textbox['rect'])
+ self.rect_signalid = rect.connect('toggled', self._rect_changed_cb)
+
+ if textbox['rect'] == 1:
+ rectcolor.set_sensitive(1)
+ if textbox['rectcolour'] != None:
+ rectcolor.set_color(gtk.gdk.color_parse(textbox['rectcolour']))
+ self.rectcolor_signalid = rectcolor.connect('color-set',
+ self._rect_color_changed_cb)
+ removebutton.set_sensitive(1)
+
+ elif event.button == 1 and self.currenttool == 'text':
+ # text tool enabled so create a new textbox
+ textbox = {}
+ textbox['text'] = ""
+ textbox['fontsize'] = 13
+ textbox['fontcolour'] = '#ffffff'
+ textbox['rect'] = 0
+ textbox['rectcolour'] = '#ffffff'
+ textbox['x1'] = int(event.x)
+ textbox['y1'] = int(event.y)
+ # make the text items sensitive
+ textentry = self.wtree.get_widget('entry-text')
+ fontsize = self.wtree.get_widget('spinbutton-fontsize')
+ fontcolor = self.wtree.get_widget('colorbutton-text')
+ rect = self.wtree.get_widget('checkbutton-rectangle')
+ rectcolor = self.wtree.get_widget('colorbutton-rectangle')
+ removebutton = self.wtree.get_widget('button-remove')
+
+ textentry.set_sensitive(1)
+ textentry.set_text(textbox['text'])
+ self.textentry_signalid = textentry.connect('changed', self._entry_changed_cb)
+ fontsize.set_sensitive(1)
+ fontsize.set_value(textbox['fontsize'])
+ self.fontsize_signalid = fontsize.connect('changed', self._fontsize_changed_cb)
+ fontcolor.set_sensitive(1)
+ fontcolor.set_color(gtk.gdk.color_parse(textbox['fontcolour']))
+ self.fontcolor_signalid = fontcolor.connect('color-set',
+ self._font_color_changed_cb)
+ rect.set_sensitive(1)
+ rect.set_active(textbox['rect'])
+ self.rect_signalid = rect.connect('toggled', self._rect_changed_cb)
+
+ if textbox['rect'] == 1:
+ rectcolor.set_sensitive(1)
+ if textbox['rectcolour'] != None:
+ rectcolor.set_color(gtk.gdk.color_parse(textbox['rectcolour']))
+ self.rectcolor_signalid = rectcolor.connect('color-set',
+ self._rect_color_changed_cb)
+
+ self.textboxes.append(textbox)
+ flu = osdparser.FluOsdParser()
+ overlayxml = flu.gen_overlayxml_from_text_boxes(self.textboxes)
+ flu.parse(overlayxml)
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+ self.textboxes = flu.get_text_boxes()
+ self.current_textbox = self.textboxes[len(self.textboxes)-1]
+ removebutton.set_sensitive(1)
+ #removebutton.connect('clicked', self._remove_button_clicked_cb)
+
+
+
+
+
+
+ def _image_motion_cb(self, widget, event):
+ label = self.wtree.get_widget('label-preview-position')
+ label.set_text('(%d,%d)' % (event.x, event.y))
+
+ def _entry_changed_cb(self, widget):
+ self.current_textbox['text'] = widget.get_text()
+ flu = osdparser.FluOsdParser()
+ overlayxml = flu.gen_overlayxml_from_text_boxes(self.textboxes)
+ flu.parse(overlayxml)
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+
+
+
+
+ def _fontsize_changed_cb(self, widget):
+ self.current_textbox['fontsize'] = int(widget.get_text())
+ flu = osdparser.FluOsdParser()
+ flu.parse(flu.gen_overlayxml_from_text_boxes(self.textboxes))
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+
+ def _font_color_changed_cb(self, widget):
+ fontcolor = widget.get_color()
+ self.current_textbox['fontcolour'] = '#%02x%02x%02x' % (fontcolor.red/256, fontcolor.green/256, fontcolor.blue/256)
+ flu = osdparser.FluOsdParser()
+ flu.parse(flu.gen_overlayxml_from_text_boxes(self.textboxes))
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+ def _rect_changed_cb(self, widget):
+ rect = widget.get_active()
+ self.current_textbox['rect'] = rect
+ rectcolor = self.wtree.get_widget('colorbutton-rectangle')
+ rectcolor.set_sensitive(rect)
+ flu = osdparser.FluOsdParser()
+ flu.parse(flu.gen_overlayxml_from_text_boxes(self.textboxes))
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+ def _rect_color_changed_cb(self, widget):
+ rectcolor = widget.get_color()
+ self.current_textbox['rectcolour'] = '#%02x%02x%02x' % (rectcolor.red/256, rectcolor.green/256, rectcolor.blue/256)
+ flu = osdparser.FluOsdParser()
+ flu.parse(flu.gen_overlayxml_from_text_boxes(self.textboxes))
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+
+
+
+
+ def _apply_button_clicked_cb(self, widget):
+ flu = osdparser.FluOsdParser()
+ overlayxml = flu.gen_overlayxml_from_text_boxes(self.textboxes)
+ self.callRemote("changeOverlay", overlayxml)
+
+ def _get_text_box_for_location(self, x, y):
+ # go through and check intersection of x and y values
+ print self.textboxes
+ for textbox in self.textboxes:
+ if textbox['x1'] < x and textbox['x2'] > x and textbox['y1'] < y and textbox['y2'] > y:
+ # this textbox intersects
+ return textbox
+ return None
+
+ def _drag_begin_cb(self, widget, context):
+ # set the icon to the text being dragged
+ print "ZAHEER: drag begin"
+ flu = osdparser.FluOsdParser()
+ image = flu.gen_image_from_textbox(self.current_textbox)
+ textpixbuf = gtk.gdk.pixbuf_new_from_data(image[0],
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, image[1], image[2], 4 * image[1])
+ context.set_icon_pixbuf(textpixbuf, 0, 0)
+
+
+ def _drag_send_data_cb(self, widget, context, selection, info, time):
+ print "ZAHEER: drag source"
+ self.dragtextbox = self._get_text_box_for_location(self.lastx, self.lasty)
+ if self.dragtextbox != None:
+ print "ZAHEER: dragging something that intersects (%d,%d)" % (self.lastx, self.lasty)
+ print self.dragtextbox['text']
+ selection.set(selection.target, 8, "yes")
+ else:
+ print "ZAHEER: dragging nothing"
+ selection.set(selection.target, 8, "no")
+
+ def _drag_receive_data_cb(self, widget, context, x, y, selection, info, time):
+ print "ZAHEER: received drag to %d,%d" % (x,y)
+ # set new x and y on textbox
+ if self.dragtextbox != None:
+ print "ZAHEER: actually moving text"
+ self.dragtextbox['x1'] = int(x)
+ self.dragtextbox['y1'] = int(y)
+ # need to set x2,y2 easiest way is to get the resulting textboxes
+ # from the parser
+ flu = osdparser.FluOsdParser()
+ flu.parse(flu.gen_overlayxml_from_text_boxes(self.textboxes))
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.textboxes = flu.get_text_boxes()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+ context.finish(1, 0, time)
+
+ def _drag_drop_cb(self, widget, context, x, y, time):
+ print "ZAHEER: drag_drop"
+
+ def _drag_motion_cb(self, widget, context, x, y, time):
+ label = self.wtree.get_widget('label-preview-position')
+ label.set_text('(%d,%d)' % (x, y))
+
+ # ok this is the plan
+ # we only have a signal connected if the tool is off
+ # so if the select button is on, the signal should be disconnected
+ def _select_button_toggled_cb(self, widget):
+ # get the widget for the text tool as that has to be toggled
+ textbutton = self.wtree.get_widget('button-text')
+ # check if select button is active or not
+ if widget.get_active():
+ # off -> on
+ print "ZAHEER: select button on"
+ # connect the drag signals
+ imageEventBox = self.wtree.get_widget('eventbox-preview')
+ imageEventBox.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_DROP, self.dragtarget,
+ gtk.gdk.ACTION_COPY)
+ imageEventBox.drag_source_set(gtk.gdk.BUTTON1_MASK, self.dragtarget,
+ gtk.gdk.ACTION_COPY)
+
+ self.dragsignal[0] = imageEventBox.connect("drag-data-get", self._drag_send_data_cb)
+ self.dragsignal[1] = imageEventBox.connect("drag-begin", self._drag_begin_cb)
+ self.dragsignal[2] = imageEventBox.connect("drag-data-received", self._drag_receive_data_cb)
+ self.dragsignal[3] = imageEventBox.connect("drag-drop", self._drag_drop_cb)
+ # now toggle the text button
+ textbutton.set_active(0)
+ self.textsignal = textbutton.connect('toggled', self._text_button_toggled_cb)
+ widget.disconnect(self.selectsignal)
+ self.selectsignal = 0
+ self.currenttool = "select"
+ else:
+ print "ZAHEER: why is selectbutton connected?"
+
+ def _text_button_toggled_cb(self, widget):
+ # get the widget for the select tool as that has to be toggled
+ selectbutton = self.wtree.get_widget('button-select')
+ # check if text button is active or not
+ if widget.get_active():
+ # off -> on
+
+ # disconnect drag signals
+ imageEventBox = self.wtree.get_widget('eventbox-preview')
+ imageEventBox.drag_source_unset()
+ imageEventBox.drag_dest_unset()
+
+ for i in range(0,3):
+ imageEventBox.disconnect(self.dragsignal[i])
+
+ selectbutton.set_active(0)
+ widget.disconnect(self.textsignal)
+ self.selectsignal = selectbutton.connect('toggled', self._select_button_toggled_cb)
+ self.textsignal = 0
+ self.currenttool = "text"
+ else:
+ print "ZAHEER: why is textbutton connected?"
+
+ def _remove_button_clicked_cb(self, widget):
+ print "ZAHEER: removing textbox"
+ print self.current_textbox
+ self.textboxes.remove(self.current_textbox)
+ self.current_textbox = None
+ flu = osdparser.FluOsdParser()
+ overlayxml = flu.gen_overlayxml_from_text_boxes(self.textboxes)
+ flu.parse(overlayxml)
+ flu.set_values(self.width, self.height, True)
+ rawimg = flu.generate_image()
+ self.pixbuf = gtk.gdk.pixbuf_new_from_data(rawimg,
+ gtk.gdk.COLORSPACE_RGB,
+ 1, 8, self.width, self.height, 4 * self.width)
+ #pixbufloader = gtk.gdk.PixbufLoader()
+ #pixbufloader.write(rawimgdata)
+ #self.pixbuf = pixbufloader.get_pixbuf()
+ #pixbufloader.close()
+ self.previewImage.set_from_pixbuf(self.pixbuf)
+
+ # get the textboxes so that they can be used when people click in
+ # the image
+ self.textboxes = flu.get_text_boxes()
+
+ # make the text items insensitive
+ textentry = self.wtree.get_widget('entry-text')
+ fontsize = self.wtree.get_widget('spinbutton-fontsize')
+ fontcolor = self.wtree.get_widget('colorbutton-text')
+ rect = self.wtree.get_widget('checkbutton-rectangle')
+ rectcolor = self.wtree.get_widget('colorbutton-rectangle')
+ removebutton = self.wtree.get_widget('button-remove')
+
+ textentry.set_sensitive(0)
+ textentry.disconnect(self.textentry_signalid)
+ fontsize.set_sensitive(0)
+ fontsize.disconnect(self.fontsize_signalid)
+ fontcolor.set_sensitive(0)
+ fontcolor.disconnect(self.fontcolor_signalid)
+ rect.set_sensitive(0)
+ rect.disconnect(self.rect_signalid)
+ rectcolor.set_sensitive(0)
+ rectcolor.disconnect(self.rect_signalid)
+ removebutton.set_sensitive(0)
+
+
+
+
+
+
+
+
+
+
+
+
+class HujjatOverlayAdminGtk(BaseAdminGtk):
+ def setup(self):
+ manipulate = ManipulateNode(self.state, self.admin, self.view)
+ self._nodes = {'Manipulate' : manipulate}
+
+ def getNodes(self):
+ return self._nodes
+
+ def component_overlayChanged(self, overlayxml, width, height):
+ self._nodes['Manipulate'].overlayChanged(overlayxml, width, height)
+
+GUIClass = HujjatOverlayAdminGtk
Modified: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/genimg.py
==============================================================================
--- flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/genimg.py (original)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/genimg.py Fri Feb 23 20:13:20 2007
@@ -1,9 +1,10 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
+# flumotion/component/converters/overlay/genimg.py: overlay image generator
+#
# Flumotion - a streaming media server
-# Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
-# All rights reserved.
+# Copyright (C) 2004 Fluendo, S.L. (www.fluendo.com). All rights reserved.
# This file may be distributed and/or modified under the terms of
# the GNU General Public License version 2 as published by
@@ -21,13 +22,17 @@
import os
+from PIL import Image
+from PIL import ImageChops
+from PIL import ImageDraw
+from PIL import ImageFont
+from PIL import ImageOps
+
directory = os.path.split(os.path.abspath(__file__))[0]
fontpath = os.path.join(directory, 'Vera.ttf')
logopath = directory
-fluendoLogoPath = os.path.join(logopath, 'fluendo.36x36.png')
-ccLogoPath = os.path.join(logopath, 'cc.36x36.png')
-xiphLogoPath = os.path.join(logopath, 'xiph.36x36.png')
+mainLogoPath = os.path.join(logopath, 'logo.36x36.png')
TEXT_XOFFSET = 6
TEXT_YOFFSET = 6
@@ -35,26 +40,15 @@
BORDER = 8
FONT_SIZE = 22
-def generate_overlay(filename, text, show_fluendo, show_cc, show_xiph,
- width, height):
- from PIL import Image
- from PIL import ImageChops
- from PIL import ImageDraw
- from PIL import ImageFont
- from PIL import ImageOps
-
+def generate_overlay(text, show_logo, width, height):
image = Image.new("RGBA", (width, height))
draw = ImageDraw.Draw(image) # inheriting color mode
- if text:
- font = ImageFont.truetype(fontpath, FONT_SIZE)
- draw.text((TEXT_XOFFSET+2, TEXT_YOFFSET+2),
- text, font=font, fill='black')
- draw.text((TEXT_XOFFSET, TEXT_YOFFSET),
- text, font=font)
-
- # How many logos we're going to show
- logos = len([i for i in (show_fluendo, show_cc, show_xiph) if i]) - 1
+ font = ImageFont.truetype(fontpath, FONT_SIZE)
+ draw.text((TEXT_XOFFSET+2, TEXT_YOFFSET+2),
+ text, font=font, fill='black')
+ draw.text((TEXT_XOFFSET, TEXT_YOFFSET),
+ text, font=font)
# This is really *NOT* the optimal way of doing this.
# We should really find out a better way of adding an image on
@@ -63,31 +57,16 @@
imax = max(width, height)
y_corr = -(abs(width - height) + WIDTH + BORDER)
- if show_xiph:
- xiph = Image.open(xiphLogoPath)
- xiph = ImageOps.expand(xiph, imax)
- xiph = ImageChops.offset(xiph, -width + (WIDTH*logos), y_corr)
- image = ImageChops.add_modulo(image, xiph)
- logos -= 1
-
- if show_cc:
- cc = Image.open(ccLogoPath)
- cc = ImageOps.expand(cc, imax)
- cc = ImageChops.offset(cc, -width + (WIDTH*logos), y_corr)
- image = ImageChops.add_modulo(image, cc)
- logos -= 1
-
- if show_fluendo:
- fluendo = Image.open(fluendoLogoPath)
- fluendo = ImageOps.expand(fluendo, imax)
- fluendo = ImageChops.offset(fluendo, -width, y_corr)
- image = ImageChops.add_modulo(image, fluendo)
-
- if os.path.exists(filename):
- os.unlink(filename)
+ if show_logo:
+ mainlogo = Image.open(mainLogoPath)
+ mainlogo = ImageOps.expand(mainlogo, imax)
+ mainlogo = ImageChops.offset(mainlogo, -width, y_corr)
+ image = ImageChops.add_modulo(image, mainlogo)
+
+ print "end of genimg"
+ return image.tostring()
- image.save(filename, 'png')
if __name__ == '__main__':
#generate_overlay('test.png', 'Testing', True, True, True, 320, 240)
- generate_overlay('test.png', 'Testing', True, True, True, 320, 240)
+ generate_overlay('Testing', True, 320, 240)
Added: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/osdparser.py
==============================================================================
--- (empty file)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/osdparser.py Fri Feb 23 20:13:20 2007
@@ -0,0 +1,223 @@
+import os
+
+from PIL import Image
+from PIL import ImageChops
+from PIL import ImageDraw
+from PIL import ImageFont
+from PIL import ImageOps
+
+from flumotion.common import log
+
+directory = os.path.split(os.path.abspath(__file__))[0]
+fontpath = os.path.join(directory, 'Vera.ttf')
+logopath = directory
+mainLogoPath = os.path.join(logopath, 'logo.36x36.png')
+
+from xml.dom import minidom, Node
+from xml.parsers import expat
+
+class FluOsdStrFileObject:
+ def __init__(self):
+ self.str = ""
+
+ def write(self,str):
+ self.str=self.str + str
+
+class FluOsdParser:
+ def __init__(self):
+ self.width = None
+ self.height = None
+ self.logo=True
+ self.logoborder = 8
+
+ def set_values(self,width,height,logo):
+ self.width = width
+ self.height = height
+ self.logo = logo
+
+ def parse(self,xmlstring):
+ self.doc = minidom.parseString(xmlstring)
+
+ def generate_image(self):
+ self.image = Image.new("RGBA", (self.width, self.height))
+
+ imax = max(self.width, self.height)
+
+ if self.logo:
+ mainlogo = Image.open(mainLogoPath)
+ mainlogoheight = mainlogo.size[1]
+ y_corr = -(abs(self.width - self.height) +mainlogoheight + self.logoborder)
+ mainlogo = ImageOps.expand(mainlogo, imax)
+ mainlogo = ImageChops.offset(mainlogo, -self.width, y_corr)
+ self.image = ImageChops.add_modulo(self.image, mainlogo)
+ draw = ImageDraw.Draw(self.image) # inheriting color mode
+
+
+ root = self.doc.documentElement
+ if not root.nodeName == 'fluosd':
+ raise Exception, "document not a fluosd document"
+ else:
+ for node in root.childNodes:
+ if node.nodeType != Node.ELEMENT_NODE:
+ continue
+ if node.nodeName == 'textarea':
+ if not node.hasAttribute('x'):
+ raise Exception, "<textarea> must have an x attribute"
+ else:
+ xpos = int(node.getAttribute('x'))
+ if not node.hasAttribute('y'):
+ raise Exception, "<textarea> must have a y attribute"
+ else:
+ ypos = int(node.getAttribute('y'))
+ if not node.hasAttribute('text'):
+ raise Exception, "<textarea> must have a text attribute"
+ else:
+ text = str(node.getAttribute('text'))
+ if not node.hasAttribute('fontsize'):
+ fontsize = 22
+ else:
+ fontsize = int(node.getAttribute('fontsize'))
+ if not node.hasAttribute('fontcolour'):
+ fontcolour = '#ffffff'
+ else:
+ fontcolour = str(node.getAttribute('fontcolour'))
+ if not node.hasAttribute('fontshadow'):
+ fontshadow = 1
+ else:
+ fontshadow = int(node.getAttribute('fontshadow'))
+ if node.hasAttribute('rect'):
+ rect = int(node.getAttribute('rect'))
+ if node.hasAttribute('rectcolour'):
+ rectcolour = str(node.getAttribute('rectcolour'))
+ else:
+ rectcolour = '#ffffff'
+ else:
+ rect = 0
+
+ font = ImageFont.truetype(fontpath, fontsize)
+ textsize = font.getsize(text)
+ if rect == 1:
+ draw.rectangle( [xpos-2,ypos-2,xpos+textsize[0]+4,ypos+textsize[1]+4],fill=rectcolour,outline='#000000')
+
+ if fontshadow == 1:
+ draw.text((xpos+2, ypos+2), text, font=font, fill='black')
+ draw.text((xpos, ypos), text, font=font, fill=fontcolour)
+ log.debug("we have text: %s with position (%d,%d) amd size %d" % (text,xpos,ypos,fontsize))
+ return self.image.tostring()
+
+ def generate_png(self):
+ str = FluOsdStrFileObject()
+ self.image.save(str, "png")
+ return str.str
+
+ def get_text_boxes(self):
+ retval = []
+ root = self.doc.documentElement
+ if not root.nodeName == 'fluosd':
+ raise Exception, "document not a fluosd document"
+ else:
+ for node in root.childNodes:
+ if node.nodeType != Node.ELEMENT_NODE:
+ continue
+ if node.nodeName == 'textarea':
+ current_textarea = {}
+ if not node.hasAttribute('x'):
+ raise Exception, "<textarea> must have an x attribute"
+ else:
+ current_textarea['x1'] = int(node.getAttribute('x'))
+ if not node.hasAttribute('y'):
+ raise Exception, "<textarea> must have a y attribute"
+ else:
+ current_textarea['y1'] = int(node.getAttribute('y'))
+ if not node.hasAttribute('text'):
+ raise Exception, "<textarea> must have a text attribute"
+ else:
+ current_textarea['text'] = str(node.getAttribute('text'))
+ if not node.hasAttribute('fontsize'):
+ current_textarea['fontsize'] = 22
+ else:
+ current_textarea['fontsize'] = int(node.getAttribute('fontsize'))
+ if not node.hasAttribute('fontcolour'):
+ current_textarea['fontcolour'] = '#ffffff'
+ else:
+ current_textarea['fontcolour'] = str(node.getAttribute('fontcolour'))
+ if not node.hasAttribute('fontshadow'):
+ current_textarea['fontshadow'] = 1
+ else:
+ current_textarea['fontshadow'] = int(node.getAttribute('fontshadow'))
+ if node.hasAttribute('rect'):
+ current_textarea['rect'] = int(node.getAttribute('rect'))
+ if node.hasAttribute('rectcolour'):
+ current_textarea['rectcolour'] = str(node.getAttribute('rectcolour'))
+ else:
+ current_textarea['rectcolour'] = '#ffffff'
+ else:
+ current_textarea['rect'] = 0
+ font = ImageFont.truetype(fontpath, current_textarea['fontsize'])
+ textsize = font.getsize(current_textarea['text'])
+ current_textarea['x2'] = current_textarea['x1'] + textsize[0]
+ current_textarea['y2'] = current_textarea['y1'] + textsize[1]
+
+
+ retval.append(current_textarea)
+ return retval
+
+ def gen_overlayxml_from_text_boxes(self, textboxes):
+ '''
+ Generate overlay xml content from an array of textbox dicts
+ '''
+ xmlelements = []
+ xmlelements.append("<fluosd>\n")
+ for textbox in textboxes:
+ xmlelements.append('<textarea text="%s" x="%d" y="%d" fontsize="%d" fontcolour="%s" rect="%d"' % (textbox['text'], textbox['x1'], textbox['y1'], textbox['fontsize'], textbox['fontcolour'], textbox['rect']))
+ if textbox['rect'] == 1:
+ xmlelements.append(' rectcolour="%s" />\n' % textbox['rectcolour'])
+ else:
+ xmlelements.append(' />\n')
+ xmlelements.append('</fluosd>')
+ return ''.join(xmlelements)
+
+ def gen_overlayxml_from_textbox(self, textbox):
+ xmlelements = []
+ xmlelements.append('<textarea text="%s" x="%d" y="%d" fontsize="%d" fontcolour="%s" rect="%d"' % (textbox['text'], textbox['x1'], textbox['y1'], textbox['fontsize'], textbox['fontcolour'], textbox['rect']))
+ if textbox['rect'] == 1:
+ xmlelements.append(' rectcolour="%s" />\n' % textbox['rectcolour'])
+ else:
+ xmlelements.append(' />\n')
+ return ''.join(xmlelements)
+
+ def gen_image_from_textbox(self, textbox):
+ # draw just the text
+
+ # first work out the size
+ font = ImageFont.truetype(fontpath, textbox['fontsize'])
+ textsize = font.getsize(textbox['text'])
+ textsizeadd = 0
+ # if shadow add 2 to width and height
+ if textbox['fontshadow'] == None:
+ textbox['fontshadow'] = 1
+ if textbox['fontshadow'] == 1:
+ textsizeadd = textsizeadd + 2
+ # if rect add 6 to width and height
+ if textbox['rect'] == 1:
+ textsizeadd = textsizeadd + 6
+
+ # create the Image object
+ image = Image.new("RGBA", (textsize[0] + textsizeadd, textsize[1] + textsizeadd))
+ draw = ImageDraw.Draw(image)
+
+ if textbox['rect'] == 1:
+ draw.rectangle( [0,0,xpos+textsize[0] + textsizeadd,textsize[1] + textsizeadd],fill=textbox['rectcolour'],outline='#000000')
+ if textbox['fontshadow'] == 1:
+ draw.text((2, 2), textbox['text'], font=font, fill='black')
+ draw.text((0, 0), textbox['text'], font=font, fill=textbox['fontcolour'])
+
+ return (image.tostring(), textsize[0] + textsizeadd, textsize[1] + textsizeadd)
+
+if __name__ == '__main__':
+ flu = FluOsdParser()
+ flu.set_values(320,240,True)
+ flu.parse('<fluosd><textarea x="44" y="200" fontsize="22" text="blah"/></fluosd>')
+ flu.generate_image()
+ print flu.get_text_boxes()
+
Added: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/osdparsertest.py
==============================================================================
--- (empty file)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/osdparsertest.py Fri Feb 23 20:13:20 2007
@@ -0,0 +1,182 @@
+import os
+import sys
+sys.path.insert(0, '/usr/lib/python2.3/site-packages')
+
+import pygtk
+pygtk.require('2.0')
+
+import warnings
+warnings.filterwarnings('ignore', category=UserWarning)
+
+dir = os.path.dirname(os.path.abspath(__file__))
+if os.path.exists(os.path.join(dir, '.svn')):
+ root = os.path.split(dir)[0]
+else:
+ root = os.path.join('/usr', 'lib', 'flumotion', 'python')
+sys.path.insert(0, root)
+
+from PIL import Image
+from PIL import ImageChops
+from PIL import ImageDraw
+from PIL import ImageFont
+from PIL import ImageOps
+
+from flumotion.common import log
+
+
+directory = os.path.split(os.path.abspath(__file__))[0]
+fontpath = os.path.join(directory, 'Vera.ttf')
+logopath = directory
+mainLogoPath = os.path.join(logopath, 'logo.36x36.png')
+
+from xml.dom import minidom, Node
+from xml.parsers import expat
+
+class FluOsdStrFileObject:
+ def __init__(self):
+ self.str = ""
+
+ def write(self,str):
+ self.str=self.str + str
+
+class FluOsdParser:
+ def __init__(self):
+ self.width=320
+ self.height=240
+ self.logo=True
+ self.logoborder=8
+
+ def set_values(self,width,height,logo):
+ self.width = width
+ self.height = height
+ self.logo = logo
+
+ def parse(self,xmlstring):
+ self.doc = minidom.parseString(xmlstring)
+
+ def generate_image(self):
+ self.image = Image.new("RGBA", (self.width, self.height))
+
+ imax = max(self.width, self.height)
+
+ if self.logo:
+ mainlogo = Image.open(mainLogoPath)
+ mainlogoheight = mainlogo.size[1]
+ y_corr = -(abs(self.width - self.height) +mainlogoheight + self.logoborder)
+ mainlogo = ImageOps.expand(mainlogo, imax)
+ mainlogo = ImageChops.offset(mainlogo, -self.width, y_corr)
+ self.image = ImageChops.add_modulo(self.image, mainlogo)
+ draw = ImageDraw.Draw(self.image) # inheriting color mode
+
+
+ root = self.doc.documentElement
+ if not root.nodeName == 'fluosd':
+ raise Exception, "document not a fluosd document"
+ else:
+ for node in root.childNodes:
+ if node.nodeType != Node.ELEMENT_NODE:
+ continue
+ if node.nodeName == 'textarea':
+ if not node.hasAttribute('x'):
+ raise Exception, "<textarea> must have an x attribute"
+ else:
+ xpos = int(node.getAttribute('x'))
+ if not node.hasAttribute('y'):
+ raise Exception, "<textarea> must have a y attribute"
+ else:
+ ypos = int(node.getAttribute('y'))
+ if not node.hasAttribute('text'):
+ raise Exception, "<textarea> must have a text attribute"
+ else:
+ text = str(node.getAttribute('text'))
+ if not node.hasAttribute('fontsize'):
+ fontsize = 22
+ else:
+ fontsize = int(node.getAttribute('fontsize'))
+ if not node.hasAttribute('fontcolour'):
+ fontcolour = '#ffffff'
+ else:
+ fontcolour = str(node.getAttribute('fontcolour'))
+ if not node.hasAttribute('fontshadow'):
+ fontshadow = 1
+ else:
+ fontshadow = int(node.getAttribute('fontshadow'))
+ if node.hasAttribute('rect'):
+ rect = int(node.getAttribute('rect'))
+ if node.hasAttribute('rectcolour'):
+ rectcolour = str(node.getAttribute('rectcolour'))
+ else:
+ rectcolour = '#ffffff'
+ else:
+ rect = 0
+
+ font = ImageFont.truetype(fontpath, fontsize)
+ textsize = font.getsize(text)
+ if rect == 1:
+ draw.rectangle( [xpos-2,ypos-2,xpos+textsize[0]+4,ypos+textsize[1]+4],fill=rectcolour,outline='#000000')
+
+ if fontshadow == 1:
+ draw.text((xpos+2, ypos+2), text, font=font, fill='black')
+ draw.text((xpos, ypos), text, font=font, fill=fontcolour)
+ log.debug("we have text: %s with position (%d,%d) amd size %d" % (text,xpos,ypos,fontsize))
+ return self.image.tostring()
+
+ def generate_png(self):
+ str = FluOsdStrFileObject()
+ self.image.save(str, "png")
+ return str.str
+
+ def get_text_boxes(self):
+ retval = []
+ root = self.doc.documentElement
+ if not root.nodeName == 'fluosd':
+ raise Exception, "document not a fluosd document"
+ else:
+ for node in root.childNodes:
+ if node.nodeType != Node.ELEMENT_NODE:
+ continue
+ if node.nodeName == 'textarea':
+ current_textarea = {}
+ if not node.hasAttribute('x'):
+ raise Exception, "<textarea> must have an x attribute"
+ else:
+ current_textarea['x'] = int(node.getAttribute('x'))
+ if not node.hasAttribute('y'):
+ raise Exception, "<textarea> must have a y attribute"
+ else:
+ current_textarea['y'] = int(node.getAttribute('y'))
+ if not node.hasAttribute('text'):
+ raise Exception, "<textarea> must have a text attribute"
+ else:
+ current_textarea['text'] = str(node.getAttribute('text'))
+ if not node.hasAttribute('fontsize'):
+ current_textarea['fontsize'] = 22
+ else:
+ current_textarea['fontsize'] = int(node.getAttribute('fontsize'))
+ if not node.hasAttribute('fontcolour'):
+ current_textarea['fontcolour'] = '#ffffff'
+ else:
+ current_textarea['fontcolour'] = str(node.getAttribute('fontcolour'))
+ if not node.hasAttribute('fontshadow'):
+ current_textarea['fontshadow'] = 1
+ else:
+ current_textarea['fontshadow'] = int(node.getAttribute('fontshadow'))
+ if node.hasAttribute('rect'):
+ current_textarea['rect'] = int(node.getAttribute('rect'))
+ if node.hasAttribute('rectcolour'):
+ current_textarea['rectcolour'] = str(node.getAttribute('rectcolour'))
+ else:
+ current_textarea['rectcolour'] = '#ffffff'
+ else:
+ current_textarea['rect'] = 0
+
+ retval.append(current_textarea)
+ return retval
+
+if __name__ == '__main__':
+ flu = FluOsdParser()
+ flu.set_values(320,240,True)
+ flu.parse('<fluosd><textarea x="44" y="200" fontsize="22" text="blah"/></fluosd>')
+ flu.generate_image()
+ print flu.get_text_boxes()
+
Modified: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.py
==============================================================================
--- flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.py (original)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.py Fri Feb 23 20:13:20 2007
@@ -1,9 +1,10 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
+# flumotion/component/converters/overlay/overlay.py: overlay converter
+#
# Flumotion - a streaming media server
-# Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
-# All rights reserved.
+# Copyright (C) 2007 Fluendo, S.L. (www.fluendo.com). All rights reserved.
# This file may be distributed and/or modified under the terms of
# the GNU General Public License version 2 as published by
@@ -16,78 +17,65 @@
# Streaming Server license may use this file in accordance with the
# Flumotion Advanced Streaming Server Commercial License Agreement.
# See "LICENSE.Flumotion" in the source distribution for more information.
-
# Headers in this file shall remain intact.
-import os
+from flumotion.common import log
+from flumotion.component import feedcomponent
+from flumotion.component.converters.overlay import osdparser
-from twisted.internet import defer
+from twisted.internet import reactor, protocol
-from flumotion.common import log
+import gobject
-from flumotion.component import feedcomponent
-from flumotion.component.converters.overlay import genimg
+class overlayprotocol(protocol.DatagramProtocol):
+ def set_ho(self, ho):
+ self.ho = ho
-import tempfile
+ def datagramReceived(self, datagram, address):
+ self.ho.newtext(datagram)
class Overlay(feedcomponent.ParseLaunchComponent):
- _filename = None
+
+ def init(self):
+ self.uiState.addKey('overlay-xml', '<fluosd />')
def get_pipeline_string(self, properties):
- # due to createComponent entry pointism, we have to import inside our
- # function. PLEASE MAKE THE PAIN GO AWAY ? <- might not be
- # necessary still
-
- # we need an element that does RGBA -> AYUV so we can overlay png
- # this got added to ffmpegcolorspace in 0.8.5
- addalpha = 'ffmpegcolorspace'
-
- source = self.config['source'][0]
- eater = '@ eater:%s @' % source
-
- # the order here is important; to have our eater be the reference
- # stream for videomixer it needs to be specified last
- pipeline = (
- 'filesrc name=source blocksize=100000 ! pngdec ! alphacolor ! '
- 'videomixer name=mix ! @ feeder:: @ '
- '%(eater)s ! %(addalpha)s ! mix.' % locals())
-
- return pipeline
+ overlayxml = properties.get('overlay-xml', '<fluosd />')
+ width = properties.get('width')
+ height = properties.get('height')
+
+ self.flu = osdparser.FluOsdParser(width, height)
+ self.flu.parse(self.overlayxml)
+ self.imbuf = self.flu.generate_image()
+
+ pipeline = "ffmpegcolorspace ! alpha ! mix." + \
+ "fakesrc name=source signal-handoffs=1 silent=true ! " + \
+ "video/x-raw-rgb,bpp=32,width=%d,height=%d,framerate=1.0 ! " % (
+ width, height) + \
+ "alphacolor ! videomixer name=mix" + \
+ " mix."
+ return pipeline
+
def configure_pipeline(self, pipeline, properties):
- self.fixRenamedProperties(properties, [
- ('show_text', 'show-text'),
- ('fluendo_logo', 'fluendo-logo'),
- ('cc_logo', 'cc-logo'),
- ('xiph_logo', 'xiph-logo')
- ])
-
- # create temp file
- (fd, self._filename) = tempfile.mkstemp('flumotion.png')
- os.close(fd)
-
- text = None
- if properties.get('show-text', False):
- text = properties.get('text', 'set the "text" property')
- genimg.generate_overlay(self._filename,
- text,
- properties.get('fluendo-logo', False),
- properties.get('cc-logo', False),
- properties.get('xiph-logo', False),
- properties['width'],
- properties['height'])
-
- source = self.get_element('source')
- source.set_property('location', self._filename)
+ source = pipeline.get_by_name('source')
+ source.connect('handoff', self.send_overlay_cb)
+ port = properties.get('overlay-port', 7861)
+ protocol = overlayprotocol()
+ protocol.set_ho(self)
+ self.ilp = reactor.listenUDP(port, protocol)
+
+ def send_overlay_cb(self, element, arg0, arg1, data=None):
+ arg0.set_buffer_data(self.imbuf)
+
+ def newtext(self,data):
+ try:
+ overlayxml = data
+ self.flu.parse(overlayxml)
+ self.imbuf = self.flu.generate_image()
+ self.uiState['overlay-xml'] = overlayxml
+ except Exception:
+ self.debug('blah','problem parsing %s' % data)
def do_stop(self):
- # clean up our temp file
- if self._filename:
- self.debug('Removing temporary overlay file %s' % self._filename)
- os.unlink(self._filename)
- self._filename = None
- else:
- self.debug("Temporary overlay already gone, " \
- "did we not start up correctly ?")
- return feedcomponent.ParseLaunchComponent.do_stop(self)
-
+ self.ilp.stopListening()
Modified: flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.xml
==============================================================================
--- flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.xml (original)
+++ flumotion/branches/newoverlay-1/flumotion/component/converters/overlay/overlay.xml Fri Feb 23 20:13:20 2007
@@ -56,6 +56,7 @@
<directory name="flumotion/component/converters/overlay">
<filename location="overlay.py" />
<filename location="genimg.py" />
+ <filename location="osdparser.py" />
<filename location="cc.24x24.png" />
<filename location="cc.36x36.png" />
<filename location="fluendo.24x24.png" />
More information about the flumotion-commit
mailing list