[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