In my app I am using AudioStreamer to play a song through server,
I am refering this tutorial,
http://cocoawithlove.com/2008/09/streaming-and-playing-live-mp3-stream.html
How to play next song Automatically when using AudioStreamer?
In the tutorial is mentioned callback function which is triggered when a song finish playing. Your goal is to write functionality for your list of songs to move on the next one when this function is called.
void MyAudioQueueIsRunningCallback( void * inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void * inData)
{
move to the next song
}
I got answer,
In that tutorial there isplaybackStateChanged:(NSNotification *)aNotification method,
- (void)playbackStateChanged:(NSNotification *)aNotification
{
if ([songStreamer isWaiting])
{
}
if ([songStreamer isPlaying])
{
}
else if ([songStreamer isIdle])
{
[self playnextsong];
}
else if ([songStreamer isPaused])
{
}
}
When song completes through streaming,
It going to idle state.
So in idle state i call a method of playing next song.
And it Runs.
Related
In my app i want to play background audio and video recording both audio and video will be record....
How can i do this functionality???
// Setup cam
-(void)setupDivAvCam
{
self.capturingWindow.delegate = self;
[self.capturingWindow setupWithOptions:#{DIYAVSettingCameraPosition : [NSNumber numberWithInt:AVCaptureDevicePositionBack] }];
[self.capturingWindow setCamMode:DIYAVModeVideo];
}
#pragma mark - Rec video methods Start
-(IBAction)captureVideo:(id)sender
{
[self startCapturingVideo];
}
-(IBAction)stopVideo:(id)sender
{
[self stopCapturingVideo];
}
//To start video recording
-(void)startCapturingVideo
{
{
{
if(![[UIDevice currentDevice].model isEqualToString:#"iPhone Simulator"])
{
//To disable the camera button for some time untill image loads
_cameraButton.userInteractionEnabled = NO;
[self.capturingWindow captureVideoStart];
}
}
}
}
//To stop video recording
-(void)stopCapturingVideo
{
[self.capturingWindow captureVideoStop];
}
The above code is to get the video
I looked in several forums and they all couldn't deliver a satisfying answer.
My wish is to be able to play and record video while playing music at the background. I managed to do that with the help of a snippet I found. here is the code:
I have an app that streams music using AudioStreamer class by Matt Gallagher. This works fine as a background process except I want to be able to skip to the next song once the stream is finished. Unfortunately this part doesn't work.
Initially I had a timer that was monitoring the stream but realized that when the app backgrounds this timer no longer runs. So I tried adding a delegate callback in the packet read function:
void ASReadStreamCallBack(CFReadStreamRef aStream, CFStreamEventType eventType, void* inClientInfo)
{
AudioStreamer* streamer = (AudioStreamer *)inClientInfo;
double percent = [streamer progress]/[streamer duration];
if(percent>=0.98 || (percent>=0.95 && [streamer isIdle])){
if([streamer.delegate respondsToSelector:#selector(didFinishPlayingStream:)] ){
[streamer.delegate didFinishPlayingStream:streamer];
streamer.delegate = nil;
}
}
[streamer handleReadFromStream:aStream eventType:eventType];
}
This works fine when the app is in the foreground but no longer works when the app is backgrounding. The delegate method basically sends a request to get the stream URL for the next song, then once it has it creates a new AudioStreamer class
While the app is in background you can implemente the delegate to handle the different remote control states.
- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
if (player.isPlaying) {
[player pause];
} else {
[player start];
}
break;
case UIEventSubtypeRemoteControlPreviousTrack:
break;
case UIEventSubtypeRemoteControlNextTrack:
[self skipSong:nil];
break;
default:
break;
} }
Something like this works for me.
I've uploaded my AudioPlayer/streamer class inspired in part by Matt Gallagher's AudioStreamer to
https://code.google.com/p/audjustable.
One of the cooler features is its support for gapless playback. This means the AudioQueue is never closed between gaps; keeping iOS from suspending your app.
You can implement AudioPlayerDelegate:didFinishBufferingSourceWithQueueItemId and AudioPlayerDelegate:didFinishPlayingQueueItemId to queue up the next track by calling AudioPlayer:queueDataSource.
Let me know if you need help using it.
I am working on an audio recorder application, it is working perfectly fine.
But I'm stuck with the problem of interruption. When a call comes,
- (void)audioRecorderBeginInterruption:(AVAudioRecorder *)recorder
then this method is called and the recording is paused.
And if the user rejects the call:
- (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder
Then here I want to resume the recording from the point where it was interrupted.
But when I call the record method again, the recording starts with a new file.
The problem is solved!
I have re-written the recording code to avoid this problem. I used AudioQueues, basically the backend code is the same of SpeakHere application with some minor changes. Provided two more apis in it:
-(void)resume
{
AudioQueueStart(queueObject, NULL);
}
-(void)pause
{
AudioQueuePause(queueObject);
}
In AudioRecorder class. The basic purpose being to avoid the recording setup which is done in record method.
Setup the interrupt callback and then use this pause and resume methods appropriately in the callback. Also take care to set active the audio session based on whether your application needs it or not.
Hope this helps someone out there.
EDIT:
Audio interrupt listener callback:
void interruptionListenerCallback (void *inUserData, UInt32 interruptionState)
{
if (interruptionState == kAudioSessionBeginInterruption)
{
[self.audioRecorder pause];
}
else if (interruptionState == kAudioSessionEndInterruption)
{
// if the interruption was removed, and the app had been recording, resume recording
[self.audioRecorder resume];
}
}
Listening for audio interruption:
AudioSessionInitialize(NULL, NULL, interruptionListenerCallback, self);
The OS is probably stopping the AVAudioRecorder during the interruption. You can either present the two or more files as a single recording to the user, or you can use AudioQueue to write your code for handling interruptions (as well as saving audio data to a file).
I tried to do this a while ago and came to the conclusion that it couldn't be done properly; the operating system itself won't let you do it. Maybe that's changed in 3.1.2, but when I tried in 3.0 it just wouldn't work.
To handle the interruption, you have to use AVAudioSessionDelegate methodes instead of AVAudioRecorderDelegate methods.This is the code sample for handling interruption:
/*=================================================================
Interruption Handling Method during Recording
==================================================================*/
- (void) beginInterruption
{
if(self.recorder)
{
//Method to handle UI
}
}
- (void) endInterruption
{
NSError *err = noErr;
[[AVAudioSession sharedInstance] setActive: YES error: &err];
if(err != noErr)
{
NSLog([err description]);
}
//method to handle UI
}
First method automatically deactivate the audio session.So,in second method,you have to reactivate the audio session.First method will pause the recording and when interruption ends you can resume with second method.I have tried this on version 3.0 and upper version.
I'm trying to display an image while a sound is playing. I can get it to appear, but I'm having trouble making it disappear once the sound has finished playing.
My code:
-(IBAction)guitarChord:(id)sender
{
if (theAudio.playing == YES) {
theAudio.stop;
theAnimation.stop;
} else {
theAudio.play;
theAnimation.play;
}
}
I'm using AVAudioPlayer.
Any ideas what I am doing wrong?
How do I detect a sound has stopped?
Briefly, you need to take a look at AVAudioPlayerDelegate and audioPlayerDidFinishPlaying.
I am developing an audio streamer and have declared an interruption listener to save state of a song when an interruption occurs - like an incoming call or an sms.
Here is the relevant code
In my AppDelegate, I have this
AudioSessionInitialize (NULL, NULL, interruptionListenerCallback, self);
AudioSessionSetActive(YES);
This is what the interruption listener looks like
void interruptionListenerCallback (void *inUserData, UInt32 interruptionState) {
// This callback, being outside the implementation block, needs a reference
//to the AudioPlayer object
MyPlayer *player = (MyPlayer *)inUserData;
if (interruptionState == kAudioSessionBeginInterruption) {
if ([player audioStreamer]) {
// if currently playing, pause
[player pausePlayback];
player.interruptedOnPlayback = YES;
}
} else if ((interruptionState == kAudioSessionEndInterruption) && player.interruptedOnPlayback) {
// if the interruption was removed, and the app had been playing, resume playback
[player resumePlayback];
player.interruptedOnPlayback = NO;
}
}
When I get a phone call the interruption listener is called and if the user declines the call the playback resume method is also called. But before the resumePlayback method is called, I get this error in the console for AudioQueueEnqueueBuffer
error: tca! error int: 560030580
Does anyone have an idea of how to correctly handle audio interruptions when streaming audio files.
Thanks.
This link shows what the problem is. Might help someone.
https://devforums.apple.com/message/31758#31758
!act is kAudioSessionNotActiveError, declared in AudioServices.h, with the comment
"The operation failed because the AudioSession is not active. Calling AudioSessionSetActive(true) first will fix this error in most cases."
You also get this error when you call AudioQueueStart() after an interruption (as I found out today).
It looks to me like you are setting inUserData as your appDelegate instead of your player.