• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Merge 2 QTTracks in a QTMovie
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Merge 2 QTTracks in a QTMovie


  • Subject: Re: Merge 2 QTTracks in a QTMovie
  • From: Alex Bumbu <email@hidden>
  • Date: Fri, 22 May 2009 15:08:03 +0300

Below is the code I'm using in this test application. I'm loading 2 mp4 movies (h.264 AAC) in the first action, getting an array of merged frames from the 2 movies and add them to the mixed video (method 3), get the sound qttracks from the 2 movies, change the layer number of the second and add them to the mix movie. Please if you have any idea on how I can make this work tell me. Thank you!

//loading the 2 movies
- (IBAction)btnPressed:(id)sender
{
NSError *aError = nil;
OSStatus theError = noErr;
Boolean active = TRUE;
Movie channelMovie1, channelMovie2;
NSString *video1Path = [NSString stringWithFormat: @"%@%@", NSHomeDirectory(), @"/Desktop/mv/video1.mp4"];
NSString *video2Path = [NSString stringWithFormat: @"%@%@", NSHomeDirectory(), @"/Desktop/mv/video2.mp4"];
QTNewMoviePropertyElement newMovieProperties[] = { {kQTPropertyClass_DataLocation, kQTDataLocationPropertyID_CFStringNativePath, sizeof(video1Path), &video1Path, 0},
{kQTPropertyClass_NewMovieProperty, kQTNewMoviePropertyID_Active, sizeof(active), &active, 0} };


theError = NewMovieFromProperties(sizeof(newMovieProperties) / sizeof(newMovieProperties[0]), newMovieProperties, 0, nil, &channelMovie1);
if(theError) {
NSLog(@"NewMovie1FromProperties failed with %d", theError);
[self dealloc];
return nil;
}
else {
movie1 = [QTMovie movieWithQuickTimeMovie: channelMovie1 disposeWhenDone: NO error: aError];
[movie1 setAttribute: [NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
if (aError == nil)
[movieView1 setMovie: movie1];
else
NSLog(@"Error 1: %@", [aError localizedDescription]);
}


QTNewMoviePropertyElement newMovieProperties2[] = { {kQTPropertyClass_DataLocation, kQTDataLocationPropertyID_CFStringNativePath, sizeof(video2Path), &video2Path, 0},
{kQTPropertyClass_NewMovieProperty, kQTNewMoviePropertyID_Active, sizeof(active), &active, 0} };
theError = NewMovieFromProperties(sizeof(newMovieProperties2) / sizeof(newMovieProperties2[0]), newMovieProperties2, 0, nil, &channelMovie2);
if(theError) {
NSLog(@"NewMovie2FromProperties failed with %d", theError);
[self dealloc];
return nil;
}
else {
movie2 = [QTMovie movieWithQuickTimeMovie: channelMovie2 disposeWhenDone: NO error: aError];
if (aError == nil)
[movieView2 setMovie: movie2];
else
NSLog(@"Error 2: %@", [aError localizedDescription]);
} }


//creating the mixed video
- (IBAction)mixBtnPressed:(id)sender
{ frames = [[NSMutableArray alloc] init];
frame = 0;
for (float i = 0; i < 70; i+=0.5) {
NSImage *mixedFrame = [movie1 frameImageAtTime: QTMakeTimeWithTimeInterval(i)];
NSImage *image2 = [movie2 frameImageAtTime: QTMakeTimeWithTimeInterval(i)];
[image2 setSize: NSMakeSize(200, 100)];
[mixedFrame lockFocus];
[image2 compositeToPoint: NSMakePoint(100, 150)
operation: NSCompositeSourceOver];
[mixedFrame unlockFocus];


[frames addObject: mixedFrame];
}
QTMovie *mMovie;
DataHandler mDataHandlerRef;
// Check first if the new QuickTime 7.2.1 initToWritableFile: method is available
if ([[[[QTMovie alloc] init] autorelease] respondsToSelector: @selector(initToWritableFile:error:)] == YES)
{
// generate a name for our movie file
NSString *tempName = [NSString stringWithCString: tmpnam(nil)
encoding: [NSString defaultCStringEncoding]];
if (nil == tempName) goto bail;
// Create a QTMovie with a writable data reference
mMovie = [[QTMovie alloc] initToWritableFile:tempName error:NULL];
}
else { // The QuickTime 7.2.1 initToWritableFile: method is not available, so use the native
// QuickTime API CreateMovieStorage() to create a QuickTime movie with a writable
// data reference
OSErr err;
// create a native QuickTime movie
Movie qtMovie = [self quicktimeMovieFromTempFile: &mDataHandlerRef error: &err];
if (nil == qtMovie) goto bail;
// instantiate a QTMovie from our native QuickTime movie
mMovie = [QTMovie movieWithQuickTimeMovie: qtMovie disposeWhenDone: YES error: nil];
if (!mMovie || err) goto bail;
}
// mark the movie as editable
[mMovie setAttribute: [NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
// keep it around until we are done with it...
[mMovie retain];


// add all the images to our movie as MPEG-4 frames
[mMovie addImagesAsMPEG4: frames];
//add sounds NSArray *audioTracks1 = [movie1 tracksOfMediaType: QTMediaTypeSound];
NSArray *audioTracks2 = [movie2 tracksOfMediaType: QTMediaTypeSound];
QTTrack *audioTrack1 = nil;
QTTrack *audioTrack2 = nil;
if( [audioTracks1 count] > 0 )
{
audioTrack1 = [audioTracks1 objectAtIndex:0];
}
if( [audioTracks2 count] > 0 )
{
audioTrack2 = [audioTracks2 objectAtIndex:0];
}
if( audioTrack1 && audioTrack2 )
{
QTTimeRange totalRange;
totalRange.time = QTZeroTime;
totalRange.duration = [[movie1 attributeForKey: QTMovieDurationAttribute] QTTimeValue];
[audioTrack2 setAttribute: [NSNumber numberWithShort: 1000] forKey: QTTrackLayerAttribute];


//[mMovie insertSegmentOfTrack: audioTrack1 timeRange: totalRange atTime: QTZeroTime];
//[mMovie insertSegmentOfTrack: audioTrack2 timeRange: totalRange atTime: QTZeroTime];
[mMovie insertSegmentOfTrack: audioTrack1
fromRange: QTMakeTimeRange(QTZeroTime, [movie1 duration])
scaledToRange: QTMakeTimeRange(QTZeroTime, [movie1 duration])];
[mMovie insertSegmentOfTrack: audioTrack2
fromRange: QTMakeTimeRange(QTZeroTime, [movie1 duration])
scaledToRange: QTMakeTimeRange(QTZeroTime, [movie1 duration])]; } //[mMovie setAttribute: [NSNumber numberWithBool: YES] forKey: @"QTMovieHasAudioAttribute"];
//[mMovie setAttribute: [NSNumber numberWithBool: YES] forKey: @"QTMoviePlaysAllFramesAttribute"];
//[mMovie setAttribute: [NSNumber numberWithBool: YES] forKey: @"QTMovieIsInteractiveAttribute"];
[movieView3 setMovie: mMovie];
bail:
return;
}


//add images from array to our movie
- (void)addImagesAsMPEG4:(NSArray *)imageFilesArray
{
if (!imageFilesArray)
goto bail;
// when adding images we must provide a dictionary
// specifying the codec attributes
NSDictionary *myDict = nil;
myDict = [NSDictionary dictionaryWithObjectsAndKeys:@"mp4v",
QTAddImageCodecType,
[NSNumber numberWithLong:codecHighQuality],
QTAddImageCodecQuality,
nil];
if (!myDict)
goto bail;


   // create a QTTime value to be used as a duration when adding
   // the image to the movie
   long long timeValue = 30;
   long timeScale      = 600;
   QTTime duration     = QTMakeTime(timeValue, timeScale);

// iterate over all the images in the array and add
// them to our movie one-by-one
int i;
for (i = 0; i < [imageFilesArray count]; ++i)
{
//NSURL *fileUrl = [NSURL fileURLWithPath:[imageFilesArray objectAtIndex:i]]; //NSImage *anImage = [[NSImage alloc] initWithContentsOfURL:fileUrl]; NSImage *anImage = [imageFilesArray objectAtIndex: i];
if (anImage)
{
// Adds an image for the specified duration to the QTMovie
[self addImage:anImage
forDuration:duration
withAttributes:myDict];
// free up our image object
[anImage release];
}
}


bail:
   return;
}

douglas welton wrote:
Yes. It'd possible. How are you creating your tracks? Can you show us a little code to see what you've tried already?

On May 21, 2009, at 8:44 AM, Alex Bumbu wrote:

Hi all,

I'm trying to add 2 sounds tracks in a QTMovie so they play at the same time. I've tried adding both sound tracks with the layer property changed to the qtmovie but the tracks are played one after another. Is this possible? And if is possible any help is really appreciated.

Thanks in advance,
Alex


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Merge 2 QTTracks in a QTMovie (From: Alex Bumbu <email@hidden>)
 >Re: Merge 2 QTTracks in a QTMovie (From: douglas welton <email@hidden>)

  • Prev by Date: [iPhone] Any way to animate a tab-bar away?
  • Next by Date: Re: [iPhone] Any way to animate a tab-bar away?
  • Previous by thread: Re: Merge 2 QTTracks in a QTMovie
  • Next by thread: Deallocating cocoa distant objects.
  • Index(es):
    • Date
    • Thread