How to make avplayer in osx autoplay?
I've tried this:
NSURL *videoURL = [[NSBundle mainBundle]
URLForResource:#"video name" withExtension:#"mp4"];
self.movieView.player = [AVPlayer playerWithURL:videoURL];
it doesn't autoplay?
You haven't called the play method.
[self.movieView.player play]
I think, AVplayer first check the URL content is available or not. You must add observer on it.
[avplayerObject addObserver:self forKeyPath:#"status" options:0 context:nil];
#pragma Observer for Player status.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == _audioPlayer && [keyPath isEqualToString:#"status"]) {
if (_audioPlayer.status == AVPlayerStatusFailed) {
NSLog(#"AVPlayer Failed");
loader.hidden = true;
} else if (_audioPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayerStatusReadyToPlay");
[_audioPlayer play];
} else if (_audioPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
[_audioPlayer removeObserver:self forKeyPath:#"status" context:nil];
}
}
Related
I use youtube-ios-player-helper: https://github.com/youtube/youtube-ios-player-helper and https://developers.google.com/youtube/v3/guides/ios_youtube_helper
I have everything working well. Video playback is fine!
BUT!
In the project settings, I turned off landscape mode.Therefore, the video only plays in portrait mode. How do I turn on landscape mode when playing video in iOS 7?
My solution:
it works for iOS 7 and iOS 8
To play a video from YouTube, I used XCDYouTubeKit (https://github.com/0xced/XCDYouTubeKit)
AppDelegate.h:
#property (nonatomic) BOOL screenIsPortraitOnly;
AppDelegate.m:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if (!self.screenIsPortraitOnly) {
return UIInterfaceOrientationMaskPortrait;
}
else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
MYTableViewController.m:
#import "XCDYouTubeVideoPlayerViewController.h"
#import "XCDYouTubeKit.h"
#import "AppDelegate.h"
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:myIdYoutube];
[[NSNotificationCenter defaultCenter] removeObserver:videoPlayerViewController name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayerViewController.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoFinished) name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayerViewController.moviePlayer];
videoPlayerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:videoPlayerViewController animated:YES completion:nil];
}
-(void)videoFinished
{
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsPortraitOnly = false;
[self dismissViewControllerAnimated:YES completion:NULL];
}
XCDYouTubeVideoPlayerViewController.m
#import "AppDelegate.h"
- (instancetype) initWithVideoIdentifier:(NSString *)videoIdentifier
{
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsPortraitOnly = true;
if ([[[UIDevice currentDevice] systemVersion] integerValue] >= 8)
self = [super initWithContentURL:nil];
else
self = [super init];
if (!self)
return nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
if (videoIdentifier)
self.videoIdentifier = videoIdentifier;
return self;
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsPortraitOnly = false;
if (![self isBeingDismissed])
return;
[self.videoOperation cancel];
}
When a group has been removed –groupForURL:resultBlock:failureBlock: will not be able to find the group anymore. Now you might say you must compare the NSURL you received from the notification with the NSURL you get when using ALAssetsGroupPropertyURL on the current group. However when the current group has a filter on it, the NSURL will be appended with &filter= and the NSURLs won't match.
So if you have a current group of type ALAssetsGroup and you receive a notification from ALAssetsLibraryChangedNotification. How do you check if the current group is the one that got removed?
My code so far:
- (void)viewDidLoad
{
[super viewDidLoad];
self.collectionView.alwaysBounceVertical = YES;
self.collectionView.backgroundColor = [UIColor whiteColor];
self.collectionView.opaque = YES;
self.collectionView.contentInset = UIEdgeInsetsMake(9, 0, 0, 0);
[self.collectionView registerClass:[CMPhotoCollectionViewCell class] forCellWithReuseIdentifier:#"PhotoCell"];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(assetsLibraryDidChange:) name:ALAssetsLibraryChangedNotification object:nil];
self.title = [self.album.group valueForProperty:ALAssetsGroupPropertyName];
if (!self.assets)
_assets = [NSMutableArray new];
else
[self.assets removeAllObjects];
ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if (result) [self.assets addObject:result];
};
[self.album.group enumerateAssetsUsingBlock:assetsEnumerationBlock];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.collectionView reloadData];
}
#pragma mark -
#pragma mark Assets Library
- (void)assetsLibraryDidChange:(NSNotification *)notification
{
if (notification.userInfo[ALAssetLibraryDeletedAssetGroupsKey])
{
NSLog (#"Album removed: %#", notification.userInfo[ALAssetLibraryDeletedAssetGroupsKey]);
NSLog (#"This album: %#", self.album.group);
NSLog (#"%#", [self.album.group valueForProperty:ALAssetsGroupPropertyURL]);
// I get a NSSet with NSURLs of groups that have been removed.
// However the NSURL seems to be always without filter, if my current item
// has a filter on it, the URLS don't match.
}
}
#pragma mark - UICollectionViewDelegate
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
return self.assets.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CMPhotoCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"PhotoCell" forIndexPath:indexPath];
ALAsset *asset = self.assets[indexPath.row];
UIImage *thumbnail = [UIImage imageWithCGImage:asset.thumbnail];
cell.imageView.image = thumbnail;
return cell;
}
I built a CollectionView controller with fixed imageView in 4 cells.
I'd like the imageView to change on cell selection.
Could you help me with this one?
Thank you
here's my code
CollectionView controller .m
....
-(NSInteger)numberOfSectionsInCollectionView:
(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return 4;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Cell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImage *image;
int row = [indexPath row];
image = [UIImage imageNamed:#"ICUbedGREEN.png"];
myCell.imageView.image = image;
return myCell;
}
I'd like the image to change on press but I cannot figure it out...
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath
{
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"ICUbedRED.png"]];
cell.imageView.image = .....
NSLog(#"elementselected");
}
in your subclass for UICollectionViewCell implement the KVO listening method. Make sure you set multiselection to true if you want it to be deselected.
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString#"selected"])
{
// check value of self.selected to know what you are currently.
// change picture of image here
}
}
in your cells init method you will need to add yourself as a listener so
[self addObserver:self forKeyPath:#"selected" options:nil context:nil];
It can be most stupid answer to your questions but it worked for me. I dont know how to work with KEy value paths as stated by Samuel.
Basically i made a NSMutableArray to store the status of icons, red or green..YES or NO..
selState = [[NSMutableArray alloc] initWithObjects:#"NO",#"NO",#"NO",#"NO",nil ];
and then in "ItemForIndexPath" method, checked the value to set image for that item
if ([[selState objectAtIndex:indexPath.row] isEqualToString:#"NO"]) {
image = [UIImage imageNamed:#"ICUbedGREEN.png"];
}
else
{
image = [UIImage imageNamed:#"ICUbedRED.jpg"];
}
When item is selected, using IndexPath, altered the value of NO into YES or vice versa..
if ([[selState objectAtIndex:indexPath.row] isEqualToString:#"NO"]) {
[selState replaceObjectAtIndex:indexPath.row withObject:#"YES"];
}
else if ([[selState objectAtIndex:indexPath.row] isEqualToString:#"YES"]) {
[selState replaceObjectAtIndex:indexPath.row withObject:#"NO"];
}
And then updated the collection View
[self.collectionView reloadData];
ALL CODE HERE
#interface ViewController (){
NSMutableArray *selState;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
selState = [[NSMutableArray alloc] initWithObjects:#"NO",#"NO",#"NO",#"NO",nil ];
}
-(NSInteger)numberOfSectionsInCollectionView:
(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return 4;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Cell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImage *image;
if ([[selState objectAtIndex:indexPath.row] isEqualToString:#"NO"]) {
image = [UIImage imageNamed:#"ICUbedGREEN.png"];
}
else
{
image = [UIImage imageNamed:#"ICUbedRED.jpg"];
}
myCell.imageView.image = image;
return myCell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath
{
if ([[selState objectAtIndex:indexPath.row] isEqualToString:#"NO"]) {
[selState replaceObjectAtIndex:indexPath.row withObject:#"YES"];
}
else if ([[selState objectAtIndex:indexPath.row] isEqualToString:#"YES"]) {
[selState replaceObjectAtIndex:indexPath.row withObject:#"NO"];
}
[self.collectionView reloadData];
}
#end
Thanks
EDITING---->>
the above code in ItemForIndexPath can also be written in
image = [[selState objectAtIndex:indexPath.row] isEqualToString:#"NO"] ?
[UIImage imageNamed:#"ICUbedGREEN.png"] : [UIImage imageNamed:#"ICUbedRED.jpg"];
END EDITING
When I click “play movie” the mpmovieplayer presents itself for half a second and I see it’s loading movie and the controls are there, but then it returns to main screen without playing the video.
How do I fix this?
Edit:
I have changed code and now the player stays up but is stuck on loading, it doesn’t play movie.
IS the problem: not preparing the movie for play? Or not stopping movie in background and then restarting it?
#import "ViewController.h"
#implementation ViewController
#synthesize moviePlayer;
-(IBAction)grabVid:(id)sender;
{
[self presentModalViewController:imagePicker animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[imagePicker setDelegate:self];
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.mediaTypes =
[UIImagePickerController availableMediaTypesForSourceType:
imagePicker.sourceType];
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagePicker animated:YES];
{
[imagePicker dismissModalViewControllerAnimated:YES];
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
//[imagePicker dismissModalViewControllerAnimated:YES];
}
-(IBAction)playMovie:(id)sender
{
NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL];
MPMoviePlayerViewController *playercontroller = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[self.view addSubview:playercontroller.moviePlayer.view];
[playercontroller.moviePlayer setFullscreen:YES animated:YES];
playercontroller.moviePlayer.shouldAutoplay = NO;
[self presentMoviePlayerViewControllerAnimated:playercontroller];
playercontroller.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[playercontroller.moviePlayer play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playercontroller.moviePlayer];
}
- (void)moviePlaybackComplete:(NSNotification *)notification
{
MPMoviePlayerController *moviePlayerController = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[moviePlayerController.view removeFromSuperview];
//[playercontroller.moviePlayer release];
}
- (void)dealloc {
//[super dealloc];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#end
-(IBAction) playVideo
{
NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL];
MPMoviePlayerViewController *playercontroller = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
moviePlayer.initialPlaybackTime = 0;
[self presentMoviePlayerViewControllerAnimated:playercontroller];
playercontroller.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[playercontroller.moviePlayer play];
[[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];
// playercontroller = nil;
}
I am trying to implement an undo/redo method using NSUndoManager. I have asked other questions on this, but am still stuck.
Where I am at the moment is as follows:
.h
NSUndoManager *undoManager;
#property(nonatomic,retain) NSUndoManager *undoManager;
.m
#synthesize undoManager;
[undoManager setLevelsOfUndo:99];
viewdidload:
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
[dnc addObserver:self selector:#selector(undoButtonTapped) name:#"undo" object:nil];
[dnc addObserver:self selector:#selector(redoButtonTapped) name:#"redo" object:nil];
- (void)resetTheImage:(UIImage*)image
{
NSLog(#"%s", __FUNCTION__);
// image = savedImage.image;
if (image != drawImage.image)
{
[[undoManager prepareWithInvocationTarget:self] resetTheImage];
image = drawImage.image ;
} else {
NSLog(#"That didn't work");
}
}
- (void)undoButtonTapped {
NSLog(#"%s", __FUNCTION__);
[undoManager undo];
}
I get "That didn't work"...
I would appreciate help. I will post the answer to my original question when I figure out what I'm doing wrong.
---EDIT---
I have changed resetTheImage as follows:
- (void)resetTheImage:(UIImage*)image
{
NSLog(#"%s", __FUNCTION__);
image = savedImage.image;
if (image != drawImage.image)
{
drawImage.image = image;
savedImage.image = image;
NSLog(#"undo image");
[[self.undoManager prepareWithInvocationTarget:drawImage.image] image];
} else {
NSLog(#"same image");
savedImage.image = image;
}
}
However, confusion rains - it may help if someone (Brad?, Justin?) can provide a bullet point list of the steps I need to take to get this working. For example:
. Add notifications in ...
. Trigger notifications....
. Have undo /redo buttons point to...
. What methods/functions I really need to build..
....
I wish SO would allow me to give you more points than 1..
(It doesn't help that my "o" key is getting wonky)
It does help that I had a baby granddaughter yesterday :))))
First, I want to thank everyone for any/all assistance. I solved this finally although I'm not sure if it's the best solution.
I made a UIView called from the UIViewController. The controls (colors and brushes) remain in the VC. The drawing methods move to the View Method.
The View Method calls a Drawing method to actually perform the draw, and the View method controls the undo/redo.
Here are some code snippets:
-(void)undoButtonClicked
{
//NSLog(#"%s", __FUNCTION__);
if ([self.currentArray count] == 0) {
//nothing to undo
return;
}
DrawingPath *undonePath = [self.currentArray lastObject];
[self.currentArray removeLastObject];
[self.redoStack addObject:undonePath];
[self setNeedsDisplay];
}
-(void)redoButtonClicked
{
//NSLog(#"%s", __FUNCTION__);
if ([self.redoStack count] == 0) {
// nothing to redo
return;
}
DrawingPath *redonePath = [self.redoStack lastObject];
[self.redoStack removeLastObject];
[self.currentArray addObject:redonePath];
[self setNeedsDisplay];
}
Let me know if anyone wants clarification. Thanks all again..
UPDATE as requested:
These are some headers:
DrawingViewController *mvc;
NSMutableArray *pathArray;
NSMutableArray *colorArray;
NSMutableArray *bufferArray;
NSMutableArray *currentArray;
UIBezierPath *myPath;
NSString *brushSize;
CGPoint lastPoint;
int colorIndex;
NSString *colorKey;
SoundEffect *erasingSound;
SoundEffect *selectSound;
BOOL swiped;
int moved;
UIColor *currentColor;
NSString *result;
}
#property(nonatomic,assign) NSInteger undoSteps;
#property (strong, nonatomic) NSString *result;
#property (strong,nonatomic) UIColor *currentColor;
#property (strong,nonatomic) NSMutableArray *currentArray;
#property (strong,nonatomic) NSMutableArray *bufferArray;
#property (strong,nonatomic) DrawingPath *currentColoredPath;
#property (strong,nonatomic) NSMutableArray *redoStack;
#property (strong, nonatomic) NSString *colorKey;
and here are some more of the methods.. The currentArray then keeps track of points, brush and color in a sort of stack. Undo removes from the stack, and adds into a temp stack that can be used to Redo.
-(void)undoButtonClicked
{
//NSLog(#"%s", __FUNCTION__);
if ([self.currentArray count] == 0) {
//nothing to undo
return;
}
DrawingPath *undonePath = [self.currentArray lastObject];
[self.currentArray removeLastObject];
[self.redoStack addObject:undonePath];
[self setNeedsDisplay];
}
-(void)redoButtonClicked
{
//NSLog(#"%s", __FUNCTION__);
if ([self.redoStack count] == 0) {
// nothing to redo
return;
}
DrawingPath *redonePath = [self.redoStack lastObject];
[self.redoStack removeLastObject];
[self.currentArray addObject:redonePath];
[self setNeedsDisplay];
}
#pragma mark - Touch Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//NSLog(#"%s", __FUNCTION__);
self.currentColoredPath = [[DrawingPath alloc] init];
[self.currentColoredPath setColor:self.currentColor];
UITouch *touch= [touches anyObject];
[self.currentColoredPath.path moveToPoint:[touch locationInView:self]];
[self.currentArray addObject:self.currentColoredPath];
// Remove all paths from redo stack
[self.redoStack removeAllObjects];
lastPoint = [touch locationInView:self];
lastPoint.y -= 20;
if ([touch tapCount] == 2) {
[self alertOKCancelAction];
return;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
//NSLog(#"%s", __FUNCTION__);
UITouch *touch = [touches anyObject];
[self.currentColoredPath.path addLineToPoint:[touch locationInView:self]];
[self setNeedsDisplay];
CGPoint currentPoint = [touch locationInView:self];
currentPoint.y -= 20;
lastPoint = currentPoint;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//NSLog(#"%s", __FUNCTION__);
self.currentColoredPath = nil;
}