package util;
//----- JDK Imports ------------------------------------------------------------
import java.util.Vector;
//----- Quicktime Imports ------------------------------------------------------
import quicktime.QTException;
import quicktime.qd.QDRect;
import quicktime.std.StdQTConstants;
import quicktime.std.StdQTException;
import quicktime.std.image.Matrix;
import quicktime.std.movies.Movie;
import quicktime.std.movies.Track;
//----- SISC Imports -----------------------------------------------------------
import sisc.data.Pair;
import sisc.interpreter.SchemeException;
/**
* Video Phoenix
* Version 0.2.0
* Copyright (c) 2007 Lunderskov, Ian; Pan, Jiabei; Rebelsky, Samuel;
* Whisenhunt, Heather; Young, Ian; Zuleta Benavides, Luis.
* All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* @author Pan, Jiabei; Rebelsky, Samuel; Whisenhunt, Heather
* @author Glimmer Labs
* @version 0.2.0
*/
public class TrackKluberizer
{
/*---------*------------------------------------------------------------------
* Methods *
*---------*/
/**
* Cut a movie in to segments of length cycle (in seconds) and store the
* segments in a vector
*
* @param mov Movie to be cut
* @param cycle Length of each segment
* @return result mov in segments of length cycle
*/
public Vector<Movie> cutMovie(Movie mov, float cycle)
throws StdQTException, SchemeException
{
float length = mov.getDuration() / mov.getTimeScale();
float now = 0;
Vector<Movie> result = new Vector<Movie>();
while ((now + cycle) <= length)
{
if (Thread.interrupted())
{
throw new SchemeException(new Pair(), null, null);
} // if (Thread.interrupted())
result.add(MovieUtils.extractSegment(mov, now, now + cycle));
now = now + cycle;
} // while ((now + cycle) <= length)
if (now != length)
{
result.add(MovieUtils.extractSegment(mov, now, length));
} // if (now != length)
return result;
} // cutMovie(Movie, float)
/**
* Squish each segment to a desired size, and compile copies of the
* squished segment to make a new segment
*
* @param movies Vector of movies to be squished
* @param direction Direction to squish: 0,2=vertical; 1,3=horizontal
* @return result Squished movies
* @throws QTException
* @throws SchemeException
*/
public Vector<Movie> squishMovies(Vector<Movie> movies, int direction)
throws QTException, SchemeException
{
Vector<Movie> result = new Vector<Movie>();
Movie mov = null;
Movie temp = null;
for (int i = 0; i < movies.size(); i++)
{
mov = movies.get(i);
temp = new Movie();
temp.setBounds(movies.get(i).getBounds());
for (int j = 0; j < (i + 1); j++)
{
if (Thread.interrupted())
{
throw new SchemeException(new Pair(), null, null);
} // if (Thread.interrupted())
Track video = mov.getIndTrackType(1, StdQTConstants.videoMediaType,
StdQTConstants.movieTrackMediaType);
Track newTrack = MovieUtils.addVideoTrack(video, temp);
Matrix mat = new Matrix();
QDRect from = mov.getBounds();
QDRect to = null;
int height = from.getHeight();
int width = from.getWidth();
int x = 0;
int y = 0;
if ((direction == 0) || (direction == 2))
{
height = Math.round(from.getHeight() * (float)1.0f/(i+1));
y = j * height;
} // if ((direction == 0) || (direction == 2))
else if ((direction == 1) || (direction == 3))
{
width = Math.round(from.getWidth() * (float)1.0f/(i+1));
x = j * width;
} // else if ((direction == 1) || (direction == 3))
to = new QDRect(x, y, width, height);
mat.rect(from, to);
newTrack.setMatrix(mat);
newTrack.setLayer(-1);
} // for
result.add(temp);
} // for
return result;
} // squishMovies(Vector<Movie>, int)
/**
* Join multiple movies into one
*
* @param movies Vector of movies to be processed
* @param cycle Length in seconds of each segment
* @return result Items in movies inserted into new movie
* @throws QTException
* @throws SchemeException
*/
public Movie glueMovies(Vector<Movie> movies, float cycle)
throws QTException, SchemeException
{
Movie mov = new Movie();
for (int i = 0; i < movies.size(); i++)
{
if (Thread.interrupted())
{
throw new SchemeException(new Pair(), null, null);
} // if (Thread.interrupted())
mov = MovieUtils.insertSegment(movies.get(i), mov, (i * cycle));
} // for
return mov;
} // glueMovies(Vector<Movie>, float)
/**
* Track-kluberize a movie
*
* @param mov Movie to be processed
* @param direction Direction to Kluberize: 0,2=vertical; 1,3=horizontal
* @param cycle Length of each Kluberization segment
* @return result Track-kluberized movie
* @throws SchemeException
*/
public Movie trackKluberizeMovie(Movie mov, int direction, float cycle)
throws SchemeException
{
try
{
Movie video = glueMovies(squishMovies(cutMovie(mov, cycle), direction),
cycle);
Track sound = mov.getIndTrackType(1,
StdQTConstants.audioMediaCharacteristic,
StdQTConstants.movieTrackCharacteristic);
MovieUtils.addAudioTrack(sound, video);
return video;
} // try
catch (StdQTException stdqte)
{
stdqte.printStackTrace();
} // catch (StdQTException)
catch (QTException qte)
{
qte.printStackTrace();
} // catch (QTException)
return mov;
} // trackKluberizeMovie(Movie, int, float)
} // class TrackKluberizer