Skip to content

Instantly share code, notes, and snippets.

@atr000
Created August 19, 2010 12:32
Show Gist options
  • Save atr000/537762 to your computer and use it in GitHub Desktop.
Save atr000/537762 to your computer and use it in GitHub Desktop.
catMovies.c
// Contact: [email protected]
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define ec(ERR, STR) if((ERR) != noErr) fprintf(stderr, "## %s() error:%d\n", (STR), (ERR))
Movie movieFromPath(const char* outPath)
{
Movie movie = NULL;
Handle dataRef = NULL;
OSType dataType;
OSErr err;
char *path = (char *)malloc(1024);
if(index(outPath, '/') == NULL){
getcwd(path, 1024);
strcat(path, "/");
strcat(path, outPath);
}
else strcpy(path, outPath);
err = QTNewDataReferenceFromFullPathCFString(CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8),
kQTNativeDefaultPathStyle, 0, &dataRef, &dataType);
ec(err, "QTNewDataReferenceFromFullPathCFString");
free(path);
if (NULL != dataRef) {
err = NewMovieFromDataRef( &movie, 0, NULL, dataRef, dataType );
ec(err, "NewMovieFromDataRef");
DisposeHandle(dataRef);
}
return movie;
}
void writeMovieToPath(Movie movie, const char *outPath)
{
Handle dataRef = NULL;
OSType dataType;
DataHandler dataHandler;
OSErr err;
char *path = (char *)malloc(1024);
if(index(outPath, '/') == NULL){
getcwd(path, 1024);
strcat(path, "/");
strcat(path, outPath);
}
else strcpy(path, outPath);
err = QTNewDataReferenceFromFullPathCFString(CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8),
kQTNativeDefaultPathStyle, 0, &dataRef, &dataType);
ec(err, "QTNewDataReferenceFromFullPathCFString");
free(path);
err = CreateMovieStorage(dataRef, dataType, 'TVOD', smCurrentScript,
createMovieFileDeleteCurFile, &dataHandler, NULL);
ec(err, "CreateMovieStorage");
err = AddMovieToStorage(movie, dataHandler);
ec(err, "AddMovieToStorage");
CloseComponent(dataHandler);
DisposeHandle(dataRef);
}
Movie createNewMovieFileFromPath(const char* outPath, DataHandler *dataHandler)
{
OSErr err;
Movie movie;
Handle dataRef;
OSType dataType;
char *path = (char *)malloc(1024);
if(index(outPath, '/') == NULL){
getcwd(path, 1024);
strcat(path, "/");
strcat(path, outPath);
}
else strcpy(path, outPath);
err = QTNewDataReferenceFromFullPathCFString(CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8),
kQTNativeDefaultPathStyle, 0, &dataRef, &dataType);
ec(err, "QTNewDataReferenceFromFullPathCFString");
free(path);
err = CreateMovieStorage(dataRef, dataType, 'TVOD', smSystemScript, newMovieActive, dataHandler, &movie);
ec(err, "CreateMovieStorage");
return(movie);
}
// select one
#define HIGHLEVEL
//#define HIGHLEVEL2
//#define MULTITRACK
#include <unistd.h>
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;
static Boolean selfContaining = false;
void usage(char *path)
{
fprintf(stderr, "Usage: %s [-s] dstFile srcFile1 [...srcFileN]\n", path);
fprintf(stderr, "\t-s: self containing movie (default is reference movie).\n");
exit(1);
}
int main (int argc, char * const argv[]) {
int i;
OSErr err;
int ch;
while ((ch = getopt(argc, argv, "s")) != -1) {
switch (ch) {
case 's':
selfContaining = true;
break;
case '?':
usage(argv[0]);
break;
default:
;
}
}
argc -= optind;
argv += optind;
if(argc < 3){
usage(argv[0]);
}
if(fopen(argv[1], "r") != NULL){
fprintf(stderr, "File already exist:%s\n", argv[1]);
exit(1);
}
EnterMovies();
DataHandler dataHandler;
Movie dstMovie = createNewMovieFileFromPath(argv[1], &dataHandler);
TimeValue totalTime = 0;
for(i = 2; i < argc; i++){
Movie srcMovie = movieFromPath(argv[i]);
if(srcMovie != NULL){
TimeRecord srcTime = {{0, GetMovieDuration(srcMovie)}, GetMovieTimeScale(srcMovie), GetMovieTimeBase(srcMovie)};
if(i == 2)
SetMovieTimeScale(dstMovie, srcTime.scale);
else
ConvertTimeScale(&srcTime, GetMovieTimeScale(dstMovie));
fprintf(stderr, "Adding file:%d - %s\n", (int)srcTime.value.lo, argv[i]);
#ifdef HIGHLEVEL
SetMovieSelection(dstMovie, GetMovieDuration(dstMovie), 0); // select last
SetMovieSelection(srcMovie, 0, GetMovieDuration(srcMovie)); // select all
PasteMovieSelection(dstMovie, srcMovie);
#endif
#ifdef HIGHLEVEL2
err = CopyMovieSettings(srcMovie, dstMovie);
ec(err, "CopyMovieSettings");
err = InsertMovieSegment(srcMovie, dstMovie, 0, srcTime.value.lo, totalTime);
ec(err, "InsertMovieSegment");
#endif
#ifdef MULTITRACK
Track srcTrack = GetMovieIndTrackType(srcMovie, 1, MPEGMediaType, movieTrackMediaType);
if(srcTrack == NULL) fprintf(stderr, "## GetMovieIndTrackType() fail:%s\n", argv[i]);
Fixed width, height;
GetTrackDimensions(srcTrack, &width, &height);
Track dstTrack = NewMovieTrack(dstMovie, width, height, kFullVolume);
if(dstTrack == NULL) fprintf(stderr, "## NewMovieTrack(dst) fail\n");
Media dstMedia = NewTrackMedia(dstTrack, MPEGMediaType, srcTime.scale, nil, 0);
if(selfContaing){
err = BeginMediaEdits(dstMedia);
ec(err, "BeginMediaEdit");
}
err = InsertTrackSegment(srcTrack, dstTrack, 0, srcTime.value.lo, totalTime);
ec(err, "InsertTrackSegment");
if(selfContaing){
err = EndMediaEdits(dstMedia);
ec(err, "EndMediaEdit");
}
err = CopyTrackSettings(srcTrack, dstTrack);
ec(err, "CopyTrackSetting");
#endif
err = UpdateMovieInStorage(dstMovie, dataHandler);
ec(err, "UpdateMovieInStorage");
totalTime += srcTime.value.lo;
DisposeMovie(srcMovie);
}
else fprintf(stderr, "Can't open file:%s\n", argv[i]);
}
SetMovieSelection(dstMovie, 0, 0); // de-select
fprintf(stderr, "Saving file:%s\n", argv[1]);
//writeMovieToPath(dstMovie, argv[1]);
//DisposeMovie(dstMovie);
err = CloseMovieStorage(dataHandler);
ec(err, "CloseMovieStorage");
ExitMovies();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment