I am using AVPlayer to play long audio mp3 stream music (8 minutes), short musics (1 to 3 minutes) plays perfectly, but with these bigger musics the music starts playing, but after play some random minutes (between 2 and 3:20) the player starts the track again from the beginning. Although the player restart the music, the status information (duration and current time) keeps counting normally, without restart, just the audio restarts. Someone has an idea?
The file I am playing is this: http://storage-new.newjamendo.com/download/track/57864/mp31/
The player code:
AVAudioSession *mySession = [AVAudioSession sharedInstance];
// Assign the Playback category to the audio session.
NSError *audioSessionError = nil;
[mySession setCategory: AVAudioSessionCategoryPlayback
error: &audioSessionError];
if (audioSessionError != nil) {
NSLog (#"Error setting audio session category.");
return;
}
// Activate the audio session
[mySession setActive: YES
error: &audioSessionError];
if (audioSessionError != nil) {
NSLog (#"Error activating audio session during initial setup.");
return;
}
player = [AVPlayer playerWithURL:[NSURL URLWithString:url]];
[player play];
And here is how I track the information about the current time, that keeps counting normally.
AVPlayerItem *item = player.currentItem;
CMTime duration = [item duration];
CMTime currentTime = [item currentTime];
Seems that the problem is that the mp3 file I was streaming was a mpeg-1 and the Apple documentation says that I have to use mpeg-2, so I have just changed to the correct version, and the error is not happening again.
I have managed to fix this problem, it would appear (for me) that the server was sending the file as one block.
I don't know the ins and outs but the stream is now provided as a "ranged" stream (it is provided in segments I am told). Not only did this solve the problem but such things below started to work for me (as apposed to providing NaN).
float duration = CMTimeGetSeconds(self.avQueuePlayer.currentItem.duration);
I hope this helps, I am not being told much about what was changed on the server. Strangly my URL links worked on just about all other devices but I got this problem when playing from my App AND Safari.
Related
I am downloading an MP3 file using NSURLConnection and I save the data to a file using NSFileHandle. Whenever a certain percentage of the file is downloaded (all the files are roughly the same size), I will start playing the MP3 file.
I thought that I could use the AVPlayer to do this but it doesn't work on a device - only in simulator.
I do the following:
if (self.player.rate == 0.0f && percentage > kMinimumDownloadPercentage)
{
NSError *error;
self.player = [AVPlayer playerWithURL:[[NSURL alloc] initFileURLWithPath:localPath]];
if (!error)
[self.player play];
else
NSLog(#"%#", error);
}
This works in simulator but not on device. No error is given. It does work if I do the following, though:
self.player = [AVPlayer playerWithURL:url];
Where url is the remote URL to the MP3 file.
Does anyone know why I can't play the local file using AVPlayer?
This turned out to be an error due to the way the file was saved.
-playerWithURL: in AVPlayer works perfectly fine.
I have an App that does the pretty standard operation:
It plays audio (streamed or in filesystem) when the app is in 1) Foreground mode, 2) Screen locked state 3)Background mode.
This was working fine in all iOS prior to iOS5.
I have been using MPMoviePlayerController (Because it can play streamed and local file system audio)
I have the following setup:
info.plist has Background Mode set to "Audio"
I have Audiosession setup as shown at http://developer.apple.com/library/ios/#qa/qa1668/_index.html
NSError *activationError = nil;
AVAudioSession *mySession = [AVAudioSession sharedInstance];
[mySession setCategory: AVAudioSessionCategoryPlayback error: &activationError];
if (activationError) { /* handle the error condition */ }
[mySession setActive: YES error: &activationError];
if (activationError) { /* handle the error condition */ }
I have background timer enabled that gets stopped at the end of audio playback
UIBackgroundTaskIdentifier newId = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:NULL];
I have the Moveplayer's useApplicationAudioSession = NO
I have subscribed to the following events to detect and handle various playback state and to start a new audio file at the end of current file.
MPMoviePlayerLoadStateDidChangeNotification
MPMoviePlayerPlaybackDidFinishNotification
MPMoviePlayerPlaybackStateDidChangeNotification
MPMoviePlayerNowPlayingMovieDidChangeNotification
Problem:
With this the audio starts to play and when the application is put to background state or if the phone is locked, the audio continues to play. But, after when I start another audio file,
I start getting PlaybackDidFinishNotification immediately with the state set to Playback ended (But the file was never played)
The same code plays audio files in foreground mode (After the current audio file ends, the next file is started without any problem)
Is there anything new in iOS5 I should be doing to get this to work? I read through the MPMoviePlayerController class reference and I couldn't see anything specific for iOS5.
Thanks in advance.
Finally figured out the issue. This is solved in this post in apple dev forums (needs login to see). That post was applicable to AVPlayer but also fixes the problem with MPMoviePlayerController as well.
Basically, this is an excerpt from that post:
your app must support remote control events! These are the audio
controller interface prex/nex/play/pause on the left of the multitask
switcher taskbar (not sure about the proper name of the thing). You
to this ensuring your view becomes First Controller and then calling
> [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
in viewDidLoad. Once you do this, your Player will no longer return
NO!!
My situation was different and I'm only answering here (and in the other SO question) to help future searchers on this error message. This does not answer the original question.
My app plays a sound OR a song but when I first coded it could play both. And in testing I always tested with a song. I played the song in the usual way:
self.musicQuery = [MPMediaQuery songsQuery];
[_musicQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:selectedSongID forProperty:MPMediaItemPropertyPersistentID comparisonType:MPMediaPredicateComparisonEqualTo]];
[_musicQuery setGroupingType:MPMediaGroupingTitle];
[_myPlayer setQueueWithQuery:_musicQuery];
[_myPlayer play];
Weeks passed and I started testing with the sound, played with AVAudioPlayer. My app started freezing for 5 seconds and I'd get the MediaPlayer: Message playbackState timed out message in the Console.
It turns out that passing a query that was empty was causing the freeze and the message. Changing my app's logic to only play a song when there was a song to play fixed it.
I need to record video from the iPhone camera, and play an MP3 file at the same time.
I started with AVCam sample code, which I'm sure you all have. It works great for recording video.
However, I then added the following code to play an MP3. This MP3-playing code works in a different app of mine, but when I insert it into this sample code the MP3 not only does not play, the AVCamCaptureManager's recordingDidFinishToOutputFileURL never gets called, so the video never gets saved out.
It's like the audio playing code conflicts with the video capture code. Any ideas?
Here's the audio playing code I put into AVCam:
AVAudioPlayer *audioPlayer = nil;
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/soundeffect.mp3", [[NSBundle mainBundle] resourcePath]]];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[audioPlayer setVolume:1.0];
[audioPlayer prepareToPlay];
[m_audioPlayer play];
Pretty simple code here. Not sure why this audio playing code causes recordingDidFinishToOutputFileURL to never get called...
Thanks for any ideas.
I figured it out: I just had to remove some code within AVCam that allocated AVCaptureDeviceInput - audioInput. That was unnecessary and conflicted with my audio playback code.
I am trying to play 6 seperate .mp3 sound files using instances of AVAudioPlayer.
The sounds are playing at the same time but they seem to be playing out of sync or
at slightly different speeds. Does anyone know why this may be?
Here is how I initialize a sound:
NSURL *musicurl = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource: #"SoundLoop" ofType: #"mp3"]];
music = [[AVAudioPlayer alloc] initWithContentsOfURL: musicurl error: nil];
[musicurl release];
music.numberOfLoops = -1; // Loop indefinately
music.currentTime = 0; // start at beginning
music.volume = 1.0;
music.meteringEnabled = YES;
and here is my AudioSession code:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
audioSession.delegate = self;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setPreferredHardwareSampleRate:44100 error:nil];
[[AVAudioSession sharedInstance] setPreferredIOBufferDuration:30 error:nil];
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
Float32 hardvol = 1.0;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
AudioSessionSetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume, sizeof(hardvol), &hardvol);
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
[[AVAudioSession sharedInstance] setActive:YES error: nil];
Could it possibly have anything to do with the bit rates of the sounds? or that I am using .mp3?
Thanks.
I found the solution to this problem by using the playAtTime: method of the AVAudioPlayer class:
NSTimeInterval shortStartDelay = 0.5; // seconds
NSTimeInterval now = player.deviceCurrentTime;
[player playAtTime:now + shortStartDelay]; //these players are instances of AVAudioPlayer
[player2 playAtTime:now + shortStartDelay];
[player3 playAtTime:now + shortStartDelay];
Using this will allow all the sounds to play asynchronously and in sync.
You should check out the MultiMedia Programming Guide. The "Using Audio" section has tons of helpful information.
http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/Introduction/Introduction.html
This sounds like it relates to your issue:
When using hardware-assisted decoding,
the device can play only a single
instance of one of the supported
formats at a time. For example, if you
are playing a stereo MP3 sound using
the hardware codec, a second
simultaneous MP3 sound will use
software decoding. Similarly, you
cannot simultaneously play an AAC and
an ALAC sound using hardware. If the
iPod application is playing an AAC or
MP3 sound in the background, it has
claimed the hardware codec; your
application then plays AAC, ALAC, and
MP3 audio using software decoding.
To play multiple sounds with best
performance, or to efficiently play
sounds while the iPod is playing in
the background, use linear PCM
(uncompressed) or IMA4 (compressed)
audio.
Here's another bit that claims what you are doing should be possible but it seems like Apple is throwing in a caveat with "the most processor-efficient multiple playback" line. I would think that if the processor is strained that would lend itself to not keeping things perfectly in time.
Starting in iOS 3.0, nearly all
supported audio formats can be used
for simultaneous playback—namely, all
those that can be played using
software decoding, as described in
Table 1-1. For the most
processor-efficient multiple playback,
use linear PCM (uncompressed) or IMA4
(compressed) audio.
In terms of debugging, you should start with two audio sounds and see if there is an issue. Then work your way up to the 6 and figure out if there is a distinct point at which the problem starts to occur. I would also find (or make) some audio tracks in the formats that Apple recommends (PCM or IMA4) and do the same testing with those. Doing these two things should help you narrow down what the actual problem is.
We have a volume slider on the audio player in our iphone app. It streams music from our server. All is well initially until the point that some background operation happens on the iPhone.
Eg: The Mail app downloads new mails in the background and that makes a little audio sound
or
I receive a new SMS and that gives a little sound alert.
In such cases, the volume of our music player increases or decreases abruptly. The slider stays where it is, but the volume pitch changes. The only way to get where it was before is pause and play again and then the volume re-adjusts.
Any idea how to solve this issue?
Thank you in advance
Swap
Sounds like a classic Audio Session Category issue.
Check the Audio Session Programming Guide on Configuring your Audio Session.
Specifically, try to setup your application audio session towards AVAudioSessionCategoryPlayback.
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryPlayback
error: &setCategoryError];
if (setCategoryError) { /* handle the error condition */ }