I'm asking the question like that because a UIAlertView will go off. Just not the AVAudioPlayer. Here's my code:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"MapViewController - didEnterRegion");
LocationReminder *theLocationReminder = [self.locationReminders objectForKey:region.identifier];
NSError *error;
NSURL *theUrl = [NSURL URLWithString:theLocationReminder.audioURI];
NSLog(#"theUrl = %#",theUrl);
AVAudioPlayer *thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:theUrl error:&error];
NSLog(#"thePlayer.url = %#",thePlayer.url);
[thePlayer play];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"entered region..." message:#"You have Entered the Location." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
alert.tag = 2;
[alert show];
}
I checked the logs on the device after testing and while the Alert View does indeed show while I'm walking around testing it, the AVAudioPlayer wont play even though it has the correct URL.
I should mention that while I have enabled audio in the plist under Required Background Modes, I'm still in the app (so backgrounding wouldn't be an issue).
You are not maintaining a reference to thePlayer so it is getting deallocated (assuming you are using ARC). Possibly add a property in your class #interface block like
#property (nonatomic, strong) AVAudioPlayer *player;
and then instead of the line you have do
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:theUrl error:&error];
Hope this helps!
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Below is code:
[NSString alloc] initWithContentsOfURL:url usedEncoding:NSUTF8StringEncoding
Xcode gives error : no visible #interface for "NSString" declares the selevtor "initWithContentsOfURL:url usedEncoding
So what is wrong here?
Here the full code:
NSURL *url = [[NSURL alloc] initWithString:#"http://google.com"];
NSStringEncoding encoding;
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url usedEncoding:NSUTF8StringEncoding];
if ([my_string length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"No Internet Connection"
message:#"A connection to the Internet is required to access this page."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
`
You missed a parameter in here :
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url usedEncoding:NSUTF8StringEncoding];
It should be :
NSError *error = nil;
NSStringEncoding enc;
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url usedEncoding:&enc error:&error];
As it's stated in NSString Reference :
- (instancetype)initWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding)enc error:(NSError **)error
Be sure to trust the warnings in Xcode. In this case, I think, it should tell you that it can't find the method signature in NSString class before you compile the code.
And also always check with Apple's documents if you aren't sure about method names or signatures. It'd help you coding faster :D
EDIT: I fixed the code as #David suggested, thank!
EDIT : Added full code with some more explanation
If I understand it correctly, you only want to convert NSData to NSString that you already knew it was in UTF8 encoding.
If that's the case, you used a wrong method. The method you used is for converting NSData to NSString and figuring out what encoding it is in. That why you have to supply it with a pointer of NSStringEncoding.
Back to your case, this is what your full code would look like :
NSError *error = nil; // I added this
NSURL *url = [[NSURL alloc] initWithString:#"http://google.com"];
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url
encoding:NSUTF8StringEncoding // and changed this
error:&error]; // and added this
if ([my_string length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"No Internet Connection"
message:#"A connection to the Internet is required to access this page."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
But if i was wrong, this might be your full code :
NSError *error = nil; // I added this
NSStringEncoding enc; // also this
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url
usedEncoding:&enc // changed this
error:&error]; // and added this
if ([my_string length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"No Internet Connection"
message:#"A connection to the Internet is required to access this page."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
I am trying to parse youtube link and play on MPMoviePlayerViewController.
I am just following this link and I can parse successfully with their example youtube link. https://github.com/hellozimi/HCYoutubeParser
http://www.youtube.com/watch?v=8To-6VIJZRE
However, the problem is that I can't parse other youtube URL like this
http://www.youtube.com/watch?v=Ndy1J859n5I
Is it because of video duration? I would like to know how to solve this.
Code
// Gets an dictionary with each available youtube url
NSDictionary *videos = [HCYoutubeParser h264videosWithYoutubeURL:[NSURL URLWithString:#"http://www.youtube.com/watch?v=8To-6VIJZRE"]];
// Presents a MoviePlayerController with the youtube quality medium
MPMoviePlayerViewController *mp = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:[videos objectForKey:#"medium"]]] autorelease];
[self presentModalViewController:mp animated:YES];
// To get a thumbnail for an image there is now a async method for that
[HCYoutubeParser thumbnailForYoutubeURL:url
thumbnailSize:YouTubeThumbnailDefaultHighQuality
completeBlock:^(UIImage *image, NSError *error) {
if (!error) {
self.thumbailImageView.image = image;
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
}
}];
I have managed to successfully send videos from a class in Parse.com to an app. Is this what you are trying to do? If so, the above code is completely incorrect.
i've been using an html string for a long period for playing youtube videos through an UIWebView, the problem is i want to get notifications with playbackstate changed. i've decided to create an MPMoviePlayerController and play the youtube video through this, but cant seem to make it work. i'm using following code in viewdidload:
NSString *urlAddress = #"http://www.youtube.com/watch?v=m01MYOpbdIk";
NSURL *url = [NSURL URLWithString:urlAddress];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
CGFloat height = [UIScreen mainScreen].bounds.size.height;
movie = [[MPMoviePlayerController alloc] initWithContentURL:url];
movie.scalingMode=MPMovieScalingModeAspectFill;
movie.view.frame = CGRectMake(0.0, 0.0, width, height);
[self.view addSubview:movie.view];
[movie play];
Gives me this error:
_itemFailedToPlayToEnd: {
kind = 1;
new = 2;
old = 0;
}
For me this library did work perfectly! https://github.com/hellozimi/HCYoutubeParser
moviePlayer = [[MPMoviePlayerController alloc] init];
moviePlayer.shouldAutoplay = YES;
moviePlayer.fullscreen = YES;
moviePlayer.repeatMode = MPMovieRepeatModeNone;
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.movieSourceType = MPMovieSourceTypeFile;
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
After this call method.
[self callYouTubeURL:[NSString stringWithFormat:#"http://www.youtube.com/embed/%#",_urlcode]];
In this method parse youtube link.
- (void)callYouTubeURL:(NSString *)urlLink
{
NSURL *url = [NSURL URLWithString:urlLink];
actvity.hidden = NO;
[HCYoutubeParser thumbnailForYoutubeURL:url thumbnailSize:YouTubeThumbnailDefaultHighQuality completeBlock:^(UIImage *image, NSError *error) {
if (!error) {
[HCYoutubeParser h264videosWithYoutubeURL:url completeBlock:^(NSDictionary *videoDictionary, NSError *error) {
NSDictionary *qualities = videoDictionary;
NSString *URLString = nil;
if ([qualities objectForKey:#"small"] != nil) {
URLString = [qualities objectForKey:#"small"];
}
else if ([qualities objectForKey:#"live"] != nil) {
URLString = [qualities objectForKey:#"live"];
}
else {
[[[UIAlertView alloc] initWithTitle:#"Error" message:#"Couldn't find youtube video" delegate:nil cancelButtonTitle:#"Close" otherButtonTitles: nil] show];
return;
}
_urlToLoad = [NSURL URLWithString:URLString];
[self urlLoadintoPlayer];
}];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
}
}];
}
After this load newly parse url into player.
-(void)urlLoadintoPlayer
{
moviePlayer.contentURL = _urlToLoad;
}
Make use of custom LBYouTubePlayerViewController
It is a subclass of MPMoviePlayerViewController.
LBYouTubeView is just a small view that is able to display YouTube videos in a MPMoviePlayerController. You even have the choice between high-quality and standard quality stream.
It just loads the HTML code of YouTube's mobile website and looks for the data in the script tag.
LBYouTubeView doesn't use UIWebView which makes it faster and look cleaner.
Official way to play youtube videos: 1) UIWebView with the embed tag from Youtube the UIWebView's content.2) Using youtube-ios-player-helper[Google official way]
Unfortunately, there's no way to directly play a youtube video with MPMoviePlayerController because youtube does not expose direct links to the video files.
There are library which runs youtube videos through MPMoviePlayerController, but they are against the TOC of youtube. Hence simplest method is to go for youtube-ios-player-helper.
In case youtube-ios-player-helper pod doesn't work you can add YTPlayer.h/.m and assets folder to your project and write a bridge header with #import "YTPlayerView.h" and rest procedure you can follow on https://github.com/youtube/youtube-ios-player-helper
This definitely worked for me!
in alarm ,notification works fine in background as follows:
UILocalNotification *notification1=[[UILocalNotification alloc]init];
notification1.fireDate=alramtime;
notification1.alertBody=#"Training Time";
notification1.repeatInterval=NSDayCalendarUnit;
notification1.soundName=#"Alarm.caf";
///////
previousnotif=[[NSUserDefaults standardUserDefaults]objectForKey:#"notif1"];
previous=[NSKeyedUnarchiver unarchiveObjectWithData:previousnotif];
NSLog(#"alarm %#",previous);
if (previous!= NULL) {
[[UIApplication sharedApplication]cancelLocalNotification:previous];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"notif1"];
}
NSData *alarm1=[NSKeyedArchiver archivedDataWithRootObject:notification1];
[notifdefaults setObject:alarm1 forKey:#"notif1"];
/////////
[[UIApplication sharedApplication] scheduleLocalNotification:notification1];
NSLog(#"new alarm %#",notification1);
but when i modify it to play in foreground too as follows:..its not working..Only alert appears but no sound???
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"KNIP"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Close"
otherButtonTitles:nil];
[alert show];
}
#end
When i log soundfile etc properties of notification..they work fine...but no sound is there...
In foreground you have to provide alert view and play sound if it requires, the notification will just call applicationDidReceiveLocalNotification. You can play the sound using AVAudioPlayer
//Playing sound
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath],notification.soundName]];
AVAudioPlayer *newAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
self.audioPlayer = newAudioPlayer;
self.audioPlayer.numberOfLoops = -1;
[self.audioPlayer play];
[newAudioPlayer release];
If the application is foremost and visible when the system delivers
the notification, no alert is shown, no icon is badged, and no sound
is played. However, the application:didReceiveLocalNotification: is
called if the application delegate implements it. The
UILocalNotification instance is passed into this method, and the
delegate can check its properties or access any custom data from the
userInfo dictionary.
Does anyone know of a way to adjust an AVPlayer track's volume when it is playing over Airplay? I have tried AVAudioMix and MPVolumeView but neither of them work. I have tried on iOS 5 and iOS 6 and am using the latest xcode 4.5.1. A simple example of this not working is Apple's AVPlayerTestApp which does a simple fade out using setVolumeRampFromStartVolume. This works fine on the device but doesn't if connected through Airplay.
In ViewDidLoad I load a track and start it playing (this is all taken from AVPlayerTestApp)
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:TRUE error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
self.mediaItems = [[[MPMediaQuery songsQuery] items] mutableCopy];
NSURL *anUrl = [[mediaItems objectAtIndex: 0] valueForProperty:MPMediaItemPropertyAssetURL];
AVAsset *asset = [AVURLAsset URLAssetWithURL:anUrl options:nil];
AVPlayerItem *myPlayerItem = [AVPlayerItem playerItemWithAsset:asset];
self.myPlayer1 = [[[AVPlayer alloc] initWithPlayerItem:myPlayerItem] retain];
[myPlayer1 play];
then I have a button which opens an alertview allowing user to set volume and switch on airplay
MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame: CGRectMake(10, 37, 260, 20)] autorelease];
UIAlertView *volumeAlert = [[UIAlertView alloc] initWithTitle:#"Volume" message:#"" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[volumeView sizeToFit];
[volumeAlert addSubview:volumeView];
[volumeAlert show];
[volumeAlert release];
then another button which fades out the currently playing track
AVAsset *asset = [myPlayer1.currentItem asset];
NSArray *keys = [NSArray arrayWithObject:#"tracks"];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^(void) {
NSError *error = nil;
AVKeyValueStatus trackStatus = [asset statusOfValueForKey:#"tracks" error:&error];
CMTime currentTime;
switch (trackStatus) {
case AVKeyValueStatusLoaded:
if(myPlayer1)
{
NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray * allAudioParams = [NSMutableArray array];
for (AVAssetTrack *t in tracks) {
AVMutableAudioMixInputParameters *params =[AVMutableAudioMixInputParameters audioMixInputParameters];
float fadeOutSeconds = 5;
currentTime = [myPlayer1 currentTime];
[params setVolumeRampFromStartVolume: 1.0 toEndVolume: 0.0 timeRange: CMTimeRangeMake(currentTime, CMTimeMakeWithSeconds(fadeOutSeconds, 1))];
[params setTrackID:[t trackID]];
[allAudioParams addObject:params];
}
AVMutableAudioMix * zeromix = [AVMutableAudioMix audioMix];
[zeromix setInputParameters:allAudioParams];
[myPlayer1.currentItem setAudioMix:zeromix];
}
break;
case AVKeyValueStatusFailed:
// error occured loading AVAsset
NSLog(#"error occured loading AVAsset");
break;
case AVKeyValueStatusCancelled:
// loading of the AVAsset was cancelled
NSLog(#"loading of the AVAsset was cancelled");
break;
default:
break;
}
}];
This works as expected on the device and fades the volume when the button is tapped. However, if Airplay is turned on the volume change doesn't get through. Using MPMoviePlayController I can do fades myself which work over Airplay but AVPlayer has less latency over Airplay so I would rather use that.
Any help much appreciated.
As Sam_899 didn't post an answer I'll have to do it. As far as I can work out, it is impossible to control the volume of avplayer over airplay unless the connection is made with mirroring turned on. As the only way to turn mirroring on is from outside your app the only option is to inform users how to turn it on themselves and hope they are happy with it! For those who don't know how to turn on mirroring over airplay; double click the home button, swipe left to the volume control, tap the airplay icon, choose the airplay device to connect to then switch mirroring on.