oro777
oro777

Reputation: 1110

Videoplayer in MATLAB, holding the slider control

I have created a GUI allowing to play a Video file. I use a uicontrol to create a slider, it works on basic use cases (when I click relatively slowly on the slider). If I hold my mouse left button on the right arrow of the slider for a certain time, MATLAB will return an error(saying it cannot read the frame) on the line reading the frame of the video.

I guess the machine does not have the time to process the video at high pace, is there a way to solve this problem ?

Here is my code.

function test_video
    figure;
    hAxes = axes;
    hSlider = uicontrol( 'Style', 'Slider' );
    hSlider.Position(3) = 500;
    hSlider.Callback = @Slider_Callback;

    Reader = VideoReader( 'MyVideo.mp4' );
    f = Reader.readFrame();
    imshow( f, 'Parent', hAxes );

    hSlider.Value = 1;
    hSlider.Min = 1;
    hSlider.Max = Reader.NumFrames-1;
    iFrameRate = Reader.FrameRate;
    function Slider_Callback( varargin )
        iFrame = floor( varargin{ 1 }.Value );
        dCurrentTime = iFrame / iFrameRate;
        Reader.CurrentTime = dCurrentTime;
        f = Reader.readFrame();
        imshow( f, 'Parent', hAxes );
    end % Slider_Callback
end

The error occurs on the line in the callback function :

f = Reader.readFrame();

It also has an error in the built-in function(asyncio.Stream/wait).

drawnow('limitrate');

Upvotes: 1

Views: 121

Answers (1)

Rotem
Rotem

Reputation: 32104

I can't test the solution, but you may try adding a flag that prevents the callback execution when it's already running:

I made some other changes to your code (for testing):

function test_video()
close all
figure;
hAxes = axes;
hSlider = uicontrol('Style', 'Slider');
hSlider.Position(3) = 500;
hSlider.Callback = @Slider_Callback;

Reader = VideoReader('MyVideo.avi');

f = Reader.readFrame();
imshow(f, 'Parent', hAxes);

NumFrames = Reader.Duration * Reader.FrameRate; %Reader.NumFrames;
hSlider.Value = 0;
hSlider.Min = 0;
hSlider.Max = NumFrames - 1; %Reader.NumFrames-1;
iFrameRate = Reader.FrameRate;

is_inside_callback = false;

function Slider_Callback(varargin)
    if ~is_inside_callback
        is_inside_callback = true;
        iFrame = floor(varargin{1}.Value);
        dCurrentTime = iFrame / iFrameRate;
        Reader.CurrentTime = dCurrentTime;
        f = Reader.readFrame();
        imshow(f, 'Parent', hAxes);
        is_inside_callback = false;
    end
end % Slider_Callback

end

Upvotes: 1

Related Questions