function PlayDualMoviesTutorial(moviename) % % PlayDualMoviesTutorial(moviename) % % This demo accepts a pattern for a valid moviename, e.g., % moviename='*.mpg', then it plays all movies in the current working % directory whose names match the provided pattern, e.g., the '*.mpg' % pattern would play all MPEG files in the current directory. % % This demo uses automatic asynchronous playback for synchronized playback % of video and sound. Each movie plays until end, then rewinds and plays % again from the start. Pressing the Cursor-Up/Down key pauses/unpauses the % movie and increases/decreases playback rate. % The left- right arrow keys jump in 1 seconds steps. SPACE jumps to the % next movie in the list. ESC ends the demo. % % History: % 10/30/05 mk Wrote it. % 06/17/13 mk Cleaned up. if nargin < 1 moviename = '*.mov'; end % Switch KbName into unified mode: It will use the names of the OS-X % platform on all platforms in order to make this script portable: KbName('UnifyKeyNames'); space=KbName('SPACE'); esc=KbName('ESCAPE'); right=KbName('RightArrow'); left=KbName('LeftArrow'); up=KbName('UpArrow'); down=KbName('DownArrow'); try % Child protection AssertOpenGL; % Open onscreen window: screen=max(Screen('Screens')); [win, scr_rect] = Screen('OpenWindow', screen, 0, [], [], [], 0, [], kPsychNeedFastBackingStore); Screen('BlendFunction', win, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); % We create a Luminance+Alpha matrix for use as transparency mask: % Layer 1 (Luminance) is filled with 'backgroundcolor'. transLayer=2; ms=200; [x,y]=meshgrid(-ms:ms, -ms:ms); maskblob=ones(2*ms+1, 2*ms+1, transLayer) * 255; % Layer 2 (Transparency aka Alpha) is filled with gaussian transparency % mask. xsd=ms/2.2; ysd=ms/2.2; maskblob(:,:,transLayer)=round(255 - exp(-((x/xsd).^2)-((y/ysd).^2))*255); % Build a single transparency mask texture: masktex=Screen('MakeTexture', win, maskblob); % Initial display and sync to timestamp: Screen('Flip',win); iteration=2; abortit=0; % Return full list of movie files from directory+pattern: moviefiles=dir(moviename); for i=1:size(moviefiles,1) moviefiles(i).name = [ pwd filesep moviefiles(i).name ]; end % Endless loop, runs until ESC key pressed: while (abortit<2) iteration=iteration + 1; moviename=moviefiles(mod(iteration, size(moviefiles,1))+1).name; moviename2=moviefiles(mod(iteration+1, size(moviefiles,1))+1).name; % Open movie file and retrieve basic info about movie: [movie movieduration fps imgw imgh] = Screen('OpenMovie', win, moviename); fprintf('Movie1: %s : %f seconds duration, %f fps...\n', moviename, movieduration, fps); rect1=SetRect(1,1,imgw,imgh); % Open 2nd movie file and retrieve basic info about movie: [movie2 movieduration fps imgw imgh] = Screen('OpenMovie', win, moviename2); fprintf('Movie2: %s : %f seconds duration, %f fps...\n', moviename2, movieduration, fps); rect2=SetRect(1,1,imgw,imgh); rect2=AdjoinRect(rect2, rect1, RectRight); [xc yc] = RectCenter(rect2); SetMouse(xc, yc, win); i=0; % Seek to start of movies (timeindex 0): Screen('SetMovieTimeIndex', movie, 0); Screen('SetMovieTimeIndex', movie2, 0); rate=1; % Start playback of movies. This will start % the realtime playback clock and playback of audio tracks, if any. % Play 'movie', at a playbackrate = 1, with endless loop=1 and % 1.0 == 100% audio volume. Screen('PlayMovie', movie, rate, 1, 1.0); Screen('PlayMovie', movie2, rate, 1, 1.0); angle=0; alpha=1; % Infinite playback loop: Fetch video frames and display them... while 1 i=i+1; if (abs(rate)>0) % Return next frame in movie, in sync with current playback % time and sound. % tex either the texture handle or zero if no new frame is % ready yet. tex = Screen('GetMovieImage', win, movie, 1); tex2 = Screen('GetMovieImage', win, movie2, 1); % Valid texture returned? if tex>0 % Draw the new texture immediately to screen: Screen('SelectStereoDrawBuffer', win, 0); Screen('DrawTexture', win, tex, [], rect1); % Release texture: Screen('Close', tex); end; % Valid 2nd texture returned? if tex2>0 % Draw the new texture immediately to screen: Screen('SelectStereoDrawBuffer', win, 1); Screen('DrawTexture', win, tex2, [], rect2, angle, [], alpha); % Release texture: Screen('Close', tex2); end; % Update display if there is anything to update: if (tex>0 || tex2>0) % We use clearmode=1, aka don't clear on flip. This is % needed to avoid flicker... Screen('Flip', win, 0, 0); end; end; % Check for abortion: abortit=0; [keyIsDown,secs,keyCode]=KbCheck; %#ok if (keyIsDown==1 && keyCode(esc)) break; end; if (keyIsDown==1 && keyCode(space)) % Exit while-loop: This will load the next movie... KbReleaseWait; break; end; if (keyIsDown==1 && keyCode(right)) angle = angle + 1; end; if (keyIsDown==1 && keyCode(left)) angle = angle - 1; end; if (keyIsDown==1 && keyCode(up)) alpha = alpha + 0.01; if alpha > 1 alpha = 1; end end; if (keyIsDown==1 && keyCode(down)) alpha = alpha - 0.01; if alpha < 0 alpha = 0; end end; [x y] = GetMouse(win); rect2 = CenterRectOnPoint(rect2, x, y); end; rect2 = rect1; % Infinite playback loop: Fetch video frames and display them... while 1 i=i+1; if (abs(rate)>0) % Return next frame in movie, in sync with current playback % time and sound. % tex either the texture handle or zero if no new frame is % ready yet. tex = Screen('GetMovieImage', win, movie, 1); tex2 = Screen('GetMovieImage', win, movie2, 1); Screen('BlendFunction', win, GL_ONE, GL_ZERO); Screen('DrawTexture', win, masktex, [], rect2); % Valid texture returned? if tex>0 % Draw the new texture immediately to screen: Screen('BlendFunction', win, GL_DST_ALPHA, GL_ZERO); Screen('DrawTexture', win, tex, [], rect1); % Release texture: Screen('Close', tex); end; % Valid 2nd texture returned? if tex2>0 % Overdraw the first tex with 2nd tex: Screen('BlendFunction', win, GL_ONE_MINUS_DST_ALPHA, GL_ONE); Screen('DrawTexture', win, tex2, rect2, rect2); % Release texture: Screen('Close', tex2); end; % Update display if there is anything to update: if (tex>0 || tex2>0) % We use clearmode=1, aka don't clear on flip. This is % needed to avoid flicker... Screen('Flip', win, 0, 0); end; end; % Check for abortion: abortit=0; [keyIsDown,secs,keyCode]=KbCheck; %#ok if (keyIsDown==1 && keyCode(esc)) % Set the abort-demo flag. abortit=2; break; end; if (keyIsDown==1 && keyCode(space)) % Exit while-loop: This will load the next movie... break; end; if (keyIsDown==1 && keyCode(right)) angle = angle + 1; end; if (keyIsDown==1 && keyCode(left)) angle = angle - 1; end; if (keyIsDown==1 && keyCode(up)) alpha = alpha + 0.01; if alpha > 1 alpha = 1; end end; if (keyIsDown==1 && keyCode(down)) alpha = alpha - 0.01; if alpha < 0 alpha = 0; end end; [x y] = GetMouse(win); rect2 = ClipRect(CenterRectOnPoint([0 0 401 401], x, y), scr_rect); end; Screen('Flip', win); Screen('Flip', win); KbReleaseWait; % Done. Stop playback: Screen('PlayMovie', movie, 0); Screen('PlayMovie', movie2, 0); % Close movie objects: Screen('CloseMovie', movie); Screen('CloseMovie', movie2); end; % Close screens. sca; % Done. return; catch %#ok % Error handling: Close all windows and movies, release all ressources. sca; end;