📄 mplay.m
字号:
function mov = mplay(varargin)
%MPLAY Play a movie interactively.
% MPLAY(A) opens a new movie player GUI and loads movie data
% A into the player. Multiple players may be used at one time.
%
% MPLAY(A, FMT) explicity specifies a format string FMT for the
% movie data, in case a warning from MPLAY(A) indicates ambiguity
% in interpreting the format of A.
%
% MPLAY(A, FPS) or MPLAY(A, FMT, FPS) specifies the default
% frame rate, FPS, for the movie, in frames per second. If
% omitted, FPS defaults to 30. The GUI supports interactive
% changes to FPS as well.
%
% M=MPLAY(...) returns a MoviePlayerAPI object, M, useful for
% programmatic control of the movie player GUI. A list of
% all available object methods is obtained from "methods(M)".
%
% Movie formats
% -------------
% Movie A may be one of the following formats:
%
% Standard MATLAB movie structure (FMT = 'structure' or 'S')
% See 'help getframe' for more information on the MATLAB
% movie structure. Only movies with empty .colormap field
% entries are supported.
%
% Intensity video array (FMT = 'intensity' or 'I')
% 3-D array organized as MxNxF, where each image is of size
% MxN and there are F image frames. An input with size
% exactly MxNx3 will be interpreted as a 3-frame intensity movie.
%
% RGB video array (FMT = 'RGB')
% 4-D array organized as MxNx3xF, where the R, G, and B
% are encoded in the 3rd dimension. Note that MxNx3 is
% the usual MATLAB format for an RGB image.
%
% Video frame data type may be double, uint8, or uint16.
%
% Keyboard support
% ----------------
% P:Play F:FFwd Rt:StepFwd Up:First J:Jump X:FwdBkwd
% S:Stop R:Rew Lt:StepRev Dn:Last L:Loop
%
% EXAMPLE: Playback of standard MATLAB movies.
% Run 'crulspin' or 'logospin' from the command line.
% These demos create a MATLAB movie structure in the
% workspace in variable 'm'. Run "mplay(m)" and be
% sure to turn on looping playback.
%
% See also MOVIE, INT2RGBM, INT2STRUCT, STRUCT2RGBM, IMVIEW.
% Copyright 2003 The MathWorks, Inc.
% Author: D. Orofino
% $Revision: $ $Date: $
% To do:
% ------
% - icon for export-to-imview
% - API properties: colormap
% - Interactive zoom
% Note: The following input syntax has been disabled in the
% CheckMovieFormat() function.
%
% Color video components (FMT = @user_fcn)
% Cell array containing arrays reprsenting each color plane of a movie,
% arranged in a form suitable for a pre-defined conversion function.
% In this case, FMT specifies a function (string or function handle) that
% converts from the color components to the 4-D RGB video format. The
% function is invoked as: RGBM = user_fcn(A{:}). The function must
% return a 4-D RGB movie array. If omitted, FMT defaults to @int2rgbm.
%
% Examples:
% MPLAY({R,G,B},@int2rgbm) % converts RGB components to 4-D array
% MPLAY({R,G,B},10) % uses int2rgbm by format, 10 frames/sec
% MPLAY({Y,U,V},@yuv2rgbm,24) % 24 frames/sec, YUV data format
%
% GUI Data organization
% ---------------------
% Figure UserData
% .hfig handle to figure window
% .haxis handle to axis containing image object
% .himage handle to image object
% .htoolbar handle to GUI button toolbar
% .htimer timer object associated with this player
% .hStatusBar structure of handles to parts of status bar
% .loopmode 0=no looping, 1=looping
% .fbmode 0=no fwd/bkwd playback, 1=fwd/bkwd playback
% .fbrev 1=currently in reverse-playback, only if fwd/bkwd flag true
% .paused true/false flag indicating that we're in
% pause mode --- set to false by pressing play or stop
% .nextframe next frame number to display
% .currframe current frame displayed in viewer
% .jumpto_frame frame number to jump to for frame num edit
% .fps requested frame rate (frames per second)
% .varName name of variable passed in to player
% .numFrames number of frames in movie
% .frameRows number of rows in movie image
% .frameCols number of columns in movie image
% .cmapexpr colormap expr to use during movie playback
% .cmap
% .UpdateImageFcn function pointer to image update fcn
% .Movie movie pixel data
% .MovieFormat 'S' Standard movie structure
% 'I' MxNxF
% 'RGB' MxNx3xF
%
% Timer Object UserData
% .hfig handle to corresponding figure window
try,
% dfmt: desired movie format, as specified by user
[A,dfmt,fps,msg] = parse_inputs(varargin{:});
error(msg);
% fmt: actual movie format to use, % string normalized to proper spelling, capitalization, etc
[A, fmt] = CheckMovieFormat(A, dfmt);
% Create and load GUI with movie
hfig = CreateGUI;
LoadMovie(hfig, A, fmt, inputname(1), fps);
UpdateGUIControls(hfig);
AdjustPlayerSize(hfig);
% Return object is LHS requested
if nargout>0, mov=GetMoviePlayerAPI(hfig); end
% Clean up
set(hfig,'vis','on'); % time to show the player
catch,
rethrow(lasterror);
end
% --------------------------------------------------------
function AdjustPlayerSize(hfig)
% Adjust width of player window to be no narrower than
% the extent needed to render the button and status bar
%
% Also, make sure it is no bigger than screen size
min_width = 370; % min pixel width to render toolbar
set(hfig,'units','pix');
figpos = get(hfig,'pos');
% Widen player to minimum width (if movie is very narrow)
if figpos(3) < min_width,
figpos(3) = min_width;
end
% Shrink movie to screen as needed:
set(0,'units','pix');
screenpos = get(0,'screensize');
if figpos(3) > screenpos(3),
figpos(3) = screenpos(3);
end
if figpos(4) > screenpos(4),
figpos(4) = screenpos(4);
end
set(hfig,'pos',figpos);
% --------------------------------------------------------
function mov = GetMoviePlayerAPI(hfig)
fcn.ffwd = @cb_ffwd;
fcn.goto_end = @cb_goto_end;
fcn.goto_start = @cb_goto_start;
fcn.jumpto = @cb_jumpto;
fcn.loop = @cb_loop;
fcn.fbmode = @cb_fbmode;
fcn.play = @cb_play;
fcn.rewind = @cb_rewind;
fcn.step_back = @cb_step_back;
fcn.step_fwd = @cb_step_fwd;
fcn.stop = @cb_stop;
fcn.truesize = @cb_truesize;
fcn.setfps = @ext_setFPS;
fcn.getfps = @ext_getFPS;
mov = mmovie.player(hfig,fcn);
% --------------------------------------------------------
function [A,fmt,fps,msg] = parse_inputs(varargin)
%PARSE_INPUTS Parse input arguments
% Valid calling syntax:
% MPLAY(A)
% MPLAY(A, FMT)
% MPLAY(A, FPS)
% MPLAY(A, FMT, FPS)
%
% Defaults:
A=[];
fmt=''; % no format specified
fps=30; % 30 frames per second
msg=''; % no errors
% Check number of input args
msg = nargchk(1,3,nargin);
if ~isempty(msg), return; end
A = varargin{1};
if nargin > 2,
% 3 or more inputs
fmt = varargin{2};
fps = varargin{3};
elseif nargin==2
% 2 inputs
if ischar(varargin{2}),
fmt = varargin{2};
else
% must disambiguate:
% (A,@my_func) from (A,fps)
if isnumeric(varargin{2}),
fps = varargin{2};
else
fmt = varargin{2};
end
end
end
% Check and expand FMT
% Expand the desired format string specified by user
% Make it lower case, and complete any partial string specified.
%
% NOTE: If A is a cell-array, skip this
% FMT could be a conversion function
%
if ~iscell(A),
if ~isempty(fmt),
if ~ischar(fmt),
msg = 'FMT must be a string.';
return
end
all_in={'intensity','rgb','structure'}; % user format strings
all_out={'I','RGB','S'}; % internal format strings
i=strmatch(lower(fmt), all_in);
if isempty(i),
msg='Unrecognized FMT string specified.';
return
end
fmt=all_out{i};
end
end
% Check FPS
if ~isa(fps,'double') || numel(fps)~=1 || fps<=0,
msg='FPS must be a scalar double-precision value > 0.';
return
end
% --------------------------------------------------------
function [A,fmt,msg] = CheckMovieFormat(A,dfmt)
% DetermineMovieFormat
% Rules to disambiguate inputs when no format is specified
%
% Is input a structure?
% - 'struct' assumed
% check for .colormap and .cdata present
% check for empty .colormap entries
% check for MxN or MxNx3 sizes in each frame
% - otherwise, ERROR
%
% Is input numeric?
% - if not, ERROR
%
% Is input 4-D?
% Are both the 1st and 3rd dims ~= 3 (or empty)?
% ERROR
% Are both the 1st and 3rd dims == 3?
% - assume 'rgb'
% - WARN user of ambiguity, and to pass 'rgb' format string
% to suppress warning next time
% Is the 1st dim = 3 and the 3rd dim ~= 3?
% - 'rgbp' assumed
% Is the 1st dim ~= 3 and the 3rd dim = 3?
% - 'rgb' assumed
%
% Is input 3-D?
% Is the 3rd dim = 3?
% WARN that this is being interpreted as a 3-frame intensity movie,
% and to pass 'intensity' format string to suppress warning next time
%
% Is input 2-D?
% - 'intensity' assumed, one frame
%
% Otherwise, ERROR
fmt = ''; % default
CR = sprintf('\n');
% Check for movie structure format
%
if isstruct(A),
fmt = 'S';
if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
end
% Check for required fields
if ~isfield(A, 'colormap') || ~isfield(A, 'cdata'),
error('Invalid movie: structure format does not contain required fields.');
end
% Check for empty colormap fields and movie datatypes
% - check all frames (thorough but time consuming)
% - check just the first frame (quick but incomplete)
%
i=1; % just check first frame
%for i=1:length(A), % check all entries in structure
if ~isempty(A(i).colormap),
error('All colormap fields in structure format must be empty.');
end
c=class(A(i).cdata);
switch c,
case {'uint8','double'},
otherwise,
error('Unsupported data type (%s) found in video frames.', c);
end
%end
return
end
% Check for cell-array arguments
%
% NOTE: Disabled color conversion syntax
if 0,
if iscell(A),
% Convert cell array of color components to 4-D RGB video array
% using user-defined conversion function
% Default if no conversion function specified: int2rgbm
if isempty(dfmt),
fmt = @int2rgbm;
else
fmt = dfmt;
end
% Try to invoke conversion function
A = feval(fmt, A{:});
% After the conversion, it is assumed that the video format is RGB
fmt = 'RGB';
dfmt = 'RGB';
% Fall-through to standard checking-code for N-D array
% after conversion function has completed
end
end
if ~isnumeric(A),
error('Unrecognized movie format.');
end
% Check for 3-D and 4-D RGB array formats
%
nd = ndims(A);
sz = size(A);
if nd==4, A33 = (sz(3)==3);
if ~A33,
error('Invalid movie format: 3rd dimension of array must be 3.');
end
fmt = 'RGB';
if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
end
return
elseif nd==3,
A33 = (sz(3)==3);
if A33 && isempty(dfmt),
warning(['Ambiguous movie format: 3rd dimension of 3-D array is 3.' CR ...
'Assuming ''intensity'' format. Pass format string to suppress warning.']);
end
fmt='I';
if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
end
return
else % 2-D input
fmt='I';
if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
end
return
end
% --------------------------------------------------------
function hfig = CreateGUI
% Determine renderer mode
if 0 & opengl('info'),
renderer='opengl';
else
renderer='painters';
end
% Create figure
defaultPos = [50 50 400 400];
hfig = figure(...
'NumberTitle','off', ...
'MenuBar','none', ...
'Renderer',renderer, ...
'HandleVis','callback', ...
'IntegerHandle','off', ...
'KeyPressFcn', @KeypressFcn, ...
'Visible','off', ...
'CloseRequestFcn',@DeleteFcn, ...
'DeleteFcn',@DeleteFcn, ...
'Position',defaultPos, ...
'BackingStore','off', ...
'DoubleBuffer','off');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -