Hi i created Avplayer for playing audio from server and its working perfectly but UISlider is not syncing with Audio even after updating UISlider method but the slider is moving properly but its not syncing with audio.i need to match that audio with UISlider
seekbar =[[UISlider alloc]init];
seekbar.frame=CGRectMake(10,CGRectGetMinY(PlayAudio.frame)-50, CGRectGetWidth(self.view.frame)-20, 20);
[seekbar addTarget:self action:#selector(seektime:) forControlEvents:UIControlEventValueChanged];
seekbar.continuous=YES;
[self.view addSubview:seekbar];
-(void)Audio{
NSString *urlString= #"https:/embed-ssl.wistia.com/deliveries/85dcf8de9db3830f47f136a4dba89114be58403f/dhwpxq4l9l.wav";
audioPlayer = [[AVPlayer alloc]initWithURL:[NSURL URLWithString:urlString]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[audioPlayer currentItem]];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(updateProgress) userInfo:nil repeats:YES];
[audioPlayer play];
NSLog(#"Audio playing");
}
- (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");
} else if (audioPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayerStatusReadyToPlay");
[audioPlayer play];
} else if (audioPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
}
- (void)seektime:(UISlider*)sender {
CGFloat currentSongTime = CMTimeGetSeconds([audioPlayer currentTime]);
seekbar.value = currentSongTime;
seekbar.minimumValue=0;
seekbar.maximumValue=currentSongTime;
}
- (void)updateProgress {
[seekbar setValue:CMTimeGetSeconds(audioPlayer.currentTime)];
}
Why are you changing the maximum value at every change?
You can set the minimumValue and maximumValue when you get AVPlayerStatusReadyToPlay according to audioPlayer.currentItem.duration
So instead of the seektime you can just use:
else if (audioPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayerStatusReadyToPlay");
[audioPlayer play];
seekbar.minimumValue = 0;
seekbar.maximumValue = CMTimeGetSeconds(audioPlayer.currentItem.duration);
}
Related
I am using AvPlayer to stream and play audio file from url. my code is working fine with small size url but stop playing big size audios.please help me to resolve this issue..
here is my code
-(void)playAudioFeeds:(NSString *)audioStr{
AVPlayerItem *audioPlayerItem;
[self enableObserver:NO onObject:audioPlayerItem addObserver:self];
audioPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:audioStr]];
[self enableObserver:YES onObject:audioPlayerItem addObserver:self];
self.audioFeedsPlayer = [[AVPlayer alloc]initWithPlayerItem:audioPlayerItem];
[self.audioFeedsPlayer play];
}
and code to add observer is..
- (void)enableObserver:(BOOL)enable onObject:(AVPlayerItem *)object addObserver:(id)observer {
if (enable) {
[object addObserver:observer forKeyPath:#"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
[[object valueForKey:#"player"] addObserver:self forKeyPath:#"status" options:0 context:nil];
NSLog(#"Enable KYObserver");
} else {
#try {
[object removeObserver:observer forKeyPath:#"playbackLikelyToKeepUp" context:nil];
[[object valueForKey:#"player"] removeObserver:self forKeyPath:#"status" context:nil];
NSLog(#"Remove KYObserver");
} #catch (NSException *__unused exception) {
NSLog(#"Exceptions occurs on removing the KYObserver");
}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
// check that all conditions for a stuck player have been met
AVPlayer *player = [object valueForKey:#"player"];
NSLog(#"In OVKP of songPlayer");
NSLog(#"keyPath:%#",keyPath);
if ([keyPath isEqualToString:#"status"]) {
if (player.status == AVPlayerStatusFailed) {
NSLog(#"AVPlayer Failed");
} else if (player.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayerStatusReadyToPlay");
} else if (player.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
if ([keyPath isEqualToString:#"playbackLikelyToKeepUp"]) {
if (player.currentItem.playbackLikelyToKeepUp == NO &&
CMTIME_COMPARE_INLINE(player.currentTime, >, kCMTimeZero) &&
CMTIME_COMPARE_INLINE(player.currentTime, !=, player.currentItem.duration))
{
NSLog(#"Hanged");
[player performSelector:#selector(play) withObject:nil afterDelay:1];
}
}
}
Hi I am trying to play live streaming api in my app but their is some error occurs like below...
Response Fail. Error : The operation couldn’t be completed. (Cocoa
error 3840.)
please help to sort out this problem
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",arrayId);
Service *srv=[[Service alloc]init];
NSString *str=#"http://streamtvbox.com/site/api/matrix/";
NSString *method=#"channel";
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[dict setValue:arrayId forKey:#"id"];
[srv postToURL:str withMethod:method andParams:dict completion:^(BOOL success, NSDictionary *responseObj)
{
if (success) {
NSLog(#"Hello I am success");
}
NSLog(#"%#",responseObj);
_player = [[MPMoviePlayerViewController alloc] initWithContentURL:responseObj];
[self presentMoviePlayerViewControllerAnimated:_player];
}];
}
AVPlayerItem is the best choice in this case as you have more control.
See the below code snippet. I have given you just basic example. You do some re-search on AVPlayerItem.
Define your AVPlayer object:
AVPlayer *videoPlayer;
Prepare AVPlayer and add Observers:
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:imageText]];
videoPlayer = [AVPlayer playerWithPlayerItem:playerItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[videoPlayer currentItem]];
[videoPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(updateProgress:) userInfo:nil repeats:YES];
Handling callbacks:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (object == videoPlayer && [keyPath isEqualToString:#"status"])
{
if (videoPlayer.status == AVPlayerStatusFailed)
{
NSLog(#"AVPlayer Failed");
}
else if (videoPlayer.status == AVPlayerStatusReadyToPlay)
{
NSLog(#"AVPlayerStatusReadyToPlay");
[videoPlayer play];
}
else if (videoPlayer.status == AVPlayerItemStatusUnknown)
{
NSLog(#"AVPlayer Unknown");
}
}
if (object == videoPlayer && [keyPath isEqualToString:#"playbackLikelyToKeepUp"])
{
if (videoPlayer.playbackLikelyToKeepUp)
{
// Hide Activity indicator
[videoPlayer play];
}
}
if (object == videoPlayer && [keyPath isEqualToString:#"playbackBufferEmpty"])
{
if (videoPlayer.playbackBufferEmpty)
{
// Show Activity indicator
[videoPlayer pause];
}
}
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
// code here whatever you want to do on finishing video stream..
}
Hi i just created AVplayer for playing audio from server. My problem is my UISlider is not moving based on Audioplayer.please help me out to overcome this problem.
seekbar =[[UISlider alloc]init];
seekbar.frame=CGRectMake(10,CGRectGetMinY(PlayAudio.frame)-50, CGRectGetWidth(self.view.frame)-20, 20);
[seekbar addTarget:self action:#selector(seekTime:) forControlEvents:UIControlEventValueChanged];
seekbar.continuous=YES;
seekbar.minimumValue=0;
seekbar.maximumValue=20;
[self.view addSubview:seekbar];
-(void)Audio{
NSString *urlString= #"https.wav";
audioPlayer = [[AVPlayer alloc]initWithURL:[NSURL URLWithString:urlString]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[audioPlayer currentItem]];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(updateProgress) userInfo:nil repeats:YES];
[audioPlayer play];
}
- (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");
} else if (audioPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayerStatusReadyToPlay");
[audioPlayer play];
} else if (audioPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
}
- (void)seekTime:(id)sender {
[seekbar setValue:CMTimeGetSeconds(audioPlayer.currentTime)];
}
seekTime is only called when the user moves the slider. So that is not a good place for updating it.
You should have a updateProgress method, that is called from the NSTimer, that's where you need to update the slider position:
- (void)updateProgress {
[seekbar setValue:CMTimeGetSeconds(audioPlayer.currentTime)];
}
So everytime the NSTimer fires, it should update the position of the slider.
On the seekTime method you should do the opposite: set the audio playback to the point that the user selected. Something like this:
[audioPlayer setCurrentTime:seekbar.value];
I have implemented AVPlayer. It is working fine. But many times during playing audio from URL, it stops/pauses automatically and takes very long time to resume/replay. On the other hand if I manually just pause and play it works fine means it does not take too much time to re-play. I want to resume/replay it whenever it is ready. Any suggestion will be great. Thank in advance !!!!!!!!
My code :
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (!songFinished) {
if (object == playerItem && [keyPath isEqualToString:#"playbackBufferEmpty"])
{
if (playerItem.playbackBufferEmpty) {
printf("\n\n\t****player item playback buffer is empty****\n\n");
//[s activityIndicator] startAnimating];
[player pause];
}
}
else if (object == playerItem && [keyPath isEqualToString:#"playbackLikelyToKeepUp"])
{
if (playerItem.playbackLikelyToKeepUp)
{
printf("\n\n\t****Ready to Play audio ****\n\n");
[player play];
//Your code here
}
}
// for player status ------------------------------------------------------
else if (object == player && [keyPath isEqualToString:#"status"])
{
if (player.status == AVPlayerStatusFailed)
{
printf("\n\n\tAVPlayer Failed\n\n");
[ViewUtilities showAlert:AUDIO_PLAYER :AUDIO_PLAYER_FAILED_MESSAGE];
}
else if (player.status == AVPlayerStatusReadyToPlay)
{
printf("\n\n\tAVPlayerStatusReadyToPlay\n\n");
[player play];
nsTimer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
}
else if (player.status == AVPlayerItemStatusUnknown)
{
[ViewUtilities showAlert:AUDIO_PLAYER :AUDIO_PLAYER_UNKNOWN];
printf("\n\n\tAVPlayer Unknown\n\n");
}
if (!player)
{
return;
}
}
}
}
I dont know where I am going wrong. [audioPlayer play], [audioPlayer stop] not working. because audioPlayer goes nil. But if I try to play audioPlayer in Status Check AVPlayerStatusReadyToPlay, then it works fine, but still other buttons not works same audioPlayer nil.
customClass.h
#property (nonatomic, retain) AVPlayer *audioPlayer;
customClass.m
-(void)prepareAudioPlayerFor:
NSURL *urlPath = [NSURL URLWithString:#"http://freshmp3music.ru/music/04.2013/chris_brown_-_fine_china_(www.freshmp3music.ru).mp3"];
AVAsset *asset = [AVURLAsset URLAssetWithURL:urlPath options:nil];
AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
AVPlayer *player = [AVPlayer playerWithPlayerItem:anItem];
audioPlayer = player;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[audioPlayer currentItem]];
[audioPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
}
- (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");
} else if (audioPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayerStatusReadyToPlay");
if(audioPlayer.currentItem == nil)
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Alert" message:#"No Audio Anthem Found" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}else
{
NSLog(#"readyToPlay");
// [audioPlayer play]; // Here Play works fine but still other buttons not work
}
} else if (audioPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
NSLog(#"finished");
// [self playPauseBtn:nil];
CMTime fiveSecondsIn = CMTimeMake(0, 1);
[audioPlayer seekToTime:fiveSecondsIn];
[audioPlayer pause];
}
- (IBAction)playBtn:(id)sender {
if (audioPlayer == nil) {
NSLog(#"Player Nil");
}
[audioPlayer play]; // this don't work why
}
OUTPUT : AVPlayerStatusReadyToPlay
OUTPUT : readyToPlay
OUTPUT : Player Nil