iphone audio streaming - iphone

i'm developing an application which uses audio streaming. For streaming audio from internet i'm using the AudioStreamer class. The audio streamer has
four state isPlaying, isPaused ,isWaiting, and isIdle . My problem is that when the audio streamer is in the state "isWaiting" and at that time if i get a phone call Audio queue fails giving the error "Audio queue start failed." Any has solution for this? help....

An interruption - such as receiving a call - will deactivate the Audio Session. It's up to you to, in your interruption handler, re-activate the Audio Session by calling AudioSessionSetActive(true).
Look here for details of the interruption handler.
Having said that, I'll assume that you're using mattgallagher's library. The thing to do is put a breakpoint in AudioStreamer.m on line 949 (the line after "err = AudioQueueStart(audioQueue, NULL);" in -[AudioStreamer pause].
If err == kAudioSessionNotActiveError then my theory's right, and you need to call restart the audio session. Perhaps something like this (but I've only only ever glanced through this code so perhaps there's a better way of solving the problem):
else if (state == AS_PAUSED)
{
err = AudioQueueStart(audioQueue, NULL);
if (err) {
err = AudioSessionSetActive(true);
if (err) {
[self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
return;
} else {
err = AudioQueueStart(audioQueue, NULL);
if (err) {
[self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
return;
}
}
}
}

Related

CameraController not starting video recording instantly Flutter

I am trying to play a beep sound with vibration before starting video recording. However, there is a delay for _cameraController.startVideoRecording()
to start video recording and this delay is not constant. Each time I try recording the delay is different.
How can I do this in a way that recording starts instantly after the beep sound finishes.
my code:
Future _handleRecording() async {
try {
await _audioCache.play(_soundPath);
Vibration.vibrate(duration: 350);
await _cameraController.startVideoRecording();
} catch (e) {
throw (e);
}
}
I am using camera: ^0.8.1+7 dependency the CameraController class.
The problem here is you are calling the startVideoRecording after initiating the play function
You have two options since your audio duration is fixed :
First one is to surround you startVideoRecording with delay like that:
Future.delay(Duration(seconds:"You audio time"),(){
await _cameraController.startVideoRecording();
} catch (e) {
throw (e);
}
});
and the second one is to check when play finish then call startVideoRecording

Can't stop audio playback on iOS with Codename One

My Codename One app features audio playback in the background when the user taps the screen. The audio I use is an mp3. Here is how I use the Media playback :
public static void playSound(boolean stop) {
sound.reset(); // The input stream needs to go back to the beginning
Media myClip = MediaManager.createMedia(sound, "audio/mp3", () -> {
// If there is no order to stop playback, we keep playing when it has completed (looping)
playSound(false);
});
if (!stop) {
myClip.play();
} else {
myClip.cleanup();
}
}
So hen the user taps the screen components change and I pass true to playSound method. On Android the current playback stops not on iOS with an iPhone 4.
Please note that when the app gets minimized (center button pressed) the playback stops (even if I don't call cleanup() on the Media which I do on Android to stop the playback when the app is minimized).
How can I stop the playback on iPhone ?
Any help appreciated,
#Shai pointed me to the right direction so here is the code finally used :
Media myClip = null;
public static void playSound(boolean stop) {
sound.reset(); // The input stream needs to go back to the beginning
/**
* If the media is playing we don't create it
* otherwise we would have several media in the wild
* that could not be stopped
*/
if (myClip == null || !myClip.isPlaying()) {
myClip = MediaManager.createMedia(sound, "audio/mp3", () -> {
// If there is no order to stop playback, we keep playing when it has completed (looping)
playSound(false);
});
}
if (!stop) {
myClip.play();
} else {
myClip.cleanup();
}
}

html5 audio tag playing audio when it is load audio

i have html5 audio player like play, pause, stop buttons.
function onUpdate()
{
var isPlaying = (!getAudioElement().paused);
document.getElementById("playerplay").style.display = (isPlaying)?"none":"block";
document.getElementById("playerpause").style.display = (isPlaying)?"block":"none";
};
function getAudioElement()
{
return document.getElementById("id_audio_element");
}
function play() {
getAudioElement().play();
onUpdate();
}
function pause() {
getAudioElement().pause();
onUpdate();
}
function stop() {
getAudioElement().pause();
getAudioElement().currentTime=0;
onUpdate();
getAudioElement().load();
}
And audio tag:
<audio id="id_audio_element" onended="onUpdate();load();"><source src="105.ogg" type="audio/ogg"></audio>
it works all on browsers perfectly, exept iPhone and iPad's Safari and Chrome. When I call load() , audio starts playing, although I don't call play().
Anybody has a solution? Thanks!
If the source is not changing, there is no need to call load(). If it is changing, try calling pause() after it loads.

Why might my AudioQueueOutputCallback not be called?

I'm using the Audio Queue Services API to play audio streamed from a server over a TCP socket connection on an iPhone. I can play the buffers that were filled from the socket connection, I just cannot seem to make my AudioQueue call my AudioQueueOutputCallback function, and I'm out of ideas.
High level design
Data is passed to the player from the socket connection, and written
immediately into circular buffers in memory.
As AudioQueueBuffers become available, data is copied from the circular buffers into the
available AudioQueueBuffer, which is immediately re-queued. (Or would be, if my callback happened)
What happens
The buffers are all filled and enqueued successfully, and I hear the audio stream clearly. For testing, I use a large number of buffers (15) and all of them play through seamlessly, but the AudioQueueOutputCallback is never called, so I never re-queue any of those buffers, despite the fact that everything seems to be working perfectly. If I don't wait for my callback, assuming it will never be called, and instead drive the enqueueing of buffers based on the data as it is written, I can play the audio stream indefinitely, reusing and re-enqueueing buffers as if they had been explicitly returned to me by the callback. It is that fact: that I can play the stream perfectly while reusing buffers as needed, that confuses me the most. Why isn't the callback being called?
Possibly Relevant Code
The format of the stream is 16 bit linear PCM, 8 kHz, Mono:
_streamDescription.mSampleRate = 8000.0f;
_streamDescription.mFormatID = kAudioFormatLinearPCM;
_streamDescription.mBytesPerPacket = 2;
_streamDescription.mFramesPerPacket = 1;
_streamDescription.mBytesPerFrame = sizeof(AudioSampleType);
_streamDescription.mChannelsPerFrame = 1;
_streamDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType)
_streamDescription.mReserved = 0;
_streamDescription.mFormatFlags = (kLinearPCMFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsPacked);
My prototype and implementation of the callback are as follows. Nothing fancy, and pretty much identical to every example I've seen so far:
// Prototype, declared above the class's #implementation
void AQBufferCallback(void* inUserData, AudioQueueRef inAudioQueue, AudioQueueBufferRef inAudioQueueBuffer);
// Definition at the bottom of the file.
void AQBufferCallback(void* inUserData, AudioQueueRef inAudioQueue, AudioQueueBufferRef inAudioQueueBuffer) {
printf("callback\n");
[(MyAudioPlayer *)inUserData audioQueue:inAudioQueue didAquireBufferForReuse:inAudioQueueBuffer];
}
I create the AudioQueue like this:
OSStatus status = 0;
status = AudioQueueNewOutput(&_streamDescription,
AQBufferCallback, // <-- Doesn't work...
self,
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&_audioQueue);
if (status) {
// This is not called...
NSLog(#"Error creating new audio output queue: %#", [MyAudioPlayer stringForOSStatus:status]);
return;
}
And I enqueue buffers like this. At this point, it is known that the local buffer contains the correct amount of data for copying:
memcpy(aqBuffer->mAudioData, localBuffer, kAQBufferSize);
aqBuffer->mAudioDataByteSize = kAQBufferSize;
OSStatus status = AudioQueueEnqueueBuffer(_audioQueue, aqBuffer, 0, NULL);
if (status) {
// This is also not called.
NSLog(#"Error enqueueing buffer %#", [MyAudioPlayer stringForOSStatus:status]);
}
Please save me.
Is this executed on the main thread or a background thread? probably not good if CFRunLoopGetCurrent() returns a run loop of a thread that could disappear (thread pool etc) or is a run loop that don't care about kCFRunLoopCommonModes.
Try to change CFRunLoopGetCurrent() to CFRunLoopGetMain() or make sure AudioQueueNewOutput() and CFRunLoopGetCurrent() is executed on the main thread or a thread that you have control over and has a proper run loop.
Try changing self for (void*)self. Like this:
status = AudioQueueNewOutput(&_streamDescription,
AQBufferCallback,
(void*)self,
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&_audioQueue);

how to run vibrate continuously in iphone?

In my application I'm using following coding pattern to vibrate my iPhone device
Include: AudioToolbox framework
Header File:
#import "AudioToolbox/AudioServices.h"
Code:
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
My problem is that when I run my application it gets vibrate but only for second but I want that it will vibrate continuously until I will stop it.
How could it be possible?
Thankfully, it's not possible to change the duration of the vibration. The only way to trigger the vibration is to play the kSystemSoundID_Vibrate as you have. If you really want to though, what you can do is to repeat the vibration indefinitely, resulting in a pulsing vibration effect instead of a long continuous one. To do this, you need to register a callback function that will get called when the vibration sound that you play is complete:
AudioServicesAddSystemSoundCompletion (
kSystemSoundID_Vibrate,
NULL,
NULL,
MyAudioServicesSystemSoundCompletionProc,
NULL
);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Then you define your callback function to replay the vibrate sound again:
#pragma mark AudioService callback function prototypes
void MyAudioServicesSystemSoundCompletionProc (
SystemSoundID ssID,
void *clientData
);
#pragma mark AudioService callback function implementation
// Callback that gets called after we finish buzzing, so we
// can buzz a second time.
void MyAudioServicesSystemSoundCompletionProc (
SystemSoundID ssID,
void *clientData
) {
if (iShouldKeepBuzzing) { // Your logic here...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
} else {
//Unregister, so we don't get called again...
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
}
}
There are numerous examples that show how to do this with a private CoreTelephony call: _CTServerConnectionSetVibratorState, but it's really not a sensible course of action since your app will get rejected for abusing the vibrate feature like that. Just don't do it.
Read the Apple Human Interaction Guidelines for iPhone. I believe this is not approved behavior in an app.
iOS 5 has implemented Custom Vibrations mode. So in some cases variable vibration is acceptable. The only thing is unknown what library deals with that (pretty sure not CoreTelephony) and if it is open for developers. So keep on searching.
The above answers are good and you can do it in a simple way also.
You can use the recursive method calls.
func vibrateTheDeviceContinuously() throws {
// Added concurrent queue for next & Vibrate device
DispatchQueue.global(qos: .utility).async {
//Vibrate the device
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
self.incrementalCount += 1
usleep(800000) // if you don't want pause in between, remove this line.
do {
if let isKeepBuzzing = self.iShouldKeepBuzzing , isKeepBuzzing == true {
try self.vibrateTheDeviceContinuously()
}
else {
return
}
} catch {
//Exception handle
print("exception")
}
}
}
To stop the device vibration use the following line.
self.iShouldKeepBuzzing = false
ios swift