How do I place a label over an AVPlayer playing a video? - ios

How do I place a label over or "on top of" an AVPlayer playing a video? I have tried adjusting Z-position as suggested in another SO post but it is not working, the video player seems to be in the front of all the labels.
//this is my label
self.commentLabel.layer.masksToBounds = YES;
self.commentLabel.layer.cornerRadius = 15.0;
[self.commentLabel sizeToFit];
self.commentLabel.center = CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/1.4);
self.commentLabel.layer.zPosition=100;
//this is my video player
self.playerViewController = [[AVPlayerViewController alloc] init];
NSString*str3=[self.FRIENDDATA stringByReplacingOccurrencesOfString:#" " withString:#"_"];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://my.website.com/%#/%#.mp4", str3,self.RANDOMDATA]];
AVURLAsset *asset = [AVURLAsset assetWithURL: url];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset: asset];
AVPlayer * player = [[AVPlayer alloc] initWithPlayerItem: item];
self.playerViewController.player = player;
[self.playerViewController.view setFrame:self.referenceImageView.frame];
self.playerViewController.view.layer.zPosition=0;
self.playerViewController.showsPlaybackControls = YES;
[self.view addSubview:self.playerViewController.view];

Have you tried adding the label subview onto the playerViewController ?
[self.playerViewController.view addSubview:self.commentLabel];
From the code I am unsure if commentLabel is not yet initialized or if it initialized somewhere else in the code or from a storyboard. It would be great to initialize the commentLabel on the playerViewController
Like this:
UILabel *commentLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/1.4, 100, 100)];
[self.playerViewController.view addSubview:commentLabel];
That should resolve your issue

Related

Add AVPlayerLayer to UIViewController

Is it possible to display AVPlayerLayer inside a UIViewController which is later on displayed in UIView.
The sample code of what I'm trying to do:
...
UIView *parentView = reinterpret_cast<UIView *>(window->winId());
AVPlayer *_player;
AVURLAsset *_asset;
AVPlayerItem *_playerItem;
AVPlayerLayer *m_playerLayer;
_player = [[AVPlayer alloc] init];
NSURL *baseURL = [[NSURL alloc] initWithString: #"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
_asset = [AVURLAsset assetWithURL:baseURL];
_playerItem = [AVPlayerItem playerItemWithAsset: _asset];
[_player replaceCurrentItemWithPlayerItem:_playerItem];
m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
// works with AVPlayerViewController
// AVPlayerViewController *playerController = [[AVPlayerViewController alloc] init];
// playerController.player = _player;
UIViewController *viewController = [[UIViewController alloc] init];
[viewController.view.layer addSublayer:m_playerLayer];
viewController.view.frame = CGRectMake(this->x(), this->y(), this->width(), this->height());
[parentView addSubview:viewController.view];
[_player play];
...
It works if I try to add the player to AVPlayerViewController and then display it, but I would want to use only AVPlayerLayer since I don't need video controls as I'll implement the functionality separately.
You can use AVPlayerViewController with
avController.showsPlaybackControls = false;
Or simply add the layer
_player = [[AVPlayer alloc] init];
NSURL *baseURL = [[NSURL alloc] initWithString: #"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
_asset = [AVURLAsset assetWithURL:baseURL];
_playerItem = [AVPlayerItem playerItemWithAsset: _asset];
[_player replaceCurrentItemWithPlayerItem:_playerItem];
m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
m_playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:m_playerLayer ];
[_player play];
I subclassed UIView and added on the AVPlayerLayer via SH_Khans method
_player = [[AVPlayer alloc] init];
NSURL *baseURL = [[NSURL alloc] initWithString: #"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
_asset = [AVURLAsset assetWithURL:baseURL];
_playerItem = [AVPlayerItem playerItemWithAsset: _asset];
[_player replaceCurrentItemWithPlayerItem:_playerItem];
m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
m_playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:m_playerLayer ];
[_player play];
Then treat the subclassed UIView how you want. Couple of things though, if you resize the AVPlayerLayerUIView you have to resize the AVPlayerLayer as the system does not do that automatically.
Additionally remember to clip to bounds on the AVPlayerLayerUIView or it will not match your frame as you want.

can't play video on local area network on ios

I can play video over web the network but can't over the local area network, my code is bellow.
- (IBAction)playAction:(id)sender {
// cant play
//self.url = [NSURL URLWithString:#"https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
// cant play
self.url = [NSURL URLWithString:#"http://192.168.43.1:6080/?methodType=download&path=/Download/hi.mp4"];
AVPlayer *player = [AVPlayer playerWithURL:self.url];
AVPlayerViewController *playerVC = [[AVPlayerViewController alloc] init];
playerVC.player = player;
playerVC.view.frame = self.view.frame;
[self.view addSubview:playerVC.view];
self.playerVC = playerVC;
[self.playerVC.player play];
}

MOV on iOS App shows QuickTime Logo At Beginning

In my app I use, I loop a video over and over again. It will always show the QuickTime logo at the beginning of the video each time. I have checked, and there isn't anything like that in the video. Thoughts to how I can get rid of that?
NSURL *videoURL = [[NSBundle mainBundle] URLForResource:#"warpspeed" withExtension:#"mov"];
UIView *patternView = [[UIView alloc] initWithFrame:self.view.bounds];
patternView.backgroundColor = [UIColor blackColor];
[self.moviePlayer2.backgroundView addSubview:patternView];
self.moviePlayer2 = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
[self.moviePlayer2 setControlStyle:MPMovieControlStyleDefault];
self.moviePlayer2.controlStyle = MPMovieControlStyleNone;
self.moviePlayer2.scalingMode = MPMovieScalingModeAspectFit;
self.moviePlayer2.movieSourceType = MPMovieSourceTypeFile;
[self.moviePlayer2 setAllowsAirPlay:YES];
self.moviePlayer2.view.frame = self.view.frame;

Black Screen when attempting to use MPMoviePlayer

I am using MPMoviePlayer to display a video from an external URL onto my iPhone App, however when I run the App a black screen is all that shows.
Here is the URL I am using:
2015-04-27 00:11:29.655 Floadt[21069:2598414] https://scontent.cdninstagram.com/hphotos-xaf1/t50.2886-16/11179443_819874424728492_389701720_n.mp4
Here is my code to try to setup MPMoviePlayer:
if (entry[#"videos"] != nil) {
NSLog(#"There is a Video: %#", entry[#"videos"]);
NSString *urlString = entry[#"videos"][#"standard_resolution"][#"url"];
NSLog(urlString);
NSURL *url = [NSURL URLWithString:urlString];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL: url];
[player prepareToPlay];
[player.view setFrame: CGRectMake(10, 65, 299, 299)];
[cell.contentView addSubview: player.view];
player.shouldAutoplay = YES;
[player play];
}
You need to retain your instance to MPMoviePlayerController i.e. as a property or an instance variable. The reference to the movie player is lost if you do not retain.
When we try to load the video from URL initially it will display blank screen only. MPMoviePlayerController will take some time to load the video from url.So we can display first frame of the video till the video loads. For this need to import two frameworks.
1.AVFoundation
2.AssetsLibrary
Using these two we can display first frame of video into UIImageView as follows:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
url=[NSURL URLWithString:#"https://scontent.cdninstagram.com/hphotos-xaf1/t50.2886-16/11179443_819874424728492_389701720_n.mp4"];
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
if ([[avAsset tracksWithMediaType:AVMediaTypeVideo] count] > 0)
{
AVAssetImageGenerator *imageGenerator =[AVAssetImageGenerator assetImageGeneratorWithAsset:avAsset];
Float64 durationSeconds = CMTimeGetSeconds([avAsset duration]);
CMTime midpoint = CMTimeMakeWithSeconds(durationSeconds/2.0, 600);
NSError *error;
CMTime actualTime;
CGImageRef halfWayImage = [imageGenerator copyCGImageAtTime:kCMTimeZero actualTime:&actualTime error:&error];
if (halfWayImage != NULL)
{
NSString *actualTimeString = (NSString *)CFBridgingRelease(CMTimeCopyDescription(NULL, actualTime));
NSString *requestedTimeString = (NSString *)CFBridgingRelease(CMTimeCopyDescription(NULL, midpoint));
NSLog(#"Got halfWayImage: Asked for %#, got %#", requestedTimeString, actualTimeString);
UIImage *img=[UIImage imageWithCGImage:halfWayImage];
_imgVw.image=img;
}
}
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapped)];
[_imgVw addGestureRecognizer:tap];
}
-(void)tapped
{
MPMoviePlayerController *movPlayer=[[MPMoviePlayerController alloc] init];
[movPlayer setContentURL:url];
[movPlayer setMovieSourceType:MPMovieSourceTypeFile];
[movPlayer.view setFrame:CGRectMake(0, 0, _imgVw.frame.size.width, 250)];
[movPlayer prepareToPlay];
movPlayer.controlStyle = MPMovieControlStyleNone;
movPlayer.fullscreen = NO;
movPlayer.shouldAutoplay=YES;
[movPlayer setScalingMode:MPMovieScalingModeAspectFill];
[_imgVw addSubview:movPlayer.view];
[movPlayer play];
}
Here i am taking UIImageView view for playing the video. In viewDidLoad i am loading the 1st frame and giving tap gesture to the UIImageView. When i tapped the ImageView then i am playing the video.

AVPlayer doesn't show anything

I try to embed different videos from youtube vimeo, dailymotion.
Sadly at the Moment nothing is shown except the backgroundcolor of my containerView:
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0, 320.0f, 200.0f)];
//item.url is my url which i get fro my webserver, it looks like http://www.youtube.com/watch?v=zPP6lXaL7KA&feature=youtube_gdata_player
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:item.url]];
AVPlayer *avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
NSLog(#"%#",playerItem);
AVPlayerLayer *avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayerLayer.frame = self.frame;
[containerView.layer addSublayer:avPlayerLayer];
[self addSubview:containerView];
[avPlayer play];
if (avPlayer.status == AVPlayerStatusReadyToPlay) {
//[playingLbl setText:#"Playing Audio"];
NSLog(#"It works");
} else if (avPlayer.status == AVPlayerStatusFailed) {
// something went wrong. player.error should contain some information
NSLog(#"Not works");
NSLog(#"%#",avPlayer.error);
}
else if (avPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
containerView.backgroundColor = [UIColor blueColor];
NSLog(#"error: %#", avPlayer.error);
NSLog(#"AVPlayer: %#", avPlayer);
AVPlayer Error is Null and the only Log i always get from the Status is: AVPlayerItemStatusUnknown. Any ideas?
EDIT 1:
Ich changed my Code to:
#implementation VideoView
BlockVideo *list;
- (id)initWithBlock:(GFBlock *)block {
self = [super initWithBlock:block];
if (self) {
if (block.values && block.values.count) {
list = (GFBlockVideo *) [block.values objectAtIndex:0];
for (int i=0; i<list.videos.count; ++i) {
GFBlockVideoItem *item = list.videos[i];
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0, 320.0f, 200.0f)];
//Like i said item.url = http://www.youtube.com/watch?v=zPP6lXaL7KA&feature=youtube_gdata_player
//#property (nonatomic, strong) NSString* url;
AVAsset *asset = [AVAsset assetWithURL:[NSURL URLWithString:item.url]];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
AVPlayer *avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayerLayer.frame = containerView.frame;
[containerView.layer addSublayer:avPlayerLayer];
[self addSubview:containerView];
[avPlayer play];
containerView.backgroundColor = [UIColor blueColor];
Sadly the only thing i can see is the blue containerView :/
I think the Problem is not the AVPlayer himself, but the frames and the layer maybe....
You'd have to do the following:
AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:item.url]];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
AVPlayer *avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayerLayer.frame = self.frame;
[containerView.layer addSublayer:avPlayerLayer];
[self addSubview:containerView];
[avPlayer play];
Hope this helps.
Addendum:
It also depends on your URL; if as you said, you have one such as in this format:
http://www.youtube.com/watch?v=zPP6lXaL7KA&feature=youtube_gdata_player
Then you should use this instead:
[NSURL urlWithString:item.url];
Given that item is your object and url is a property there of object type NSString.
AVPlayer Implementation which working for me:
MP4:
player = [AVPlayer playerWithURL:videoPathUrl];
AVcontroller = [[AVPlayerViewController alloc] init];
[AVcontroller.view setFrame:CGRectMake(0, 0,self.view.frame.size.width, self.view.frame.size.width)];
AVcontroller.player = player;
AVcontroller.showsPlaybackControls = FALSE;
[self addChildViewController:AVcontroller];
[self.view addSubview:AVcontroller.view];
[player play];
MP3 :
playerItem = [AVPlayerItem playerItemWithURL:url];
player = [AVPlayer playerWithPlayerItem:playerItem];
player = [AVPlayer playerWithURL:url];
[player play];
For getting thumbnail form video try this
AVAsset *asset = [AVAsset assetWithURL:videoPathUrl];
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
float tempTime = CMTimeGetSeconds(player.currentItem.duration);
CMTime time = CMTimeMake(tempTime, 1); // (1,1)
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
UIImage *aThumbnail = [UIImage imageWithCGImage:imageRef];
For Stop Video
[player pause];
player = nil;
**Setting Play rate/Speed for video **
[player play];
[player setRate:currentRate];
Play From start
[player seekToTime:kCMTimeZero];
[player play];
for checking video is playing or not
if ((player.rate != 0) && (player.error == nil)) {
// playing
}
For seeking video (for some duration ahead)
float tempSeekTime = CMTimeGetSeconds(player.currentItem.duration) + 10;
CMTime targetTime = CMTimeMakeWithSeconds(tempSeekTime, NSEC_PER_SEC);
[player seekToTime:targetTime];
Use the requestPlayerItemForVideo method of PHImageManager to acquire an AVPlayerItem; it is the simplest, sure-fire way to play an AVAsset, performing flawlessly and consistently.
I use it here:
https://youtu.be/7QlaO7WxjGg

Resources