Cocoa - Add Video Watermark General Info - iphone

Just looking for how to programmatically add a watermark or some sort of overlay to video using cocoa. Not looking for a step by step ( although that would awesome ), but more or less looking for where I should start looking to learn how. Are there frameworks developed to work for this. Would like something native to cocoa or objective-c or c because I would like to eventually give this a go on the iPhone. Any help would be great.

I'm not sure if you mean just for playback, or if you'd like to export a video with a watermark that'll show up on other players.
If you mean just for playback, you can probably just add a view on top of the player view on Mac and iPhone that contains the watermark.
If you'd like a watermark on the video itself, this is hard on the Mac and probably impossible on the iPhone without essentially rewriting QuickTime.
On the Mac, the code might look like this (you need to import QTKit):
// Make a new movie so we don't destroy the existing one
QTMovie* movie = [[QTMovie alloc] initWithMovie:currentMovie
timeRange:QTMakeTimeRange(QTMakeTime(0,1000), [currentMovie duration])
error:nil];
// Make it editable
[movie setAttribute:[NSNumber numberWithBool:YES]
forKey:QTMovieEditableAttribute];
//Get the size
NSValue *value = [movie attributeForKey:QTMovieNaturalSizeAttribute];
NSSize size = [value sizeValue];
// Add a new track to the movie and make it the frontmost layer
QTTrack *track = [movie addVideoTrackWithSize:size];
[track setAttribute:[NSNumber numberWithShort:-1] forKey:QTTrackLayerAttribute];
// Create a codec dictionary for the image we're about to add
NSDictionary *imageDict = [NSDictionary dictionaryWithObjectsAndKeys:
#"tiff", QTAddImageCodecType,
[NSNumber numberWithLong:codecHighQuality], QTAddImageCodecQuality, nil];
// Get the video length in QT speak
QTTime qttime = [currentMovie duration];
NSTimeInterval reftime;
QTGetTimeInterval(qttime, &reftime);
//Add the image for the entire duration of the video
[track addImage:image forDuration:qttime withAttributes:imageDict];
// Finally, tell the track that it should use its alpha correctly
MediaHandler media = GetMediaHandler([[track media] quickTimeMedia]);
MediaSetGraphicsMode(media, graphicsModeStraightAlpha, NULL);
... And that's it! Your movie now has a watermark, and you can export it to file.

Related

Multiple time allocation of GPUImageFilter crashes the application

I am working a picture/video filter effect project. For making effect i am using GPUImage project. It works fine for pictures. Now i need to do the same effect on videos too. I grab images from video at 30 frames per second. Now for 1 min video i filtered about 1800 images. and filtering, for each image i allocate GPUImagePicture and GPUImageSepiaFilter classes, and release them manully. But these allocations is not released, and after processing on about 20 sec video application crashes due to memory warning.
Is it possible to allocate GPUImagePicture and Filter class once for makeing filter on all images. if yes, How?
Please tell me it will very helpfull.
Here is my code what actully i am doing...
The get image method is called by a NSTimer which is called 30 times per second, and getting image from app document directory and send for filtering to - (void)imageWithEffect:(UIImage *)image method.
-(void)getImage
{
float currentPlayBacktime = slider.value;
int frames = currentPlayBacktime*30;
NSString *str = [NSString stringWithFormat:#"image%i.jpg",frames+1];
NSString *fileName = [self.imgFolderPath stringByAppendingString:str];
if ([fileManager fileExistsAtPath:fileName])
[self imageWithEffect:[UIImage imageWithContentsOfFile:fileName]];
}
- (void)imageWithEffect:(UIImage *)image
{
GPUImagePicture *gpuPicture = [[GPUImagePicture alloc]initWithImage:img] ;
GPUImageSepiaFilter *filter = [[[GPUImageSepiaFilter alloc]init] autorelease];
gpuPicture = [gpuPicture initWithImage:image];
[gpuPicture addTarget:filter];
[gpuPicture processImage];
playerImgView.image = [filter imageFromCurrentlyProcessedOutputWithOrientation:0];
[gpuPicture removeAllTargets];
[filter release];
[gpuPicture release];
}
Why are you processing a movie as a series of still UIImages? Why are you allocating a new filter for each image? That's going to be incredibly slow.
Instead, if you need to process a movie file, use a GPUImageMovie input, and if you need access to the camera, use a GPUImageVideoCamera input. Both of these are tuned to provide fast video feeds through the filter pipeline. There's a lot of wasted processing cycles in converting still frames to and from UIImages.
Also, only set up a filter once, and reuse it as necessary. There's significant overhead in the creation of a GPUImageFilter (setting up an FBO, etc.), so you only want to create it once and then attach inputs and outputs as they change.

How to change sprite image with array of images cocos2d?

I am learning Cocos2d and building an application where i have sprite at one end and I need to through it on the other side and with the same I am removing the sprite from the screen and after some time, I am displaying the same.
Now I have a folder of images in my application and I need to load different images each time in random order from the same folder and maintain a log that these images do not repeat again and again. I am able to load images from the folder with :
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundleRoot error:nil];
NSArray *onlyJPGs = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self ENDSWITH '.jpg'"]];
Now how would I call this array and display different images each time and also maintain a log that images don't get repeat. I have already went through links like this and this but in vail. Any clue will be really very helpful. Thank you for the help in advance.
The best way to do this is by creating a spriteSheet. first of all you can get http://zwoptexapp.com/ , its free and you can create your spritesheet for using with cocos (on the exporter make sure you select cocos2d to create the proper plist)
You want to pack all your image in 1 big texture so you can add it to your project with the plist (zwoptex will create both for you)
then you can load your texture with
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"your_plist"];
switching textures is slow operation, so having all the images in the same texture will boost the openGL performance, after you've done that changing the texture for a sprite is very easy
[yourSprite setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"FRAME_NAME"]];
where FRAME_NAME is the name of the frame in the plist (you can see it by selecting the plist inside xcode.
to cycle in a random way without repeating images...
(i'll write some pseudocode directly in here, let me do inits inside class declaration and inline implementations :) )
//WARNING THIS IS PSEUDO CODE :)
#interface Randomizer {
//an array of NSStrings containing all you images names
NSMutableArray *allImagesFrameNames = [NSMutableArray arrayWithCapacity:NUM_FRAMES];
CCSprite *sprite = alloc init
}
-(void) resetAllFrames {
[allImagesFrameNames removeAllobjects];
[allImagesFrameName addObject:#"FIRST_IMAGE"];
[allImagesFrameName addObject:#"SECOND_IMAGE"]; //add all your images
}
#end
And to display a random frame:
-(void) display a randomImage {
//if the array is empty, all images are already been randomly displayed, so we reset the array
if([allImagesFrameName count] == 0)
[self resetAllFrames];
//we choose a random index
int randomIndex = arc4random %[allImagesFrameName count];
//we get the frame name at that index
NSString *imageFrameName = [allImagesFrameNames objectAtIndex:randomIndex];
//and we display the frame
[sprite setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:imageFrameName]];
[allImagesFrameNames removeObjectAtIndex:randomIndex];
}

Using AVQueuePlayer to get current track information

I am loading my iPod library into AVQueuePlayer and playing it using this:
[[AVQueuePlayer alloc]]initWithItems:[MPMediaCollectionInstance items] ]; //just one line.
But how do I read which MPMediaItem is currently playing? I want to know information like artist / song name etc.
Thanks.
Have the instance of the AVQueuePlayer that you have allocated.
AVQueuePlayer *_queuePlayer = [[AVQueuePlayer alloc] initWithItems:[MPMediaCollectionInstance items]];
With that instance, you can get the AVPlayerItem.
AVPlayerItem *currentItem = _queuePlayer.currentItem;
For the above line, please check the doc reference.
And now try the following code
NSArray *metadataList = [currentItem.asset commonMetadata];
for (AVMetadataItem *metaItem in metadataList) {
NSLog(#"%#",[metaItem commonKey]);
}
Which will give a list as follows:
title
creationDate
artwork
albumName
artist
Now you can get the value for corresponding keys. For this, you have to refer this doc too.

Programmatically determine dimensions of image files in bundle

I have a large number of image files in my iPhone app bundle (~3000) and I want to determine the dimensions at runtime rather than store this data in the database or an xml manifest for the images.
Is there a way to do this programmatically?
UIImage has the size property that returns the dimensions of the image, however I wouldn't recommend loading all 3000 of your images in your iPhone app. Pre-generating that information at build time would give you much better results. Failing that you might possibly use some sort of naming convention for your images that encodes the image size in the file name, however this is really not that different to storing the information in some sort of database or XML file ;)
The file Unix utility uses the header information on the file to determine the size. It basically requires loading in the first block of the file and sifting through the information (varies by file type but presumably you'll only have one to implement since you control the images).
As of iOS 4, it is possible to access image properties without actually loading image in memory.
You'll need ImageIO.framework and #import < ImageIO/ImageIO.h>
NSURL *imageFileURL = [NSURL fileURLWithPath:imagePath];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
if (imageSource == NULL)
{
// Error loading image ...
}
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], (NSString *)kCGImageSourceShouldCache, nil];
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options);
NSNumber *mImageWidth;
NSNumber *mImageHeight;
if (imageProperties)
{
mImageWidth = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
mImageHeight = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
CFRelease(imageProperties);
}

Playing from iPod music library

I want to play particular selected song from my ipod music library.How can i do that?
My idea is to save the title name from MPMediaQuery and then play later on when app starts
so any one can have idea to do this?
Thank You.
The basic solution is to save the unique identifier each song in the library has, aka MPMediaItemPropertyPersistentID. You can use this ID to play the song, and you can save the ID to memory in order to remember the song the user selected between launches. If you don't know how the Media Player Framework works, look at the AddMusic sample code.
Your view controller must implement the MPMediaPickerControllerDelegate protocol. Assuming you're just allowing the user to select a single song, then the basic outline of your callback will look something like this.
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
NSArray* items = [mediaItemCollection items];
if ([items count] == 1)
{
MPMediaItem* song = (MPMediaItem *)[items objectAtIndex:0];
NSNumber* persistentId = [song valueForProperty:MPMediaItemPropertyPersistentID];
// ...Save/Play here...
}
}
At this point you can use the persistent ID to play the song, and/or save it to user defaults.