wxmedia video information and seeking

141 views
Skip to first unread message

Simon Ho

unread,
Jul 23, 2013, 2:12:41 AM7/23/13
to wxpytho...@googlegroups.com
I'm fairly new to wxpython and python in general and have been trying to create a video player using wxmedia.

i have a few questions:

1) at what point in the code should I use GetBestSize() to determine the size of my loaded video? And how can I then use that size to adjust the player dimensions? As of right now I have the player set to a proportion of the screen size, but this results in the video stretching, so I want to be able to get the video size, make the video as big as possible in the screen while maintaining the same aspect ratio

2) is there a way to get and store the current video frame (ie a screenshot)?

3) is there a better way to implement the time slider? I have disabled the slider because every time I use it the video lags as it tries to reach that point in the video. Is there a smoother way to do it?

4) is it possible to play a video backwards? or change its playback speed?

I'm on windows, and occasionally test on mac with python 2.7 if that makes a difference. I have attached the code for the program im writing

thanks!
videoSegment.py

Tim Roberts

unread,
Jul 23, 2013, 1:39:36 PM7/23/13
to wxpytho...@googlegroups.com
Simon Ho wrote:
>
> 1) at what point in the code should I use GetBestSize() to determine
> the size of my loaded video? And how can I then use that size to
> adjust the player dimensions? As of right now I have the player set to
> a proportion of the screen size, but this results in the video
> stretching, so I want to be able to get the video size, make the video
> as big as possible in the screen while maintaining the same aspect ratio

Well, you need to do it after you know the file has been loaded and
parsed. The MediaCtrl demo in the wxPython demos calls GetBestSize in a
periodic timer, but that is probably a bit much. You should be able to
resize your main window and have the sizers adjust your video frame
accordingly, but it will be up to you to figure out the adjustments
needed to keep the aspect ratio correct.


> 2) is there a way to get and store the current video frame (ie a
> screenshot)?

Not with the wx.media control. You can try using Blt from a DC to grab
a copy of your window, but even that can be problematic. Depending on
the capabilities of your graphics card, the video frames may not ever
stored in the frame buffer. The frames are drawn into an offscreen
overlay surface or texture surface, and the graphics card blends that
surface in when it refreshes the screen.


> 3) is there a better way to implement the time slider? I have disabled
> the slider because every time I use it the video lags as it tries to
> reach that point in the video. Is there a smoother way to do it?

The problem here is that a slider generates a LOT of events. You get an
event when you start sliding, then continuous events while you drag the
slider, then more events when you let go. As it is, you'll be pounding
the player with seek requests, and arbitrary seek requests in modern
video formats are expensive to handle. You might think about storing up
the last slider value, and then checking in a timer to see if the
desired seek point has changed since the last call.


> 4) is it possible to play a video backwards? or change its playback speed?

There is a SetPlaybackRate API, but not all of the players support it.
Playing an MPEG movie backwards, for example, is computationally
intensive and not often supported.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

David Woods

unread,
Jul 23, 2013, 4:33:59 PM7/23/13
to wxpytho...@googlegroups.com
Hi Simon,
>> 1) at what point in the code should I use GetBestSize() to determine
>> the size of my loaded video? And how can I then use that size to
>> adjust the player dimensions? As of right now I have the player set to
>> a proportion of the screen size, but this results in the video
>> stretching, so I want to be able to get the video size, make the video
>> as big as possible in the screen while maintaining the same aspect ratio
> Well, you need to do it after you know the file has been loaded and
> parsed. The MediaCtrl demo in the wxPython demos calls GetBestSize in a
> periodic timer, but that is probably a bit much. You should be able to
> resize your main window and have the sizers adjust your video frame
> accordingly, but it will be up to you to figure out the adjustments
> needed to keep the aspect ratio correct.

I always call it in the wx.EVT_SIZE events. IIRC, I call my Size event
once I know my media file is loaded.
>> 2) is there a way to get and store the current video frame (ie a
>> screenshot)?
> Not with the wx.media control. You can try using Blt from a DC to grab
> a copy of your window, but even that can be problematic. Depending on
> the capabilities of your graphics card, the video frames may not ever
> stored in the frame buffer. The frames are drawn into an offscreen
> overlay surface or texture surface, and the graphics card blends that
> surface in when it refreshes the screen.

I use FFmpeg for screen captures. It works okay, but was quite
difficult to get working on Windows and can be time-consuming as you get
further into the video file.
>> 3) is there a better way to implement the time slider? I have disabled
>> the slider because every time I use it the video lags as it tries to
>> reach that point in the video. Is there a smoother way to do it?
> The problem here is that a slider generates a LOT of events. You get an
> event when you start sliding, then continuous events while you drag the
> slider, then more events when you let go. As it is, you'll be pounding
> the player with seek requests, and arbitrary seek requests in modern
> video formats are expensive to handle. You might think about storing up
> the last slider value, and then checking in a timer to see if the
> desired seek point has changed since the last call.

Better than what? I've implemented a slider of my own that works with
from 1 to 4 simultaneous, synchronized media players. How well playback
works depends mostly on the characteristics of the media files
themselves. But if written correctly, the slider shouldn't interfere
with playback of a single media file. I'd look at what else could be
interfering with your playback speeds, say from events related to the
slider.
>> 4) is it possible to play a video backwards? or change its playback speed?
> There is a SetPlaybackRate API, but not all of the players support it.
> Playing an MPEG movie backwards, for example, is computationally
> intensive and not often supported.

The success of changing playback speed (when playing video forward)
varies heavily depending on the back end used and the media file
format. I've never tried playing video backwards outside of when users
are moving through a video file frame by frame manually, but I suppose
that calling lots and lots of seeks would work for some formats in some
back ends.

You're welcome to take a look at my source code at
http://sourceforge.net/projects/transana/ . Look particularly at the
video_player.py file, which implements a single instance of a media
player, and the VideoWindow.py file, which puts up to four video_players
into a window with a controller and a button for taking screen shots.
Also look at MediaConvert.py for the screen capture stuff.

David

Simon Ho

unread,
Jul 28, 2013, 2:05:40 AM7/28/13
to wxpytho...@googlegroups.com
with regards to my first problem, let me try to clarify what my goal/aim is:

i have a video player script that will let you choose a video, load it, and a button to play it (please see the attached skeleton code)

what I want is to:
1) be able to play the video back at the biggest size possible, whilst maintaining aspect ratio
2) always center the video in the frame (vertically and horizontally)

so the code starts with some default size and position values for the player and buttons (im using actual pixel values instead of sizers for this. the numbers in the attached file are just arbitrary, im making everything relative to the users display size in the final version)

once I load a video and hit play, I call GetBestSize(). this gets me the dimensions of the loaded video file

what i want to be able to do, and what i am currently stuck on, is how do you take the value returned from GetBestSize, and use that to resize the original video player/panel/window? and secondly, how do you use it to center the video irrespective of screen resolution?

something like EVT_SIZE will only get called when the window resizes, which I am not doing. I just want to be able to automatically set the player size and position based on the videos frame dimensions when I hit play

Im pretty new to wxpython so what I'm not seeing is a way to update attributes of a frame that has already been intialized - this is ultimately what I want to be able to do

thanks
Simon
sample.py

David Woods

unread,
Jul 29, 2013, 11:23:14 AM7/29/13
to wxpytho...@googlegroups.com
with regards to my first problem, let me try to clarify what my goal/aim is:

i have a video player script that will let you choose a video, load it, and a button to play it (please see the attached skeleton code)

what I want is to:
1) be able to play the video back at the biggest size possible, whilst maintaining aspect ratio
2) always center the video in the frame (vertically and horizontally)

so the code starts with some default size and position values for the player and buttons (im using actual pixel values instead of sizers for this. the numbers in the attached file are just arbitrary, im making everything relative to the users display size in the final version)

once I load a video and hit play, I call GetBestSize(). this gets me the dimensions of the loaded video file

what i want to be able to do, and what i am currently stuck on, is how do you take the value returned from GetBestSize, and use that to resize the original video player/panel/window? and secondly, how do you use it to center the video irrespective of screen resolution?

something like EVT_SIZE will only get called when the window resizes, which I am not doing. I just want to be able to automatically set the player size and position based on the videos frame dimensions when I hit play

Im pretty new to wxpython so what I'm not seeing is a way to update attributes of a frame that has already been intialized - this is ultimately what I want to be able to do

What I'd do is build a window with proper sizers to handle the screen layout and then resize the wxMediaCtrl widget when you get a new size value from GetBestSize(), probably in your wx.EVT_MEDIA_LOADED event.

My point is, you've really got a Sizers issue rather than a wxMediaCtrl issue.  See http://wiki.wxpython.org/UsingSizers .

David

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Simon Ho

unread,
Jul 29, 2013, 10:23:30 PM7/29/13
to wxpytho...@googlegroups.com
OK - so I've rebulit it using some nested boxsizers

and I can create an event handler for the EVT_MEDIA_LOADED event. within that I am using GetBestSize() to get video size, but how would you use those dimensions to (re)set the mediactrl widget?

I created the widget with some default dimensions (arbitrary), and it doesnt seem that the widget gets recreated at any point to be able to take the new dimensions from GetBestSize(). I guess what it comes down to is not knowing how to re-set the widget size once it has already been created

thanks
Simon

David Woods

unread,
Jul 30, 2013, 11:45:01 AM7/30/13
to wxpytho...@googlegroups.com
Once you know the size, use the widget's SetSize() or SetDimensions() method to change its size.

David


Reply all
Reply to author
Forward
0 new messages