AVPlayer seekTo not accurate - ios

So I have an HLS stream that I have AVPlayer playing. I am trying to create a button to jump back 30 seconds like so:
- (void) rewindStream
{
NSLog(#"Seeking...");
NSLog(#"Current Time: %f", CMTimeGetSeconds(self.player.currentTime));
NSLog(#"New Time: %f", CMTimeGetSeconds(CMTimeMakeWithSeconds(CMTimeGetSeconds(self.player.currentTime) - 30.0f, self.player.currentTime.timescale)));
[self.player pause];
CMTime cmTime = CMTimeMakeWithSeconds(CMTimeGetSeconds(self.player.currentTime) - 30.0f, self.player.currentTime.timescale);
[self.player seekToTime:cmTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
NSLog(#"Complete. Current Time: %f", CMTimeGetSeconds(self.player.currentTime));
[self.player play];
}];
}
Which works sometimes, but not others. Here is the log:
Seeking...
Current Time: 47.253361
New Time: 37.254001
Complete. Current Time: 37.254944
Seeking...
Current Time: 59.409800
New Time: 49.410447
Complete. Current Time: 50.103244
Seeking...
Current Time: 68.780054
New Time: 58.780436
Complete. Current Time: 60.086244
Seeking...
Current Time: 80.493733
New Time: 70.494375
Complete. Current Time: 80.140578
Seeking...
Current Time: 92.674773
New Time: 82.675062
Complete. Current Time: 110.135244
I have the tolerance set, and I am making sure I give enough time for the segments to download/buffer so that seeking is possible, but I am not sure what the issue could be.
Any help would be greatly appreciated.
Thanks.

I always use a timescale of 60000 which gives enough accuracy for almost anything. Not sure if this is your issue but I've found that most of my CMTime problems came before I settled on this. Warren Moore has a great post describing this at http://warrenmoore.net/understanding-cmtime

It looks right, off the top of my head, maybe something like this?
CMTime currentTime = self.player.currentTime;
CMTime timeToSubtract = CMTimeMakeWithSeconds(30, 1);
CMTime resultTime = CMTimeSubtract(currentTime, timeToSubtract);
[self.player seekToTime:resultTime];

Related

AvPlayer seekToTime issue

I am working on video app and playing video on AVPlayer. But problem is when I seek the video to particular time with the help of UISlider. The player seekToTime method get time value in integer but I want that it gets in float. Please help
Here is my code
Float32 sliderValue = (float) avPlayerSlider.value;
[mPlayer seekToTime:CMTimeMake(sliderValue, 1) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
You can set proper time scale.
CMTimeMake(12345, 10000); //This is 1.2345 seconds
Or use defined time scales
#define NSEC_PER_USEC 1000ull /* nanoseconds per microsecond */
#define USEC_PER_SEC 1000000ull /* microseconds per second */
#define NSEC_PER_SEC 1000000000ull /* nanoseconds per second */
#define NSEC_PER_MSEC 1000000ull /* nanoseconds per millisecond */
In my player app, I'm using such conversations:
CMTime thumbTime = CMTimeMakeWithSeconds(self.currentPlaybackTime, NSEC_PER_SEC);
I have also been plagued by this problem, fix it and the code below:
[_playerItem cancelPendingSeeks];
[_player seekToTime:CMTimeMakeWithSeconds(leftPosition, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
leftPosition(CGFloat) is the time of the asset, the unit is a second.
I hope can help to you

iOS - AVPlayer seekToTime restarts playback of currentItem

I'm making an app that uses AVPlayer. In one of my views I have a UISlider with which the user should be able to scrub forward and backward. I'm having some trouble getting seekToTime to work as I want. When I try to change time the playback starts from 0, and I'm not sure how to solve this. My current implementation looks like this:
[self.progressSlider addTarget:self action:#selector(sliderValueChanged) forControlEvents:UIControlEventValueChanged];
[self.progressSlider addTarget:self action:#selector(sliderReleased) forControlEvents:UIControlEventTouchUpInside];
- (void)sliderValueChanged {
[...]
[player pause];
}
- (void)sliderReleased {
float timeInSecond = self.progressSlider.value;
timeInSecond *= 1000;
// I have trie to hard code this value, but I get the same result.
CMTime cmTime = CMTimeMake(timeInSecond, NSEC_PER_SEC);
[player.currentItem seekToTime:cmTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
if (finished) {
[player play];
}
}];
}
Any ideas on what I'm doing wrong?
Can mention that I stream audio using AVPlayer's: playerItemWithURL if that makes any difference.
One problem is that NSEC_PER_SEC is 1,000,000,000, so CMTimeMake(timeInSecond, NSEC_PER_SEC) is going to be a really tiny number (unless timeInSecond is ridiculously huge) - in fact, it will be arbitrarily close to zero, which is exactly what you are experiencing.
Just to be clear: CMTimeMake defines a rational number. You are giving a numerator and a denominator. If your denominator is huge, the rational number will be tiny.

Accuracy issue in jump to particular section of video in MPMoviePlayerController

in my app i want to add feature . swipe on video take the video to next 2 sec from current playback time. but my player not doing this accurate and exact according to time which i pass to function it jump the current play back time at any where else. i already search a lot and found may be this is due to key-frame of my video i think i need to increase key-frame of video if yes
then (1) what is the best way to increase key-frame of video?
if this issue can solve without increasing key-frame then
(2) how can i do this ?
here is my code
-(void) handleOneFingerSwipeRight
{
if(labelTimer.isValid)
[labelTimer invalidate];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(signleTap) object:nil];
[videoPlayer pause];
double d = 0;
d = floor([videoPlayer currentPlaybackTime]);
d = d+2.0;
NSLog(#"current time %f",floor([videoPlayer currentPlaybackTime]));
NSLog(#"new time %f",d);
[videoPlayer setCurrentPlaybackTime:d];
[videoPlayer play];
[self setLable:[NSString stringWithFormat:#"Adaptive Forward %f",d]];
}

AVPlayer provide wrong currenttime and duration iOS when seek the video many times?

I use use AVPlayer to implement a custom player.
Some video playerItem provide the current time and wrong duration. After to seek time use slide to seek time many times. Call the API
When I seek to zero, some video can not be precisely seeked.
[self.player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)
toleranceBefore:CMTimeMake(1, 1)
toleranceAfter:CMTimeMake(1, 1)
completionHandler:^(BOOL finished) {
if (finished) {
IVCLogV(#"seek finish!");
}
else
{
IVCLogV(#"seek interrupted");
}
if (completionHandle) {
completionHandle(finished);
}
}];
I change the codes according the mediaTime.timeScale. Now I discover the video stream have changed the video duration and current time after several play.
Make sure that the Timescale of the media being played matches with your timescale. I can see you have used NSEC_PER_SEC as timescale. You may have to scale your CMTime input to seelTo method.
CMTime timeAccordingToMediaTimescale = CMTimeConvertScale(time, mediaTime.timescale, CMTimeRoundingMethod);

AVPlayer Progress slider change with user dragging it

I am using AVPlayer, and its working good.
I put slider and it is progression according to player duration.
But i want if user drags slider then play time changes accordingly. i.e. Song forwards or backwards according to slider position.
I have tried
-(IBAction)sliderChange:(id)sender{
[player pause];
CMTime t = CMTimeMake(slider.value,1);
[player seekToTime:t];
[player play];
}
But it again takes slider to starting point. Any help would be much appreciated.
EDIT (WORKING WITH BELOW LINK)
AVPlayer Video SeekToTime
-(IBAction) valueChangeSliderTimer:(id)sender{
[avplayer pause];
isPlaying = FALSE;
[btnPauseAndPlay setTitle:#"Play" forState:UIControlStateNormal];
float timeInSecond = sliderTimer.value;
timeInSecond *= 1000;
CMTime cmTime = CMTimeMake(timeInSecond, 1000);
[avplayer seekToTime:cmTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
}
Edited Code .
And try this link as well :
Try this link

Resources