iOS - Create an NSURL from an NSFileHandle or NSPipe - ios

I am receiving a stream of encoded audio over the network, but there is a bunch of data mixed in so I need to receive the packets, strip out the audio then play the audio.
AVAudioPlayer, which may or may not be the best tool for this but it's the path I'm currently chasing, wants data from NSData or NSURL. NSData won't work because it is a stream of data and I want it to start as soon as it arrives and continue playing. My thought was:
NSPipe *pipe = [[NSPipe alloc] init];
NSFileHandle *writeHandle = [pipe fileHandleForWriting];
NSFileHandle *readHandle = [pipe fileHandleForReading];
// in network reception thread...
NSData *audioData = [packet getAudioData];
[writeHandle writeData:audioData];
// in audio thread...
NSURL *url = [[NSURL alloc] init];
[url setResourceValue:NSURLFileResourceTypeNamedPipe
forKey:NSURLFileResourceTypeKey
error:&error];
// Connect the readHandle
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
However, I don't know how to pass the `readHandle` into the URL. How do I create an NSURL from an existing NSFileHandle? Is there some better approach for this entirely? Is there a way to write data into something that can become an NSURL?
The only real requirement is that I can play the audio as near real time as possible. I don't want to queue up data for even a tenth of a second before it gets played.

It is not possible to retrieve an NSFileHandle's URL because not all handles have a corresponding URL. Your example would appear to be one such example.

Related

How to play array of words or NSString using AVAudioPlayer?

I have Array of words which i want to pick one after the other and play using AVAudioPlayer, how can i achieve playing NSString using AVAudioPlayer?
I don't have the audio file and i have list of words to which i want to play each word using AVAudioPlayer programming .
i found to play the audio file using AVAudioPlayer but not able to find to play NSSting or word in AVAudioPlayer
Below is the code using to play the audio clips :
NSString *path = [NSString stringWithFormat:#"%#/audio.mp3", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath:path];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
You need to create an AVSpeechUtterance object using the words that you want the device to "speak," and then pass that object to AVSpeechSynthesizer. Those classes provide the methods you need to control the speech; there's no need to use AVAudioPlayer.

I am trying to play audio from server using AVAudioPlayer, but file not Playing

i am trying to make an online audio player. but i can't paly audio using AVAudioPlayer object. Please Help Me. Thanks in Advance.
Here is my audio player code.
================>>
NSURL *url =[[NSURL alloc] initWithString:#"My Url"];
xPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
xPlayer.numberOfLoops = 0;
xPlayer.volume = 1.0f;
[xPlayer prepareToPlay];
[xPlayer play];
Q: Does the AVAudioPlayer provide support for streaming audio content?
A: The AVAudioPlayer class does not provide support for streaming audio based on HTTP URL's. The URL used with initWithContentsOfURL: must be a File URL (file://). That is, a local path.
Source: https://developer.apple.com/library/ios/qa/qa1634/_index.html

How to play a radio station on button press in iOS

I want to play a radio station when someone presses the play radio button. However, it does not work.
Here is my code:
NSURL *url = [NSURL URLWithString:#"http://www.radio.net.pk/"];
NSData *data = [NSData dataWithContentsOfURL:url];
AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithData:data error:nil];
[audio play];
The AVAudioPlayer class only lets you play sound in any audio format available in iOS and OS X
This means, the AVAudioPlayer class does not provide support for streaming audio based on HTTP URL's. The URL used with initWithContentsOfURL: must be a local path URL.
So you should save the NSData locally (with different chunks) and play it using AVAudioPlayer.
It won't work ever.
Does radio.net.pk offers any APIs?
datWithContentsOfURL will return HTML string that you are trying to play using AVAudioPlayer !!. Please go through the website again and check for any developer API.
// Using this Cannel
NSURL *url6 = [NSURL URLWithString:#"http://sc6.spacialnet.com:35464/"]
layerItem = [AVPlayerItem playerItemWithURL:_strTemp]; // add url to playerItem
player = [AVPlayer playerWithPlayerItem:playerItem]; // add player item to AVAudioPlayer
player = [AVPlayer playerWithURL:_strTemp]

How to play 'http:/....... /mp3' with AVAudioPlayer

I can't play mp3 audio file.
URL_PATH = #"http://...../.…./A1.mp3";
NSError *error;
player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:URL_PATH] error:&error];
if (error)
{
NSLog(#"error:%#",error.localizedDescription);
}
if (player ==nil)
{
NSLog(#"nil");
}
else
{
NSLog(#"playing");
[player play];
}
error code :
error:The operation couldn’t be completed. (OSStatus error -43.)
nil
How can I do?
Please tell me hint. pre-Thanks!
You are using the wrong player to play audio captured from a network stream. See Apple's documentation on AVAudioPlayer:
Apple recommends that you use this class for audio playback unless you
are playing audio captured from a network stream or require very low
I/O latency. For an overview of audio technologies, see Audio & Video
Starting Point and “Using Audio” in Multimedia Programming Guide.
One work around way to use AVAudioPlayer is to fetch the audio's data and put it in a NSData. Then you can init your AVAudioPlayer by initWithData:error:. Also, don't put the code in your main queue. Else it will block your user interface from reacting to user's input.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *mp3URL = [NSURL URLWithString:#"http://zhangmenshiting.baidu.com/data2/music/44799433/4479927746800128.mp3?xcode=dbff90a141d5d136fdc7275fdc3fae126077a44adc974ad8"];
NSData *data = [NSData dataWithContentsOfURL:mp3URL];
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:NULL];
[self.audioPlayer play];
});
sunkehappy is right, AVAudioPlayer isn't meant for streaming audio. It is meant for playing audio files and for data that is already in memory. That's why you need to init it with the data and not with the URL.
Here's the apple answer (which you can find here http://developer.apple.com/library/ios/#qa/qa1634/_index.html ):
The AVAudioPlayer class does not provide support for streaming audio
based on HTTP URL's. The URL used with initWithContentsOfURL: must be
a File URL (file://). That is, a local path.
If you look for an audio streamer, you can test that audio streamer.

How can I stream audio and also be able to control volume on iOS?

I've developed an iOS app that plays two separate audio streams simultaneously. To do this I am using AVPlayer thus:
//Use URL to set up the speech radio player.
NSURL *urlStreamSpeech = [NSURL URLWithString:self.urlAddressSpeech];
playerSpeech = [AVPlayer playerWithURL:urlStreamSpeech];
//Use URL to set up the music player.
NSURL *urlStreamMusic = [NSURL URLWithString:self.urlAddressMusic];
playerMusic = [AVPlayer playerWithURL:urlStreamMusic];
I am now trying to implement a volume control so that the user will be able to control the volume for the audio streams individually. As I've tried this I have come to the conclusion that there is no volume property for the AVPlayer class. I also looked at the AVAudioPlayer class, but from what I gather that class is only able to play local audio files, not streamed audio.
So my question is: how can I control the volume of streamed audio on iOS?
NSString* resourcePath = url; //your url
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:resourcePath]];
NSError *error;
app.audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
app.audioPlayer.numberOfLoops = 0;
app.audioPlayer.volume = 1.0f;
[app.audioPlayer prepareToPlay];
if (app.audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[app.audioPlayer play];
Look into the AVPlayer class, part of the AVFoundation framework... this is the objective-c (iOS) class you use for streaming audio.
look at this post Live streaming
MPMusicPlayerController* musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
[musicPlayer setVolume:[SliderVolumen value]];
Only work in the device, no simulator.
Compatible with AVPlayer.

Resources