I'm using a UISlider programmatically in a MPMoviePlayerController and set its value with the movie current playback time. This doesn't work properly in some cases, the value of the slider remains zero not changed with the movie's current playback time. Can anyone help me please?
My code is set to fire after each second. Both labels work properly but the UISlider value doesn't get updated and remains zero.
float playbackTime = player.currentPlaybackTime;
float duration = player.duration;
timeLabel.text = [NSString stringWithFormat:#"%.0f / ",playbackTime];
durationlbl.text=[NSString stringWithFormat: #"%.0f",`duration];`
progressSlider.value = playbackTime;
you should probably do this:
progressSlider.minimumValue = 0.0;
progressSlider.maximumValue = player.duration;
you should do this not all the times that you update the slider but only when you initialize the slider or when you start a new video
i resolved this issue by stop the video on close action of the player before play other video.
this issue occur because of previous video state in the player due to which on launching new video slider valur disturbed.
Related
I have a requirement where I am displaying a media library video (AVAsset) using AVPlayer and updating the current frame in the video using a custom slider in the UI.
However, what I am looking for is how to tie the slider with the video without actually trimming the video.
I want to show a fraction of video attached to the slider i.e. say I have a video of duration 10 secs. I want the slider to be attached to 3-6 secs, which means if the slider is at start it should show the frame at 3.0 secs in the video and if the slider is at end it should show the frame at 6th sec in the video.
Simply put, to the user it should appear as the video is only of total duration 3 secs.
P.S. There is a lot in the above question, but I've tried my best to simplify my query.
1) Seek to start position:
int32_t preferredTimeScale = 600;
CMTime inTime = CMTimeMakeWithSeconds(self.startTime, preferredTimeScale);
[mainPlayer seekToTime:inTime];
2) Set a timer:
_EndOFRegionCheckTimer = [NSTimer scheduledTimerWithTimeInterval:0.10f
target:self
selector:#selector(_checkEndPassedFired)
userInfo:nil
repeats:YES];
3) In timer fire event check current position and stop playing if necessary:
- (void)_checkEndPassedFired {
AVPlayerItem *currentItem = mainPlayer.currentItem;
if ((double)currentItem.currentTime.value/currentItem.currentTime.timescale>self.stopTime)
{
[mainPlayer pause];
}
}
I play a MP3 in my iPhone app using AVAudioPlayer; i need to perform some operations at certain times (say 30th seconds, 1 minute); is there a way to invoke callback functions based on mp3 playing time?
I believe the best solution is to start an NSTimer as you start the AVAudioPlayer playing. You could set the timer to fire every half second or so. Then each time your timer fires, look at the currentTime property on your audio player.
In order to do something at certain intervals, I'd suggest you kept an instance variable for the playback time from last time your timer callback was called. Then if you had passed the critical point between last callback and this, do your action.
So, in pseudocode, the timer callback:
Get the currentTime of your AVAudioPlayer
Check to see if currentTime is greater than criticalPoint
If yes, check to see if lastCurrentTime is less than criticalPoint
If yes to that too, do your action.
Set lastCurrentTime to currentTime
If you're able to use AVPlayer instead of AVAudioPlayer, you can set boundary or periodic time observers:
// File URL or URL of a media library item
AVPlayer *player = [[AVPlayer alloc] initWithURL:url];
CMTime time = CMTimeMakeWithSeconds(30.0, 600);
NSArray *times = [NSArray arrayWithObject:[NSValue valueWithCMTime:time]];
id playerObserver = [player addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{
NSLog(#"Playback time is 30 seconds");
}];
[player play];
// remove the observer when you're done with the player:
[player removeTimeObserver:playerObserver];
AVPlayer documentation:
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVPlayer_Class/Reference/Reference.html
I found this link describing a property property which seems to indicate you can get the current playback time.
If the sound is playing, currentTime is the offset of the current
playback position, measured in seconds from the start of the sound. If
the sound is not playing, currentTime is the offset of where playing
starts upon calling the play method, measured in seconds from the
start of the sound.
By setting this property you can seek to a specific point in a sound
file or implement audio fast-forward and rewind functions.
To check the time and perform your action you can simply query it:
if (avAudioPlayerObject.currentTime == 30.0) //You may need a more broad check. Double may not be able to exactly represent 30.0s
{
//Do Something
}
with multithreading your goal is simple, just do like this :
1 : in your main thread create a variable for storing time passed
2 : create new thread like "checkthread" that check each 30-20 sec(as you need)
3 : if the time passed is what you want do the callback
Yes Sure you can ...it's tricky i hope it works for you but it works for me ..
1- you play your mp3 file.
2- [self performSelector:#selector(Operation:) withObject:Object afterDelay:30];
then the function
-(void)Operation:(id)sender;
called; so you fired function after 30 second of mp3 file .. you can make many of function based on time you want..
3- there is other solution using timers
[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(CheckTime:) userInfo:nil repeats:YES];
it will fire function called Check Time
-(void)CheckTime:(id)sender{
if (avAudioPlayerObject.currentTime == 30.0)
{
//Do Something
//Fire and function call such
[self performSelector:#selector(Operation:) withObject:Object]
}
}
then you can change time interval you want and repeats is for you to control repeat this action every 5 seconds or not..
Hope that helpful..
Thanks
i think ,you want to play different sound-files after 30sec then use this code :
1) all sound-files put in Array and then retrieve from document directory
2)then try this:
-(IBAction)play_sound
{
BackgroundPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:[Arr_tone_selected objectAtIndex:j]ofType:#"mp3"]]error:NULL];
BackgroundPlayer.delegate=self;
[BackgroundPlayer play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[BackgroundPlayer stop];
j++;
[self performSelector:#selector(play_sound) withObject:Object afterDelay:30];
}
I'm making app using MPMoviePlayerController.
I want to make special function.
What I want to function is like this.
If I play movie, player will stop after few second (ex: 30sec).
If I click play button, player has to play from 30sec to next stop point.
For me to realize this function, I've used initialPlaybackTime and endPlaybackTime option of MPMoviePlayerContrller.
But, this function didn't work like my thought.
mplayer.initialPlaybackTime = 0;
mplayer.endPlaybackTime = 10;
[mplayer play];
....
[mplayer pause];
,,,
mplayer.initialPlaybackTime = 10;
mplayer.endPlaybackTime =30;
[mplayer play];
And, mplayer is played again from 0 to 10, not from 10 to 30.
This is a little late, but for anyone who comes upon this question, it appears that endplaybacktime and initialplayback time can only be set once for an initialized mpmovieplayercontroller. If you want to reset the values you'll have to destroy your mpmovieplayercontroller instance and create a new one.
This is very disappointing, could I be wrong? I would love it if I were.
Change your code to set the currentPlaybackTime before restarting the playback. Note, the order of initializing these properties does matter.
[...]
mplayer.initialPlaybackTime = 10.0;
mplayer.endPlaybackTime = 30.0;
mplayer.currentPlaybackTime = 10.0;
[mplayer play];
OK. AvPlayer is working great with streaming audio. In my app I have UISlider that shows current seconds of the playing song. Now I'm trying to make audio seek with UISlider.
Here is the code
-(IBAction)slide{
Float64 curSec = mySlider.value;
int32_t tScale = 600;
CMTime mySec = CMTimeMakeWithSeconds(curSec, tScale);
player.currentTime = mySec; <- error is here
NSLog(#"%f",mySlider.value);
}
The error is "Setter method is needed to assign to object using property assignment syntax"
In .h file I have AVPlayer *player; and #property(nonatomic, retain)AVPlayer *player. Also in .m I have #synthesize player;
So what is wrong? THANK YOU!
According to the doc, it seems to me that you have to use seekToTime: method instead of setting time directly to the currentTime property.
float second = 30.0;
CMTime time = CMTimeMake(second, 1);
[player seekToTime:time];
I have an UISlider that shows the progress of a song, and the user can go back and forth using it.
I'm using a custom player an the code for my UISlider is the following:
mySlider.value = (float)myAudio.packetPosition / (float)myAudio.totalTimeInBytes;
All works perfectly but sometimes the application crashes, receiving a EXC_BAD_ACESS. Maybe it's a division by zero, I don't know.
How do I prevent this?
Thank you!
if(!(myAudio.totalTimeInBytes == 0.0f))
{
mySlider.value = (float)myAudio.packetPosition / (float)myAudio.totalTimeInBytes;
}
else
{
mySlider.value = 0.0f;
}