How to play protected video content in iOS using AVPlayer - ios

I have used the below implementation to play a protected video content from the media server, but it shows play icon with cross line.
After login app need to sync the cookies to the media assets to play the protected video after authentication.By using AVURLAsset, we are streaming the protected video but its not working.
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *opt = #{
AVURLAssetReferenceRestrictionsKey: #(AVAssetReferenceRestrictionForbidRemoteReferenceToLocal),
AVURLAssetHTTPCookiesKey: cookies
};
AVAsset *asset = [AVURLAsset URLAssetWithURL:linkUrl//Media protected URL(http://www.example.com/media/video/media_mp4)
options:opt];
AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:item];
AVPlayerViewController *playerVC = [[AVPlayerViewController alloc]init];
playerVC.player = player;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self presentViewController:playerVC animated:NO completion:nil];
});

After searching a lot and finally it worked for me. I got the app cookies from NSHTTPCookieStorage class. Then using this I created a dictionary with key value pairs as below,
#{AVURLAssetHTTPCookiesKey : cookies}
Then I set this dictionary to the options in the AVURLAsset URLAssetWithURL:linkUrl options:
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
AVURLAsset * asset = [AVURLAsset URLAssetWithURL:linkUrl options:#{AVURLAssetHTTPCookiesKey : cookies}];
AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:item];
AVPlayerViewController *playerVC = [[AVPlayerViewController alloc]init];
playerVC.player = player;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self presentViewController:playerVC animated:NO completion:nil];
});

Related

Error about using AVQueuePlayer

I init a AVQueuePlayer like :
AVPlayerItem *item1 = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:#"http://XXX.mp4"]];
AVPlayerItem *item2 = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:#"http://YYY.mp4"]];
AVQueuePlayer player = [[AVQueuePlayer alloc]initWithItems:#[item1,item2]];
and I want to show it by AVPlayerViewController so I init a AVPlayerViewController like :
AVPlayerViewController *playerController = [[AVPlayerViewController alloc] init];
playerController.player = player;
...
...
[self.view addSubview:_playerController.view];
[self addChildViewController:_playerController];
now I want to play it:
[player play];
Question:
It always crashes at main when the first AVPlayerItem end play.
Did I do something wrong or wrong way to show it?
(AVPlayer is OK by this way)

Play Song using MPMediaItemPropertyTitle

I get Song title in TableView using this code:
MPMediaQuery *everything = [[MPMediaQuery alloc] init];
NSArray *itemsFromGenericQuery = [everything items];
for (MPMediaItem *song in itemsFromGenericQuery) {
NSString *songTitle = [song valueForProperty: MPMediaItemPropertyTitle];
[songTitleArray addObject:songTitle];
}
Now I want to play that song inside tableView I added Two button play and Stop how to play using Title in same ViewController.
To play song you can do something like :
MPMusicPlayerController *controller = [MPMusicPlayerController iPodMusicPlayer];
MPMediaItemCollection *collection = [[MPMediaItemCollection alloc] initWithItems:arrayOfMediaItems];
MPMediaItem *item = [collection representativeItem];
[controller setQueueWithItemCollection:collection];
[controller setNowPlayingItem:item];
[controller prepareToPlay];
[controller play];
You can also use AVPlayer to play song, after picking it through MPMediaPickerController :
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker
didPickMediaItems: (MPMediaItemCollection *) collection {
MPMediaItem *item = [[collection items] objectAtIndex:0];
NSURL *url = [item valueForProperty:MPMediaItemPropertyAssetURL];
[self dismissModalViewControllerAnimated: YES];
// Play the item using MPMusicPlayer
MPMusicPlayerController* appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[appMusicPlayer setQueueWithItemCollection:collection];
[appMusicPlayer play];
// Play the item using AVPlayer
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
[player play];
}

Not able to play video file on iPad using AVPlayerViewController

I have seen exactly the same issue here but its unanswered so asking the same question again.
AVPlayer wont play video from url in iOS9
I tried all various ways to try to play the video but unfortunately they are not working for me.
Here is the code :
AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
NSString *url = [[NSBundle mainBundle] pathForResource:#"Intro" ofType:#"mp4"];
_asset = [AVURLAsset assetWithURL: [NSURL URLWithString:url]];
_playerItem = [AVPlayerItem playerItemWithAsset: _asset];
_player = [[AVPlayer alloc] initWithPlayerItem: _playerItem];
[playerViewController.view setFrame:_videoView.frame];
playerViewController.showsPlaybackControls = YES;
[_videoView addSubview:playerViewController.view];
playerViewController.player = _player;
[_player play];
and here is the screen shot of what it looks like currently by using above code. And I used another Apple code to check the video and it worked fine but the Apple code is like too much for me as its too complicated for simple things. Here it is :https://developer.apple.com/library/prerelease/ios/samplecode/AVFoundationSimplePlayer-iOS/
Thanks
AJ
I was finally able to figure this out by again looking into Apple's Sample code.
Solution:
Added the AAPLPlayerView files to my project.
Then changed my UIView in Storyboard to above class
Then updated below lines of code into my view controller class:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.playerView.playerLayer.player = self.player;
NSURL *movieURL = [[NSBundle mainBundle] URLForResource:#"Intro" withExtension:#"mp4"];
self.asset = [AVURLAsset assetWithURL:movieURL];
self.playerItem = [AVPlayerItem playerItemWithAsset: self.asset];
[self.player play];
}
- (AVPlayer *)player {
if (!_player)
_player = [[AVPlayer alloc] init];
return _player;
}
- (AVPlayerLayer *)playerLayer {
return self.playerView.playerLayer;
}
- (AVPlayerItem *)playerItem {
return _playerItem;
}
- (void)setPlayerItem:(AVPlayerItem *)newPlayerItem {
if (_playerItem != newPlayerItem) {
_playerItem = newPlayerItem;
// If needed, configure player item here before associating it with a player
// (example: adding outputs, setting text style rules, selecting media options)
[self.player replaceCurrentItemWithPlayerItem:_playerItem];
}
}
And it worked.
The issue was the PlayerLayer was not set properly and the video was not visible due to that.

AVPlayer - how to reset play button

Im working on a app which stream a audio file online. The code below is working, but when the audio file ends, the play button don't reset. The button is still pressed, and before the user can play the audio file again, the user have to press the button 2 times.
My question is: How do i reset the play button automatically after the audio file ends?
Here is my code:
-(IBAction)togglePlayPauseTapped:(id)sender
{
if(self.togglePlayPause.selected) {
[self.audioPlayer pause];
[self.togglePlayPause setSelected:NO];
} else {
[self.audioPlayer play];
[self.togglePlayPause setSelected:YES];
self.audioPlayer = [[AVPlayer alloc] init];
NSString *urlString = #"MYURL";
NSURL* urlStream = [NSURL URLWithString:urlString];
AVPlayerItem * currentItem = [AVPlayerItem playerItemWithURL:urlStream];
[self.audioPlayer replaceCurrentItemWithPlayerItem:currentItem];
[self.audioPlayer play];
}
}`
Set the delegate of audioPlayer to self and make sure the designated ViewController can receive AVAudioPlayer Delegate calls. Then implement the audioPlayerDidFinishPlaying method and call your togglePlayPauseTapped method:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[self togglePlayPauseTapped:nil];
}
The total should look something like this:
Edit:
And change this
self.audioPlayer = [[AVPlayer alloc] init];
To this:
self.audioPlayer = [[AVAudioPlayer alloc] init];

Multiple audio files playing at once in iOS App

I have an iOS app which works like this:
First view
3 buttons that link to different views, each has its own audio file within
Imagine user opens one view, and starts to play the audio file. When they navigate around the app, the audio file still plays which is fine, Im happy with that.
However, if user then opens the second audio file and presses play, it plays on top of the first one so 2 audios are playing together.
How do I tell the code that if another play button is pressed it should stop the first audio file that is playing??
I am using AVFoundation framework to do this
Code is as follows:
NSString *stringPath = [[NSBundle mainBundle]pathForResource:#"01" ofType:#"MP3"];
NSURL *url = [NSURL fileURLWithPath:stringPath];
NSError *error;
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
[avPlayer setNumberOfLoops:2];
[avPlayer setVolume:self.sliderVolumeOutlet.value];
[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:#selector(updateMyProgress) userInfo:nil repeats:YES];
-(void)updateMyProgress
{
float progress = [avPlayer currentTime]/[avPlayer duration];
self.myProgressView.progress = progress;
}
- (IBAction)sliderVolumeAction:(id)sender {
UISlider *mySlider = sender;
[avPlayer setVolume:mySlider.value];
}
- (IBAction)stopButton:(id)sender {
[avPlayer stop];
[avPlayer setCurrentTime:0];
}
- (IBAction)pauseButton:(id)sender {
[avPlayer pause];
}
- (IBAction)playButton:(id)sender {
[avPlayer play];
}
- (IBAction)backButtonEvent:(id)sender {
[self dismissViewControllerAnimated:YES completion:NULL];
}
You can check whether it is playing the previous track or not by if ([AVPlayer rate] != 0.0)
If it is playing then you can either add the next track into queue or just use this function to replace current track with the new one - (void)replaceCurrentItemWithPlayerItem:(AVPlayerItem *)item
Perhaps creating some sort of playSound function would be better suited for this. Something like this:
- (void)playSoundWithFileName:(NSString *)fileName andExtension:(NSString *)extension {
NSString *stringPath = [[NSBundle mainBundle]pathForResource:fileName ofType:extension];
NSURL *url = [NSURL fileURLWithPath:stringPath];
NSError *error;
if (avPlayer) {
[avPlayer stop];
avPlayer = nil;
}
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
if (error)
NSLog(#"Error");
else {
[avPlayer setNumberOfLoops:2];
[avPlayer setVolume:self.sliderVolumeOutlet.value];
[avPlayer play];
}
}
Use:
[self playSoundWithFileName:#"01" andExtension:#"MP3"];
[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:#selector(updateMyProgress) userInfo:nil repeats:YES];
and call -(void)playSoundWithFileName whenever you want to play another sound.
Or if you were using the AVPlayer class:
- (void)playSoundWithFileName:(NSString *)fileName andExtension:(NSString *)extension {
NSString *stringPath = [[NSBundle mainBundle]pathForResource:fileName ofType:extension];
NSURL *url = [NSURL fileURLWithPath:stringPath];
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
if (avPlayer)
[avPlayer replaceCurrentItemWithPlayerItem:item];
else
avPlayer = [AVPlayer playerWithPlayerItem:item];
[avPlayer setVolume:self.sliderVolumeOutlet.value];
[avPlayer play];
}
Though the latter doesn't allow you set a number of loops.

Resources