MPMoviePlayerController not playing URL from GDataFeedYouTubeVideo - xcode

I am using GDataFeedYouTubeVideo to populate a tableview with images and titles. This works. I want to play the video after the cell is selected. I am using the url from the feed to pass to the MPMoviePlayer and it looks like it loads because the screen goes black, the moviePlaybackDidFinish is called but does not play the video and goes back to displaying the tableview? An example url from the feed is:
https://www.youtube.com/v/o7QAMH3qRvU?version=3&f=user_uploads&app=youtube_gdata
This does work from a browser but not in the MPMoviePlayer? Please help me figure this one out. I would rather not have to write some hack routine to replace or remove the URLString returned by the feed. I am using ARC & Storyboards. The second time I select a cell I get:
An instance 0xce6a7b0 of class AVPlayerItem was deallocated while key value observers were still registered with it...
Yes I did try what was suggested in:
iOS 5 an instance of AVPlayerItem was deallocated
and this did not fix it.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
YouTubeVideo *item = [searchList objectAtIndex:indexPath.row];
if (item != nil) {
NSURL *url = [NSURL URLWithString:item.URLString];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;
[self.view addSubview:moviePlayer.view];
[moviePlayer setFullscreen:YES animated:YES];
}
}
- (void)moviePlaybackDidFinish:(NSNotification *)notification {
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
if ([player respondsToSelector:#selector(setFullscreen:animated:)])
[player.view removeFromSuperview];
}

Tried this and it works if I format the url slightly:
https://github.com/hellozimi/HCYoutubeParser

Related

Switched from tableview to colelctionview now didselectitematindexpath not called

So I switched from a UITableView to a UICollectionView. The cells are all loading just fine and look beautiful, but now I can no longer select any of them. The taps are recognized in the logs, but it doesn't take me to the view that it's supposed to take me to anymore.
The only things that changed really are the ones the ones you see commented out in the "cellForItem" section. Everything else is identical to how it was when it was working in the TableView. It's just supposed to take me to the ViewController specified when you tap. Instead the tap is recorded, but it does nothing. Any help would be appreciated.
Also I tried getting rid of the [collectionView deselectItemAtIndexPath:indexPath animated:YES];
...but it didn't make any difference.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PlaceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
//UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
// NSArray *topLevelItems = [placeCell instantiateWithOwner:self options:nil];
// cell = [topLevelItems objectAtIndex:0];
Place *p = [_entries objectAtIndex:indexPath.row];
cell.placeName.text = p.PName;
NSLog(#"p:%#",p.PName);
cell.placeName.textColor = [UIColor colorWithRed:3/255.0f green:6/255.0f blue:4/255.0f alpha:1.0f];
NSString *pIcon;
pIcon = typeName;
//NSLog(pIcon);
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
NSLog(#"i:%#",p.PImage);
return cell;
}
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"Tap Recognized");
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
Place *p = [_entries objectAtIndex:indexPath.row];
DetailPlaceViewController * pvc = [[DetailPlaceViewController alloc] init];
[pvc setPlace:p];
[self.navigationController pushViewController:pvc animated:YES];
}
Well this one was fun...
For some odd reason my navigation controller isn't working... so of course using the navigation controller to load a view wasn't going to work. Simple enough solution... load the view without the navigation controller. I was just going to delete this question, but maybe somebody might be in a similar situation one day:
[self presentViewController:pvc animated:YES completion:nil];

Display images from URL in a Detailviewcontroller with Tableviewcontroller as a parent

Hard to explain, but I'll try;
I am making an app for showing roadcameras. I have a TableViewController which leads to a DetailViewController.
What I want to achieve is that when I click on Row 1 it shows the picture from www.url1.com. If I click on Row 2, it shows the picture from www.url2.com, and so on. I can't seem to figure out how to do this.
I first started by using this code:
_place = #[#"E6 Minnesund",
#"E6 Heia"];
_url = #[#"http://webkamera.vegvesen.no/kamera?id=450848",
#"http://webkamera.vegvesen.no/kamera?id=100102"];
But stopped because I couldn't see how I could get this working...
Any ideas?
And please don't just rate the post down because you think its stupid. I'm kinda new to Xcode and for me, this is hard. Thanks in advance
I can post the whole project folder if necessary
just write the code in didselectrowAtIndexPath
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *picker = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
picker.row=indexPath.row;
[self.navigationController pushViewController:picker];
}
and in DetailViewController
in .h
#interface DetailViewController : UIViewController
{
}
#property(nonatomic,assign)int row;
in .m
- (void)viewDidLoad
{
dispatch_queue_t myqueue = dispatch_queue_create("myqueue", NULL);
// execute a task on that queue asynchronously
dispatch_async(myqueue, ^{
NSURL *url = [NSURL URLWithString:[_url objectAtIndex:row];
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
Image.image = [UIImage imageWithData:data]; //UI updates should be done on the main thread
UIImageView * myImageView = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:myImageView];
});
});

Setting up NSMetadataQueryDidUpdateNotification for a simple response

I'm trying to get up and running with an NSMetadataQueryDidUpdateNotification on an OS X app, to alert me when a file in my iCloud ubiquity container is updated. I've been doing a lot of research (including reading other Stack answers like this, this, this, and this), but I still don't have it quite right, it seems.
I've got a "CloudDocument" object subclassed from NSDocument, which includes this code in the H:
#property (nonatomic, strong) NSMetadataQuery *alertQuery;
and this is the M file:
#synthesize alertQuery;
-(id)init {
self = [super init];
if (self) {
if (alertQuery) {
[alertQuery stopQuery];
} else {
alertQuery = [[NSMetadataQuery alloc]init];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];
NSLog(#"Notification created");
[alertQuery startQuery];
}
return self;
}
-(void)queryDidUpdate:(NSNotification *)notification {
NSLog(#"Something changed!!!");
}
According to my best understanding, that should stop a pre-existing query if one is running, set up a notification for changes to the ubiquity container, and then start the query so it will monitor changes from here on out.
Except, clearly that's not the case because I get Notification created in the log on launch but never Something changed!!! when I change the iCloud document.
Can anyone tell me what I'm missing? And if you're extra-super-sauce awesome, you'll help me out with some code samples and/or tutorials?
Edit: If it matters/helps, there is only one file in my ubiquity container being synced around. It's called "notes", so I access it using the URL result from:
+(NSURL *)notesURL {
NSURL *url = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
return [url URLByAppendingPathComponent:kAllNotes];
}
where "kAllNotes" is set with #define kAllNotes #"notes".
EDIT #2: There have been a lot of updates to my code through my conversation with Daij-Djan, so here is my updated code:
#synthesize alertQuery;
-(id)init {
self = [super init];
if (self) {
alertQuery = [[NSMetadataQuery alloc] init];
if (alertQuery) {
[alertQuery setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSString *STEDocFilenameExtension = #"*";
NSString* filePattern = [NSString stringWithFormat:#"*.%#", STEDocFilenameExtension];
[alertQuery setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE %#", NSMetadataItemFSNameKey, filePattern]];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(queryDidUpdate:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];
NSLog(#"Notification created");
[alertQuery startQuery];
}
return self;
}
-(void)queryDidUpdate:(NSNotification *)notification {
[alertQuery disableUpdates];
NSLog(#"Something changed!!!");
[alertQuery enableUpdates];
}
How do you save your document - what url do you give it? Unless you give it an extension yourself, it won't automatically be given one - so your *.* pattern will never match a file that does not have an extension. Try * as the pattern and see what happens.
Also, it helps to log what is happening within queryDidUpdate, until you've worked out exactly what's going on :
Try something like:
-(void)queryDidUpdate:(NSNotification *)notification {
[alertQuery disableUpdates];
NSLog(#"Something changed!!!");
// Look at each element returned by the search
// - note it returns the entire list each time this method is called, NOT just the changes
int resultCount = [alertQuery resultCount];
for (int i = 0; i < resultCount; i++) {
NSMetadataItem *item = [alertQuery resultAtIndex:i];
[self logAllCloudStorageKeysForMetadataItem:item];
}
[alertQuery enableUpdates];
}
- (void)logAllCloudStorageKeysForMetadataItem:(NSMetadataItem *)item
{
NSNumber *isUbiquitous = [item valueForAttribute:NSMetadataItemIsUbiquitousKey];
NSNumber *hasUnresolvedConflicts = [item valueForAttribute:NSMetadataUbiquitousItemHasUnresolvedConflictsKey];
NSNumber *isDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey];
NSNumber *isDownloading = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadingKey];
NSNumber *isUploaded = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey];
NSNumber *isUploading = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadingKey];
NSNumber *percentDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentDownloadedKey];
NSNumber *percentUploaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentUploadedKey];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
BOOL documentExists = [[NSFileManager defaultManager] fileExistsAtPath:[url path]];
NSLog(#"isUbiquitous:%# hasUnresolvedConflicts:%# isDownloaded:%# isDownloading:%# isUploaded:%# isUploading:%# %%downloaded:%# %%uploaded:%# documentExists:%i - %#", isUbiquitous, hasUnresolvedConflicts, isDownloaded, isDownloading, isUploaded, isUploading, percentDownloaded, percentUploaded, documentExists, url);
}
you never allocate your alertQuery....
somewhere you need to alloc,init a NSMetaDataQuery for it
example
NSMetadataQuery* aQuery = [[NSMetadataQuery alloc] init];
if (aQuery) {
// Search the Documents subdirectory only.
[aQuery setSearchScopes:[NSArray
arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
// Add a predicate for finding the documents.
NSString* filePattern = [NSString stringWithFormat:#"*"];
[aQuery setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE %#",
NSMetadataItemFSNameKey, filePattern]];
// Register for the metadata query notifications.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(processFiles:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(processFiles:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
// Start the query and let it run.
[aQuery startQuery];
}
processFiles method
== your queryDidUpdate
- processFiles(NSNotification*)note {
[aQuery disableUpdates];
.....
[aQuery enableUpdates];
}
NOTE: disable and reenable search there!
see:
http://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloud101/SearchingforiCloudDocuments/SearchingforiCloudDocuments.html

MPMoviePlayerController “Loading Movie from server

its problem when i play the video it shows black screen and playing audio without the video and can't do any thing but close app.
here is my code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *movieURL = [NSString stringWithFormat:#"http://www.aliakbar84.com/test/%d.mp4",indexPath.row];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:movieURL]];
[moviePlayer play];
MPMoviePlayerViewController *movieplayer1 = [[MPMoviePlayerViewController alloc] initWithContentURL:movieurl];
[self presentMoviePlayerViewControllerAnimated:movieplayer1];
Why exactly are you initializing both, MPMoviePlayerController and MPMoviePlayerViewController?
That should not be done. Remove the initializing of MPMoviePlayerController!

Will NSNotificationCenter call back method be called in main thread or background thread?

My code is just play a downloaded mp4 files and register the view controller to observe the notification of end of player.
It works pretty good in not only iOS5 but also iOS4.
But I just want to know for sure that whether the call back method by NotificationCenter will be called in background thread or main thread.
(loadMoviePlayerStateChanged:(NSNotification*)notification is call back method in my code)
Do anyone know exactly about this?
- (void) playMovie:(NSURL *)fileURL {
MPMoviePlayerViewController *MPVC = [[MPMoviePlayerViewController alloc] initWithContentURL:fileURL];
self.mMPVC = MPVC;
self.mMPVC.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loadMoviePlayerStateChanged:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.mMPVC.moviePlayer];
[MPVC.moviePlayer prepareToPlay];
[MPVC release];
}
- (void) loadMoviePlayerStateChanged:(NSNotification*)notification {
int loadState = self.mMPVC.moviePlayer.loadState;
if(loadState & MPMovieLoadStateUnknown) {
IGLog(#"The load state is not known at this time.");
return;
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.mMPVC.moviePlayer];
[self.mMPVC.view setFrame:self.view.bounds];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.mMPVC.moviePlayer];
/* if I do not use performSelectorOnMainThread method to add subview to UIViewController`s view,
the view of MPMoviePlayerViewController would not be removed from superview normally */
[self.view performSelectorOnMainThread:#selector(addSubview:)
withObject:self.mMPVC.view
waitUntilDone:YES];
[self.mMPVC.moviePlayer play];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
[self.mMPVC.moviePlayer stop];
[self.mMPVC.moviePlayer.view removeFromSuperview];
NSString* dstFilePath = [[_mPopupVC.mSelectedMovie decryptionFilePath] stringByAppendingPathExtension:#"mp4"];
[[NSFileManager defaultManager] removeItemAtPath:dstFilePath error:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.mMPVC.moviePlayer];
}
I got an answer for my question in apple developer site, the answer is,
"notifications safely thread themselves and perform their selectors on the main thread.
however, your problem is that you should not be adding and removing the player view like that, use the presentModalVideo methods provided as a category in your view controller class."
and I solved the problem that i had. code is below..
- (void) playMovie
{
/*
*create and initialize MPMoviePlayerViewController with specified url and retain it
*/
MPMoviePlayerViewController *MPVC = [[MPMoviePlayerViewController alloc] initWithContentURL:vodWebURL];
self.mMPVC = MPVC;
[MPVC release];
self.mMPVC.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
self.mMPVC.moviePlayer.shouldAutoplay = NO;
[self.mMPVC.moviePlayer prepareToPlay];
/*
*register movie player to NSNotificationCenter
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loadMoviePlayerStateChanged:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.mMPVC.moviePlayer];
}
- (void) loadMoviePlayerStateChanged:(NSNotification*)notification
{
/*
*do your work for the state of the movie player
*/
int loadState = self.mMPVC.moviePlayer.loadState;
if(loadState & MPMovieLoadStateUnknown) {
NSLog(#"The load state is not known at this time.");
return;
} else if(loadState & MPMovieLoadStatePlayable) {
NSLog(#"MPMovieLoadStatePlayable : The buffer has enough data that playback can begin, but it may run out of data before playback finishes.");
} else if(loadState & MPMovieLoadStatePlaythroughOK) {
NSLog(#"MPMovieLoadStatePlaythroughOK : Enough data has been buffered for playback to continue uninterrupted.");
} else if(loadState & MPMovieLoadStateStalled) {
NSLog(#"MPMovieLoadStateStalled : The buffering of data has stalled.");
}
/*
*set frame of the view of MPMoviePlayerViewController and add it
*call play method
*/
[self.mMPVC.view setFrame:self.view.superview.bounds];
[self.view.superview addSubview:self.mMPVC.view];
[self.mMPVC.moviePlayer play];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.mMPVC.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.mMPVC.moviePlayer];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
/*
*remove the view of MPMoviePlayerViewController
*release MPMoviePlayerViewController
*/
[self.mMPVC.moviePlayer stop];
[self.mMPVC.moviePlayer.view removeFromSuperview];
self.mMPVC = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.mMPVC.moviePlayer];
}

Resources