python timers and COM/directshow

S

Sayanan Sivaraman

Hey all,

So I've written a simple video player using directshow/COM in VC++,
and I'm in the process of translating it to python. For example, when
the avi starts playing, I have a call media_control.Run() , etc.

I'm wondering how I should go about updating my gtk.Hscale widget as a
trackbar for the avi player.

In C++, I have the following callbacks that update the scrollbar and
video position with a timer.

void CvideoDlg::OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT
*pResult)
{ //Slider event handler
LONGLONG lPos = 0;
LONGLONG lDuration = 0;
KillTimer(101);

g_pSeek->GetDuration(&lDuration);
g_pSeek->GetCurrentPosition(&lPos);


Videopos= m_slider.GetPos(); //Sets new video position to that of
the slider, which user inputs
lPos = ((long)Videopos * (lDuration/num_of_frames));


g_pSeek->SetPositions(&lPos, AM_SEEKING_AbsolutePositioning,NULL,
AM_SEEKING_NoPositioning);
*pResult = 0;
}
void CvideoDlg::OnTimer(UINT nIDEvent)
{ //Timer event handler.
LONGLONG lPos = 0;
LONGLONG lDuration = 0;

g_pSeek->GetDuration(&lDuration);
g_pSeek->GetCurrentPosition(&lPos);
Videopos = (int)(lPos * num_of_frames/ lDuration);
m_slider.SetPos(Videopos);
if (Videopos==(int)(last_frame)) //If we get to the end of the
selection, the video pauses
pause();
else{
UpdateData(); //Updates the slider controller and position
CDialog::OnTimer(nIDEvent);}

}

I'm wondering how I would implement similar callbacks in Python for a
gtk.Hscale, and some sort of time [I'm not familiar with Pythons
timers/threading at all].
 
T

Tim Golden

Sayanan said:
So I've written a simple video player using directshow/COM in VC++,
and I'm in the process of translating it to python. For example, when
the avi starts playing, I have a call media_control.Run() , etc.

I'm wondering how I should go about updating my gtk.Hscale widget as a
trackbar for the avi player.

In C++, I have the following callbacks that update the scrollbar and
video position with a timer.

[... snip callbacks ...]
I'm wondering how I would implement similar callbacks in Python for a
gtk.Hscale, and some sort of time [I'm not familiar with Pythons
timers/threading at all].


You'd help your cause a lot here if you posted *Python*
code to indicate what's calling what back where. Also if
you stated whether you were using, eg, the GTK toolkit which
your description suggests, or some other GUI toolkit. Because
they tend to vary as to how they arrange their callbacks.

In geeneral, Python callbacks are trivial: you create the
function to do whatever and then pass the function as an
object into the calling-back function call. Something
like this (invented GUI toolkit):

<code>
def handle_lbutton_click (event):
#
# do stuff with lbutton click
#

def handle_widget_slide (event):
#
# do stuff with widget slide
#


handle_event ("lbutton_click", handle_lbutton_click)
widget.attach_event ("slide", handle_widget_slide)

</code>

But the details will obviously depend on the toolkit you
use.

TJG
TJG
 
S

Sayanan Sivaraman

Sayanan said:
So I've written a simple video player using directshow/COM in VC++,
and I'm in the process of translating it to python.  For example, when
the avi starts playing, I have a call media_control.Run() , etc.
I'm wondering how I should go about updating my gtk.Hscale widget as a
trackbar for the avi player.
In C++, I have the following callbacks that update the scrollbar and
video position with a timer.

[... snip callbacks ...]


I'm wondering how I would implement similar callbacks in Python for a
gtk.Hscale, and some sort of time [I'm not familiar with Pythons
timers/threading at all].

You'd help your cause a lot here if you posted *Python*
code to indicate what's calling what back where. Also if
you stated whether you were using, eg, the GTK toolkit which
your description suggests, or some other GUI toolkit. Because
they tend to vary as to how they arrange their callbacks.

In geeneral, Python callbacks are trivial: you create the
function to do whatever and then pass the function as an
object into the calling-back function call. Something
like this (invented GUI toolkit):

<code>
def handle_lbutton_click (event):
  #
  # do stuff with lbutton click
  #

def handle_widget_slide (event):
  #
  # do stuff with widget slide
  #

handle_event ("lbutton_click", handle_lbutton_click)
widget.attach_event ("slide", handle_widget_slide)

</code>

But the details will obviously depend on the toolkit you
use.

TJG
TJG

Sorry, you make a very good point. I am using gtk. I don't have a
problem with callbacks for the gtk widgets. My question is about
timers and their callbacks. The reason I used c++ code is that
Microsoft's COM interface is natively in C++, and Python uses "import
comtypes" to access this functionality and the dll's.[ie
GetModule('quartz.dll')]

Essentially what I would like to have [as evidenced by the c++ code]
is something like the following:

def timer_callback(args):
while timer is active
update scrollbar position based on video progress

#here I am using microsoft's COM interface, so the function would
be something like
scrollbar.set_value(media_control.CurrentPosition)

def scrollbar_callback :
when the scrollbar is moved, update this video position
#this I understand. It would be something like
media_control.CurrentPosition= scrollbar.get_value()

def pauser :
media_control.Pause()
*somehow kill timer*

def player:
media_control.Run()
timer.run() #timer.run() would call timer_callback


So I would like to know how to construct and implement a timer that
would do the above, a la the first callback. In addition, the timer
has to be able to be paused/killed if I pause the video, and
implemented again if I play the video ie:


Thanks,
sayanan
 
S

Sayanan Sivaraman

You're right. Let me be more specific. Firstly, the reason I
included c++ code is because I'm using Microsoft COM, which is
natively in c++, and in fact, to access them through Python I use the
comtypes module [import comtypes] and then GetModule('quartz.dll') to
access the dll's.

I am using the gtk GUI widgets. I have a gtk.Hscale scrollbar which I
would like to be a trackbar for the video playback. To coordinate
this in Python, much like in c++, I would like to have a timer thread
synchronizing the scrollbar update. ie:

def scrollbar_callback(args):
media_control.CurrentPosition= scrollbar.get_value()

def timer_callback(args):
#code to update the scrollbar based on video position, something
like
scrollbar.set_value(media_control.CurrentPosition)

def player(args):
media_control.Run() #plays video
timer.run()

def pauser(args):
media_control.Pause()
timer.kill

Any tips?

-sayanan
 
S

Sayanan Sivaraman

Ok, so I actually found a solution to this out there, and decided I'd
post back here and share it.

import pygtk
pygtk.require('2.0')
import gtk
import ctypes
from ctypes import *
from comtypes import client
from ctypes.wintypes import *
import gobject

def delete_event(widget,event,data=None):
global filter_builder, filter_graph, media_control, vseek
media_control.Stop
vseek.Release
filter_builder.Release
GUIDATA.win1.Release
media_control.Release
filter_graph.Release
del GUIDATA.win1
del filter_graph
del vseek
del filter_builder
del media_control
del all
sys.exit([status])
os._exit(status)
gtk.main_quit()
exit()
return False

def pauser(widget,data=None):
global media_control,playing, scrollbar, vseek
if GUIDATA.data_loaded==0:
return 0
scrollbar.set_value(vseek.CurrentPosition*30)
media_control.Pause()
playing=0
return 0

def player(widget,data=None):
global media_control, vseek, scrollbar,playing
if GUIDATA.data_loaded==0:
return 0
media_control.Run()
playing=1
gobject.timeout_add(1,on_timer,scrollbar)

def scrollbar_callback(widget,scroll, data=None):
global media_control, vseek
vseek.CurrentPosition= scrollbar.get_value()/30
return 0
def on_timer(data=None):
global scrollbar, vseek, playing, media_control
if (playing==1)and
(vseek.CurrentPosition*30)<int(frame2.get_text()) :
g= vseek.CurrentPosition
scrollbar.set_value(g*30)
f= "%d" %(vseek.CurrentPosition*30)
curframe.set_text(f)
print "update"
return True




win = gtk.Window()
win.connect("destroy", lambda x: gtk.main_quit())
win.set_default_size(500,800)
win.set_title("LISA GUI")

filename= LPCWSTR("mymovie.avi")
#importing quartz.dll and qedit.dll for filtergraph construction
qedit = client.GetModule('qedit.dll') # DexterLib
quartz= client.GetModule('quartz.dll')

CLSID_FilterGraph = '{e436ebb3-524f-11ce-9f53-0020af0ba770}'
filter_graph =
client.CreateObject(CLSID_FilterGraph,interface=qedit.IFilterGraph)
filter_builder = filter_graph.QueryInterface(qedit.IGraphBuilder)
media_control = filter_builder.QueryInterface(quartz.IMediaControl)
GUIDATA.win1= filter_builder.QueryInterface(quartz.IVideoWindow)
filter_builder.RenderFile(GUIDATA.video, None)
GUIDATA.win1.SetWindowPosition(512, 0, 512, 400)
vseek=filter_graph.QueryInterface(interface=quartz.IMediaPosition)



adj= gtk.Adjustment(1,1,30*vseek.Duration+1,1,1.0,1.0)
scrollbar = gtk.HScale(adj)
scrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS)
scrollbar.connect("change_value",scrollbar_callback)
scrollbar.show()
hbox6=gtk.HBox(False,0)
hbox6.pack_start(scrollbar,True,True)
hbox6.show()
vbox.pack_end(hbox6,False,True)



play_video= gtk.Button("Play")
play_video.connect("clicked",player)
play_video.show()

pause_video= gtk.Button("Pause")
pause_video.connect("clicked",pauser)
pause_video.show()

hbox4= gtk.HBox(False,0)
hbox4.pack_start(play_video,True,True)
hbox4.pack_start(pause_video,True,True)
hbox4.show()
vbox.pack_end(hbox4,False,True)
vbox.show()
win.add(vbox)
win.show_all()
gtk.main()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top