[Cvs-annodex] commit (annodex): keystroke/trunk/keystroke.py +keystroke/trunk/textsrc.py

scott nobody at lists.annodex.net
Mon Oct 2 08:47:33 UTC 2006


Update of /var/local/lib/svn/annodex (new revision 2510)

Added files:
   keystroke/trunk/textsrc.py

Modified files:
   keystroke/trunk/keystroke.py

Log Message:
On a good day, you will have two random subtitle show at the beginning.

Modified: keystroke/trunk/keystroke.py
===================================================================
--- keystroke/trunk/keystroke.py	2006-10-02 08:41:03 UTC (rev 2509)
+++ keystroke/trunk/keystroke.py	2006-10-02 08:47:31 UTC (rev 2510)
@@ -46,6 +46,11 @@
 import gst
 import mimetypes
 
+#Import custom element
+import gobject
+from textsrc import TextSource
+gobject.type_register(TextSource)
+
 def format_time(time):
   hour = int(time)/1000/3600
   if hour<10:
@@ -75,7 +80,7 @@
   h,m,ms = string.replace(".","").split(":")
   return int(h)*3600*1000 + int(m)*60*1000 + int(ms)
 
-class Annotool:
+class Keystroke:
   #This class handles all aspects of the program.  Nothing fancy here.
   
   #Below are all of our callbacks.
@@ -275,9 +280,24 @@
       if self.debug: print "Error: Trying to seek to two identical times at " + start + "!"
       return
     elif end==None:
-      return self.pipeline.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, gst.MSECOND*to_ms(start), gst.SEEK_TYPE_SET, self.pipeline_duration*gst.MSECOND)
+      result = self.pipeline.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, gst.MSECOND*to_ms(start), gst.SEEK_TYPE_SET, self.pipeline_duration*gst.MSECOND)
     else:
-      return self.pipeline.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, gst.MSECOND*to_ms(start), gst.SEEK_TYPE_SET, gst.MSECOND*to_ms(end))
+      result = self.pipeline.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, gst.MSECOND*to_ms(start), gst.SEEK_TYPE_SET, gst.MSECOND*to_ms(end))
+    #Push relevant text to overlay.
+    return result
+    
+  def push_text_cb(self, accel_group, window, keyval, modifier):
+    self.push_text()
+    
+  def push_text(self, start=None,end=None):
+    #data = self.export_buffer()
+    #for clip in data["subtitle-en"]:
+      #buf = gst.Buffer (clip[2])
+      #buf.timestamp = to_ms(clip[0])*gst.MSECOND
+      #buf.duration = (to_ms(clip[1]) - to_ms(clip[0]))*gst.MSECOND
+      #print "time: " + str(buf.timestamp) + " duration: " + str(buf.duration)
+      #print self.text_pad.push (buf)
+    pass
       
   def enter_activated(self, accel_group, window, keyval, modifier):
     #Handles clip to text buffer, formatting and pipeline control.
@@ -508,6 +528,7 @@
     self.progress.props.fraction = 0
     total_clips = len(clips)
     x=0
+    self.pipeline.get_state() # Let pipeline catch up to script.
     for node in clips:
       # load data
       start_time = node.getAttribute('start')
@@ -575,7 +596,6 @@
         mark.set_visible(self.visible_marks)
       x += 1
       self.progress.props.fraction = x/total_clips
-    self.pipeline.get_state() # Let pipeline catch up to script.
     self.pipeline_duration = self.pipeline.query_duration(gst.FORMAT_TIME)[0]/gst.MSECOND
     if (end_time!="" and to_ms(end_time) < self.pipeline_duration-3*60*1000) or to_ms(start_time) < self.pipeline_duration-4*60*1000: #If last clip is towards end, skip and play from the beginning.  If not go to the last clip.
       if end_time!="":
@@ -626,6 +646,12 @@
   def bus_call(self, bus, message):
     if message.type == gst.MESSAGE_ERROR:
       print message.parse_error()[1]
+    elif message.type == gst.MESSAGE_STATE_CHANGED and (message.parse_state_changed()[0]==gst.STATE_PAUSED or message.parse_state_changed()[0]==gst.STATE_PLAYING) and message.parse_state_changed()[2]==gst.STATE_VOID_PENDING and message.src == self.pipeline:
+      print message.parse_state_changed()
+      self.push_text()
+    else:
+      #print "Unhandled: " + str(message.type)
+      pass
     return True
   
   #Below are functions generally called once.
@@ -634,7 +660,7 @@
     self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
     self.window.connect("delete_event", self.delete_event)
     self.window.connect("destroy", self.destroy)
-    self.window.set_title("Annotool")
+    self.window.set_title("Keystroke - Martini Alpha")
     self.window.set_default_size(500,300)
     self.vbox = gtk.VBox()
     
@@ -648,6 +674,7 @@
     self.accels.connect_group(gtk.gdk.keyval_from_name("r"),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE,self.restart_clip) # ctrl - r
     self.accels.connect_group(gtk.gdk.keyval_from_name("p"),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE,self.just_play) # ctrl - p
     self.accels.connect_group(gtk.gdk.keyval_from_name("i"),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE,self.import_file) # ctrl - i
+    self.accels.connect_group(gtk.gdk.keyval_from_name("w"),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE,self.push_text_cb) # ctrl - w
     self.accels.connect_group(gtk.gdk.keyval_from_name("Return"),0,gtk.ACCEL_VISIBLE,self.enter_activated) # enter
     self.window.add_accel_group(self.accels)
     
@@ -698,27 +725,31 @@
     self.window.set_border_width(6)
     
     #gstreamer setup
-    self.use_overlays = False
+    self.use_overlays = True
     self.pipeline = gst.Pipeline()
     self.playbin = gst.element_factory_make ("playbin")
     self.playbin.props.audio_sink = gst.element_factory_make ("alsasink")
     if self.use_overlays:
       self.video_process = gst.Bin()
-      #self.timeoverlay = gst.element_factory_make ("timeoverlay")
+      self.timeoverlay = gst.element_factory_make ("timeoverlay")
       self.textoverlay = gst.element_factory_make ("textoverlay")
-      self.textoverlay.props.text = "An Annotool test."
       self.xvimagesink = gst.element_factory_make ("xvimagesink")
-      self.video_process.add (self.textoverlay,self.xvimagesink)
-      #self.pad = gst.Pad ("mysrc", gst.PAD_SRC)
-      #self.pad.set_caps (gst.Caps ("text/plain"))
-      #self.pad.link (self.textoverlay.get_pad ("text_sink"))
-      #self.timeoverlay.link(self.textoverlay)
-      self.textoverlay.link (self.xvimagesink)
-      self.video_process.add_pad (gst.GhostPad ("sink",self.textoverlay.get_pad ("video_sink")))
+      self.effect = gst.element_factory_make ("agingtv")
+      self.colorspace = gst.element_factory_make("ffmpegcolorspace");
+      self.colorspace2 = gst.element_factory_make("ffmpegcolorspace");
+      self.textsource = TextSource()
+      self.video_process.add (self.timeoverlay,self.textoverlay,self.xvimagesink,self.textsource,self.effect,self.colorspace,self.colorspace2)
+      self.timeoverlay.link(self.textoverlay)
+      self.textsource.get_pad("src").link(self.textoverlay.get_pad ("text_sink"))
+      self.textoverlay.link(self.colorspace)
+      self.colorspace.link(self.effect)
+      self.effect.link(self.colorspace2)
+      self.colorspace2.link (self.xvimagesink)
+      self.video_process.add_pad (gst.GhostPad ("sink",self.timeoverlay.get_pad ("video_sink")))
       self.playbin.props.video_sink = self.video_process
     else:
-      self.playbin.props.video_sink = gst.element_factory_make ("ximagesink")
-    self.playbin.props.vis_plugin = gst.element_factory_make ("libvisual_corona")
+      self.playbin.props.video_sink = gst.element_factory_make ("cacasink")
+    self.playbin.props.vis_plugin = gst.element_factory_make ("goom")
 
     self.pipeline.add (self.playbin)
     bus = self.pipeline.get_bus()
@@ -733,7 +764,7 @@
     self.mode = 'transcribe'
     self.show_keystrokes = False
     self.debug = False
-    
+
     self.window.show_all()
     self.clip_text.grab_focus()
     
@@ -741,5 +772,5 @@
     gtk.main()
     
 if __name__ == "__main__":
-  annotool = Annotool()
-  annotool.main()
+  keystroke = Keystroke()
+  keystroke.main()

Added: keystroke/trunk/textsrc.py
===================================================================
--- keystroke/trunk/textsrc.py	2006-10-02 08:41:03 UTC (rev 2509)
+++ keystroke/trunk/textsrc.py	2006-10-02 08:47:31 UTC (rev 2510)
@@ -0,0 +1,64 @@
+#! /usr/bin/env python
+"""
+This is a gstreamer source element which draws its data from an internal python dictionary variable.
+Copyright (C) 2006  Scott Shawcroft
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+"""
+import gobject
+import pygst
+pygst.require("0.10")
+import gst
+
+class TextSource (gst.PushSrc):
+  __gsttemplates__ = (
+    gst.PadTemplate("src",
+                    gst.PAD_SRC,
+                    gst.PAD_ALWAYS,
+                    gst.Caps("text/plain")),
+    )
+  
+  data = [[0*gst.MSECOND, 1958*gst.MSECOND,"...if you want to hold it."], [1958*gst.MSECOND,3627*gst.MSECOND,"Oh you gotta... Does this pick you up as well?"]]
+  current_index = 0
+  
+  def __init__(self, name="TextSource"):
+    self.__gobject_init__()
+    self.set_name(name)
+    self.set_format(gst.FORMAT_TIME)
+  
+  def do_check_get_range(self):
+    return True
+    
+  def do_create(self, offset, length):
+    print "CREATE: " + str(self.current_index)
+    if self.current_index < len(self.data):
+      buf = gst.Buffer(self.data[self.current_index][2])
+      buf.timestamp = self.data[self.current_index][0]
+      buf.duration = self.data[self.current_index][1]
+      self.current_index += 1
+      return gst.FLOW_OK, buf
+    else:
+      buf = gst.Buffer(" ")
+      buf.timestamp = self.data[-1][0]+self.data[-1][1]
+      buf.duration = 9999999*gst.SECOND # A really long time.  (FIXME)
+      return gst.FLOW_OK, buf
+      
+  def do_do_seek(self, segment):
+    print "SEEK"
+    self.current_index = 0
+    return True
+    
+  def do_is_seekable(self):
+    return True


-- 
scott



More information about the cvs-annodex mailing list