Playing from iPod music library - iphone

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.

Related

How to update the whole UI according to the configuration the user selects

I have a configfile1.plist file in my app bundle that includes all the required settings for the UI of the app, i.e. the background images, the animations, the sounds, database, and anything else. I have used a ConfigFileManager class in which there's this method as follows:
-(void) loadConfigFile
{
configFile = [[NSBundle mainBundle] pathForResource:#"ConfigFile1"
ofType:#"plist"];
rootDictionary = [[NSDictionary alloc]initWithContentsOfFile:configFile];
//__ settings
settings = [rootDictionary objectForKey:#"settings"];
timerMode = [settings objectForKey:#"timerMode"];
timePerQuestion = [settings objectForKey:#"timePerQuestion"];
if (timerMode.intValue == 1) {
//__time is fixed.
}
else
{
//time is not fixed, there's an initialTime to begin with, and it increases if the answer is correct (timePerQuestion), and doesn't change if it's wrong.
initialTime = [settings objectForKey:#"initialTime"];
}
//__ Textures
textures = [rootDictionary objectForKey:#"textures"];
//__ buttons
buttons = [textures objectForKey:#"buttons"];
buttonBackground = [buttons objectForKey:#"buttonBG"];
buttonBackgroundSelected = [buttons objectForKey:#"buttonBGSelected"];
mainMenuPlayButton = [buttons objectForKey:#"mainMenu.playButton"];
.
.
.
}
This is the default configuration for the app for which the method is called in the app delegate while the app is being opened. Now let's say I have configfile2.plist, configfile3.plist, and so on. I have a UIViewController for this, too, that must display the available config files in a table view. What should I do this, so that the user can select one of the config files, and that gets applied to the whole app?
Any detailed response will be appreciated.
Thanks in advance!
The general idea is like this:
a .plist stores possible options
shows the options to user
save the selected options to somewhere
refresh UI based on saved options
You have done step 1 and 2. So you have to decide where to store the options for later retrieval.
One option is to use [NSUserDefaults standardUserDefaults] to save selected options. You may check out InAppSettingsKit and its sample app to see how the whole thing work.

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.

MPMediaItemCollection Delete selected que/collection?

I am currently looking at Apple's AddMusic example and playing around with it before I start rewriting it into my application.
I noticed that it makes its own little playlist of the songs qued. I want to use the swipe action on the table view to remove songs that a use clicked by mistake.
I have implemented the swipe action but can't work out a way to delete that specific row?
Any idea would be great, below is the code to add it. I tried doing the reverse with no luck. If it's not possible how should I go about it?
Cheers
MainViewController *mainViewController = (MainViewController *) self.delegate;
MPMediaItemCollection *currentQueue = mainViewController.userMediaItemCollection;
MPMediaItem *anItem = (MPMediaItem *)[currentQueue.items objectAtIndex: row];
An MPMediaItemCollection is immutable, ie. you can't change the items. You need to create a new one with all items less the one you want to remove. See below:
NSArray* items = [currentQueue items];
NSMutableArray* array = [NSMutableArray arrayWithCapacity:[items count]];
[array addObjectsFromArray:items];
[array removeObjectAtIndex:row];
MPMediaItemCollection* newCollection = [MPMediaItemCollection collectionWithItems:array];
Be careful to not create an empty collection. It's not allowed and the MPMediaItemCollection will raise an exception.

I'm having issues inputing a name if applicable

I have a function here that upon completing a single round, if your score is higher than either a default score entry or a newly placed high score then it will swap its data with your data and push everything else down. removing the last entry from the list. currently this is just one exchange and for functions sake I'm going to hard code it and then refactor it later.
My main problem is that when I set up a text input view to capture the players name execution continues immediately without the players input and crashes the game. I commented out the line that sets the text because I have a default value in place just in case any attempt that I try to make fails. How can I get Execution to wait for a moment while input is taken? Would I have to set up a delegate method? If so I'm still a bit confused by delegates. I could set it up to work but I don't understand it, so I wouldn't be able to do any other special custom tasks with it. I've worked on it for a while and got no further...
-(void)saveData:(ScoreKeep *)stats{
NSMutableDictionary *swap = [[NSMutableDictionary alloc]init];//used for swaping entries
NSString *filePath = [self pathOfFile];
NSLog(#"Writing to %#", filePath);
if ([[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
NSLog(#"Loading previous dictionary to save...");
dataDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
if ([dataDictionary objectForKey:#"1"]) {
NSMutableDictionary *highScore = [dataDictionary objectForKey:#"1"];
if ([stats.score intValue] > [[highScore objectForKey:#"SCORE"] intValue]) {
NSLog(#"You Win! score: %# highscore: %#", stats.score,[NSNumber numberWithInt:[[highScore objectForKey:#"SCORE"] intValue]] );
stats = [[ScoreKeep alloc] initWithNibName:#"Scorekeep" bundle:nil];
NSLog(#"Setting up name entry");
[self.view addSubview:stats.view]; //New view is added so that the player can input data(Assume it is complete);
//stats.nameTag = setName.nameTag;//This line is executed before the new view is dismissed causing an error to occur
[stats setupDictionary]; // It just goes down hill from here if the previous line is uncommented
[dataDictionary setObject:stats.sComponents forKey:#"1"];
}else {
NSLog(#"You Lose: %# highscore: %#", stats.score,[NSNumber numberWithInt:[[highScore objectForKey:#"SCORE"] intValue]] );
}
NSLog(#"Got first place entry");
}else {
NSLog(#"Initilizing Score");
}
}else{
NSLog(#"Creating new dictionary to save...");
dataDictionary = [[NSMutableDictionary alloc]init];
}
[dataDictionary writeToFile:filePath atomically:YES];
}
Help would greatly be appreciated. If more information is needed I'd be happy to provide.
by the way ScoreKeep is an object that contains a dictionary and a function to create a dictionary such that it can set any values I need and package them into sComponents(the dictionary to be entered into the main savefile)
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#class omphalosUtility;
#pragma mark -
#pragma mark Saving data
#pragma mark -
static inline void poop(){
NSLog(#"POOP");
}
I'm going to try making a utility file that works independently of the app so that I Can update files and perform other universal operations such as saving when needed. Its a step in a direction that i'd like to take.
If i get it right, (The code is really nasty, man...) your problem is that you are trying to present a View Controller with the wrong way.
Correct me if i'm wrong, is ScoreKeep is a ViewController? if so, you have to name it properly. that's for a start.
Second, you cant present another view controller only by adding its "view" property to the current view controller's View Hierarchy. that way the view will not respond properly to the events.
the correct way to to what you'r trying to do is by presenting the ScoreKeep ViewController modally.
there is no other right way to do this without using delegation. you will have to acquire this technique.
Your view controller that responsible for getting the name from the user need to have a way to tell it's master view controller that the user entered a name. and that is achieved through delegation.
What you should do:
Basically you create a protocol called something like "NamePrompterViewControllerDelegate"
that will have at least one method that will be called when the user will done entering his name.
Your ScoreKeepViewController should have an instance variable that implemented the protocol (Look at the apple documentation on protocols for assistance)
Your main view controller (the one that contains the method you added) then should implement the protocol you created, and set itself as the delegate of ScoreKeep like that:
stats = [[ScoreKeep alloc] initWithNibName:#"Scorekeep" bundle:nil];
stats.delegate = self;
For more info on presenting and dismissing ViewControllers modally you should read the documentation at Apple Documentation
I hope i helped you, there is just a lot to cover and it hardly can be done by writing an answer.
Feel free to ask more for clearance.

Cocoa - Add Video Watermark General Info

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.