mpmovieplayercontroller stop function, and then play with current time (iPhone) - ios

I have this situation:
Play (streamed) video, stop by code the video, and then play again.
The problem is that the video is begin from the start and not when i stopped it.
What solution do you now of?

EDIT: As #willcodejavaforfood has pointed out, stop only pauses the movie - calling play should restart where you left off so you shouldn't ever need my answer! Can you post the code you are using so we can see what's going on? Thanks.
If you want it to restart where you left off, you will need to remember how far through the movie you were and set the initialPlaybackTime property before you call play again.
i.e. Store the time when you start the movie
...
[myMoviePlayer start];
startDate = [[NSDate date] retain];
...
Store the time you stop the movie
...
[myMoviePlayer stop];
endDate= [[NSDate date] retain];
...
And when you start playback again, use the difference between these times
...
[myMoviePlayer setInitialPlaybackTime:[endDate timeIntervalSinceDate:startDate]];
[myMoviePlayer play];
...
Sam
PS To force it to start at the start, just set the initial playback time to 0.0
PPS I don't know how accurate NSDate is in milliseconds so you might have to use a better way of working out the current position in the movie :)

Related

iOS AVPlayer EXC_BAD_ACCESS when accessing properties

I'm working on a plugin for Apache Cordova that will allow audio streaming from a remote URL through the Media API.
The issue that I'm experiencing is that I get an EXC_BAD_ACCESS signal whenever I try to access certain properties on the AVPlayer instance. currentTime and isPlaying are the worst offenders. The player will be playing sound through the speakers, but as soon as my code reaches a player.currentTime or [player currentTime] it throws the bad access signal.
[player play];
double position = round([player duration] * 1000) / 1000;
[player currentTime]; //This will cause the signal
I am using ARC, so I'm not releasing anything that shouldn't be.
Edit:
Everything that I've done has been hacking around on the Cordova 3 CDVSound class as a proof of concept for actual streaming on iOS.
The original code can be found here: https://github.com/apache/cordova-plugin-media/tree/master/src/ios
My code can be found here:
CDVSound.h
CDVSound.m
The method startPlayingAudio will trip an exc_bad_access at line 346. Removing line 346 will cause audio to play, but it will trip a bad access later down the road when getCurrentPositionAudio and line 532 is called.
Edit / Solution
So it turns out that the best way to handle this is to use a AVPlayerItem and then access it with player.currentItem.currentTime. The real question then becomes, why isn't this behavior documented with AVPlayer and why does it behave like this?

Stop watch and timer

I want to use NSDate and NSTimer to retrieve the elapsed time between I press a start button and a stop button and present the time in seconds. Then I want to use the time for a calculation. I know how to get the time but it is always in format like this 2013-01-15 14:01:55.369.
How do I subtract one time from the other to get the seconds.
I am not sure how to use NDDate and NSTimer.
This should be really easy but I am sort of stuck here.
//Make two properties `NSDate *startDate, *endDate`
//in the action method of start Button
startDate=[NSDate date];
//in the action method of stop Button
stopDate=[NSDate date];
long elapsedSeconds=[stopDate timeIntervalSinceDate:startDate];
NSLog(#"Elaped seconds:%ld seconds",elapsedSeconds);
Please check my project for stopwatch kind of thing, this may come handy for you
Check this code, most of requirement are solved here.
You can use
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)date
to get the time interval between the receiver and a given date in seconds.
To get current time from NSData use:
[[NSData data] timeIntervalSince1970];
and just substract it from your NSTime value.
Use timeIntervalSinceDate between the start date and en stop date.

How to track how long the movie player is running in iOS

I have used MPMoviePlayerController for playing a movie file in one of my application. It is working fine. I have a requirement where I have to track "for how long the movie is being played by the user?". I am using Omniture for that.
I am stuck at knowing the duration of playing time from start
Thanks
You just need to record when the movie starts :
self.movieStartDate = [NSDate date];
and when the movie has finished (or gets stopped), get how long it's been since then
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:self.movieStartDate];
duration will then contain the amount of time since the movie started, in seconds.
But remember that a movie can stop because the app enters the background / becomes inactive so you'll have to listen out for those notifications as well as the ones from the movie player :)

Matt Gallagher's AudioStreamer play mp3 from offset before playing state

I did not found solution for one issue: how to play mp3 file from offset immideately?
I can only play file then send -(void)seekToTime: but in this case sound begins and interrupts then begins from defined offset.
I tried to apply seekToTime method on ASStatusChangedNotification (in different cases of AudioStreamerState) but there were without result.
upd: I think that may set time offset after the file began streaming (before playing). But how?
Thanks.
What I did was create a method to seek to the desired time that I run after [streamer start]:
while(streamer.bitRate == 0) {
sleep(1);
}
If you're concerned about waiting too long, you can add a time out: either a count of times through the loop, or set a start time and compare it to the current time to break out of the loop.
This blog post has another take:
http://www.saygoodnight.com/2009/08/streaming-audio-to-the-iphone-starting-at-an-offset/

recording against a metronome of set length using remote IO

I was able to create the exact functionality I wanted to avaudioplayer and avaudiorecorder but of course experienced latency problems. So after reading pretty much every article on the web and reviewing stacks of sample code, I'm still not sure how to achieve the following:
User chooses to record a sample 2 bars long (4 beats per bar) with a pre-roll/count-in
User clicks record
A metronome starts which counts in 4 beats (accent on the first beat)
The app automatically starts recording on the start of the next bar
The app automatically turns off recording at the end of the 3rd bar (the 2 bars + the pre-roll)
The user can then playback their recording or delete it and start again.
So, with avaudioplayer and avaudiorecorder I simply created a 'caf' using audacity with a metronome set at the correct bpm (bpm is set for the app). I then setup and play the avaudioplayer and using the audiodidfinishsuccessfully delegate method, performed some logic to start the recorder, restart the player, maintain a loop count etc. to turn off recording and audio.
As I mentioned, I was pretty much able to achieve the user experience I am after but the latency problems are not acceptable.
I have been working with audio units and the remote IO and have setup a project with a playback callback and recorder callback etc. but now face the problem of working how to make this work based on the description above. I am trying to work out the following things for starters:
If I create a 1 beat caf file, how could I make use of audio units and remote IO to play x amount of beats and then stop?
How could I do the pre-roll and start the recording callback after 4 beats
Can anyone give me some ideas or point me in the right direction. As I have mentioned, I have already done a stack of research including buying the core audio book, reading every article on atastypixel.com, timbolstad.com etc and trawled through the apple docs.
Thanks in advance for your help.
I start an NSTimer. Use values based on BPM (Beats per Minute) / 60. So if user wants to record a 2 bar file with a count in might do something like this:
//timer interval=100BPM/60secs per minute
timerInterval=100/60;
metroTimer = [NSTimer scheduledTimerWithTimeInterval:timerinterval target:self selector:#selector(blinkMetroLight) userInfo:nil repeats:YES];
- (void)blinkMetroLight
{
if(beatNumber == 0)
{
beatNumber = 1;
}
else if (beatNumber == 5)
{
[self audioProcessorStart];
}
if (beatNumber == 8)
{
[self audioProcessorStop];
[metroTimer invalidate]; metroTimer = nil;
}
beatNumber++
}

Resources