AVAudioPlayer in not playing file from url? - ios4

I am trying to play a recorded file in AVAudioPlayer.
It plays my Local recording fine but when I try to play the same file stored on server with a valid url it doesn't play any sound..?
I tried
NSURL *url = [NSURL URLWithString:self.filePathUrl];
NSData *memoData = [NSData dataWithContentsOfURL:url];
newPlayer = [[AVAudioPlayer alloc] initWithData:memoData error:nil];//[[AVAudioPlayer alloc] initWithContentsOfURL:url error: nil];
This is not working..
I am not understanding what happen while getting data from url. I am getting my data too. its length is not 0. and the file format on server is .caf only. Please help me to understand the issue.
Thanks.

You have to start the audioplayer
[newPlayer play];

The AVAudioPlayer can only play local files. See the Apple Developer page on AVAudioPlayer streaming support.
You could use Miguel's streaming audio player that uses an AudioQueue but I don't think you can seek or scrub the audio.
Hope this helps.

Related

SpriteKit - How to stop a sound when enemy is killed

I'm building my first project with SpriteKit, but I can't figure out this part.
My project includes enemy helicopters flying into the screen. Each enemy plays a sound file around 14 seconds long. It's not a loop. It includes the sound of the enemy approaching before it enters the screen and more sound fx while it moves across the screen. The problem is that when I kill one of this helicopters, the sound keeps playing even after the enemy helicopter node has been removed from the scene.
I tried using the playSoundFileNamed action but I know those can't be stopped.
I tried using SoundManager but since all the enemies have the same file id, if I stop one, it stops all of them, even the ones still on the screen.
I read I should use OpenAL but I can't find a source that explains how can I add some kind of ID to each sound playing to know which one to stop.
Same with AVAudioPlayer. I tried creating a player for each enemy but for some reason the runBlock SKAction just ignores this code and never plays the sound. Weird. I also read AVAudioPlayer is better for playing background music than with handling sound FX.
Is there some kind of sound engine that helps with this issue?
I was able to solve it keeping all the audio players in an array. Here's the code:
First you create a NSMutableArray to keep track off all the players (called it 'playerArray'). Then each SKSpriteNode gets it's own player when they're added to the scene:
NSError *error;
NSURL * backgroundSound = [[NSBundle mainBundle] URLForResource:#"coptersound" withExtension:#"mp3"];
AVAudioPlayer *copterPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundSound error:&error];
copterPlayer.numberOfLoops = 1;
copterPlayer.delegate = self;
[copterPlayer prepareToPlay];
SKAction *moveCopter = [SKAction moveToX:(-10 - enemy.size.width) duration:14];
SKAction *copterSound = [SKAction runBlock:^{
[playerArray addObject:copterPlayer];
[copterPlayer play];
[enemy.userData setValue:copterPlayer forKeyPath:#"player"];
}];
SKAction *moveGroup = [SKAction group:#[copterSound, moveCopter]];
Then when collision is detected, this is how I stop the player:
[[enemy.userData objectForKey:#"player"] stop];
[playerArray removeObject:[enemy.userData objectForKey:#"player"]];
Need to pause all the players? Do this:
for(AVAudioPlayer *a in playerArray) {
[a pause];
}
And don't forget to remove all the players that have finished playing from the array using this:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[playerArray removeObject:player];
}
Not sure if it's the best way but it works perfectly. Still open for better suggestions since it's my first time working with SpriteKit.
playSoundWithFile can be stopped, add a child SKNode to your helicopter, play the sound on your child, then just pause the child

Small delay when playing a sound for the first time with SpriteKit

When I play a sound using [self playSoundFileNamed], there is a small delay the first time a sound is played where the whole app freezes for about half of a second, but after that it's fine. How can I get rid of this?
In my game setup method, I do something like this and it seems to work well.
Have an iVar
SKAction *_ballsHitSound;
Set it up when load the scene
_ballsHitSound = [SKAction playSoundFileNamed:#"ballsCollide.mp3" waitForCompletion:NO];
then the sound is ready to go
[self runAction:_ballsHitSound];
The playSoundFileNamed: action is made to play small sounds, like sound effects of your game, not background music or such bigger sound files. If you plan to play bigger sound files you better use AVAudioPlayer class, that gives you more control over the sound reproduction.
Here's a code snippet of how to use it:
// Load and start background music
NSError *error;
NSURL * backgroundMusicURL = [[NSBundle mainBundle] URLForResource:#"background-music" withExtension:#"mp3"];
self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
self.backgroundMusicPlayer.numberOfLoops = -1;
[self.backgroundMusicPlayer prepareToPlay];
[self.backgroundMusicPlayer play];
I think that you don't have to play your sounds on the main thread so I would try to play it on the background thread.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
// Play it here
});

Trouble in playing video from URL in iPhone using MPMoviePlayerController

I am trying to play a video through a link in my app. The code goes here
NSURL *videoURL = [NSURL URLWithString:viewURL];
NSLog(#"Filepath is: %#", viewURL);
MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playbackFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:movie];
movie.view.frame = CGRectMake(0.0f, 50.0f, 320.0f, 320.0f);
movie.fullscreen = YES;
[self.view addSubview:movie.view];
[movie play];
This was written in a method that is called on a button press. This code once worked but now there is no response from the code. Nothing happens when I click on the button even when I connected everything properly in my xib file.
Try this:
Remove
[movie play];
and add
movie.shouldAutoplay = YES;
[movie prepareToPlay];
instead.
Streaming movies (m3u8), from my experience, are a bit quirky when it comes to starting the playback. In certain situations, your original version won't work properly but my replacement always works.
EDIT:
You may also want to check your encodings and delivery using Apples Mediastream Validator as described by this Best Practice Guide and this TechNote.

donloading gif giles in iphone - improving performance

I have a table view showing records
When user taps ona record I need to show the details of that record
The detail shown also includes an image that I need to download from awebserver ( GIF ) file
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
NSData *imageData = [NSData dataWithContentsOfURL:url];
The problem is the last line where it takes some time to download the image
I am wondering what the possible options should be / can be done
I know the initWithRequest is aynchronous - but the call to dataWithContentsofUrl is right in the main path - so user experiences a wait time of more than a second
Is there a way that I could possibly have the dataWithContentsofUrl pushed into some other method that is called asynchronously
If thats possible I could look at showing a spinner or "please wait...." while the image loads
The other option I am thinking of is :
Should I have the images saved on the server in a zipped format ?
and then unzip ?
will it be faster ?
has anyone tried it before ?
or does anyone have a better option ?
I am not looking for spoon feeding but would like to hear your ideas please!

Video/audio streaming does not stop even if UIWebView is closed - iPad

I see this issue only on the iPad. The same things works as expected on the iPhone.
I am opening the URL from my application in a UIWebView. If the URL is a normal web page, it works fine as expected. But if the URL is that of a remote video/audio file, the UIWebView opens the default player which is again good.
Now when I dismiss the UIWebView (by clicking on the Done button on the player), the streaming doesn't stop and the audio/video keeps playing in the background (I cannot see it but it does keep playing in the background, can hear it). The UIViewController in which the webview was created is also dealloced (I put in a log statement in the dealloc method) but the streaming doesn't stop.
Can someone please help me out on why this could be happening? And how can I stop the audio/video streaming when the UIWebView is closed?
Thanks.
I have the same issue as stated but in this case the video that won't stop playing is a Youtube video embeded using the object/embed method.
I spent a long time trying to figure out how to get the video to stop playing and the only solution I found was to tell the UIWebView to load a blank page before dismissing the view:
[self.webContent loadRequest:NSURLRequestFromString(#"about:blank")];
Edit(2015-05-12): As mentioned by #chibimai below, this answer by alloc_iNit works along the same lines but since my answer is from 5 years ago -- and his only 4 -- the linked answer may be more applicable. I no longer do iPhone dev work so I cannot determine which is better either way.
I also found this behaviour simply because the web view hadn't been released.
I know this is pretty old thread, but for the sake of new developers like me.
My scenario was: I was using split controller, with media list on master and player in the detail controller section
I faced the same issue and tried all sorts of workaround.
I finally figured it out that the problem was simple, I was holding the reference of the detail controller in my master, and was not releasing the earlier detail controller. A simple release in the master at the right place solved the issue.
I'm working on the same problem. I've found that if you define something like this in your script tag:
function stopVideo(){ video.pause(); }
window.onunload = stopVideo;
Then in your UIViewController, add in:
-(void)viewWillDisappear:(BOOL)animated{
[webView stringByEvaluatingJavaScriptFromString:#"window.onunload();"];
[super viewWillDisappear:animated];
}
It seems to try to pause/stop the video for several seconds, but then you hear the audio continue to play!
Update!
This is a general bug with the media player. You have to set the playback time to -1 in order to make it really stop.
I've just had an issues with an mp4 file opening automatically in media player from a web-page without possibility to close it - "Done" button was only seen in video fullscreen mode and just closed fullscreen, so I had no way to return to the webpage without adding a "Back" button to the navigation bar. (on iPhone the video was opening in a separate view with "Done" button taking back to the WebView with the source page)
The workaround that helped me is to open the video file in a separate media player.
catch opening an MP4 file
- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType
{
NSRange range = [request.URL.absoluteString rangeOfString: #".mp4" options: NSCaseInsensitiveSearch];
if ( range.location != NSNotFound ) //opening MP4 video file
{
[self showFullscreenMediaWithURL: request.URL];
return NO;
}
return YES;
}
where
- (void) showFullscreenMediaWithURL: (NSURL *) mediaURL
{
MPMoviePlayerViewController *ctrl = [[MPMoviePlayerViewController alloc] initWithContentURL: mediaURL];
ctrl.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController: ctrl animated: YES];
[ctrl release];
}
opens video with URL in a media player in a model view
don't forget to add MediaPlayer.framework to the project and import
#import <MediaPlayer/MediaPlayer.h>
for the project to be built
PS. many thanks to Viktor Gubrienko for the solution
In fact, I prefer to use the null link to solve the problem.
like this:
[self.webView loadRequest:NSURLRequestFromString(#"about:blank")];
thanks to your thread on this issue I was able to figure out a solution that resolves the issue completely, and I tested it on my IPad, not just the simulator. This also resolves the issue with the audio playing. This is not the permanent resolution but an effective work around.
Overview of the approach:
Basically all that is needed is to send a short audio file to the webView. I made a copy of the IMac submarine.m4v file, I called ping.m4v and added it to my xcode project in the resource folder.
Then at the point when I want the video / audio to stop I do the following steps:
webView.hidden = TRUE;
NSString *mimeType = [[NSString alloc] initWithString:#"video/x-m4v"];
NSData *PingData = [NSData alloc];
PingData = [NSData dataWithContentsOfFile:PingFilePath];
[webView loadData:PingData MIMEType:mimeType textEncodingName:nil baseURL:[NSURL URLWithString:PingFilePath]];
Now you also have to handle error "204". Error 204 seems to be just a warning saying that webView is going to handle this audio file. To handle the error I added this single line (see >>>) to didFailLoadWithError
(void)webView:(UIWebView *)BHwebView didFailLoadWithError:(NSError *)error
{
NSLog(#"Error %i", error.code);
if (error.code == NSURLErrorCancelled) return; // this is Error -999
if (error.code == 204) return; // this is Error 204 - for audio player in webview.
Finally I turn webView.hidden = FALSE right before I display my next Audio/Video. This way the little play bar for the sound file does not show on the display. There is just a soft ping sound... any audio file will do...
I hope this helps...
This is what I use. It does log this error "Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session." but does stop the audio file from playing (fading out) and remembers the play position.
AVAudioSession *s = [AVAudioSession sharedInstance];
if (s != nil)
[s setActive:NO error:nil];
As web view hadn't been released, the video keeps playing on the web view in background.
So you need to release the web view simply by using below code which works fine for me.
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:(BOOL)animated];
[self.wvwebview removeFromSuperview];
}
I hope this helps...
in my case using loadHTMLString and not loadRequest with #"about:blank", fix the problem on macOS
[self.wkWebView loadHTMLString:#"about:blank" baseURL:nil];
I had the same issue in Table view where the table view cell has a webview which loads an audio file . Once you play and go back to another screen the audio still plays .
Solution : reload the table view in viewWillDisappear(_:) of the table view controller and the audio will stop playing once you navigate to another screen .

Resources