I have created a webView:
videoView.delegate = self;
videoView.userInteractionEnabled = true;
[videoView loadRequest:[[NSURLRequest alloc]initWithURL:[[NSURL alloc] initWithString:#"website"]]];
I have html/javascript to handle the video's loading as well as the autoplay and next video. This all works, but my problem is that IOS autoloads the quicktime - like player, which is also a good thing, but I do not know how to control that, nor do I know how to get the video to play once that has happened. I would like the button that shows up in the player to autoplay. I would like that to happen anytime a new video is loaded.
JS code works like this. I take in a list and that is my playlist. I do not load a playlist from youTube I just make my own list and when end of video is called I load a new video by id. I also autoplay the video which is what gives me the button that IOS supplies anytime a video loads. Also, I am using an iframe to do all of this, with the youTube api's that is how I have control on the js side of things.
Question: Is there a way to control the play via code? If so how, also when the player is already loaded and I load another video how can I get that to autoplay as well?
I found the answer:
If you put webView.mediaPlaybackRequiresUserAction=FALSE; in the webViewDidFinishLoad then it will autoplay and still let you use the other buttons as well. This worked like a charm and suggest using it.
I found the answer: If you put
webView.mediaPlaybackRequiresUserAction=FALSE;
In the webViewDidFinishLoad: then it will autoplay and still let you use the other buttons as well. This worked like a charm and suggest using it.
To check if the playback is finished I used the following method:
First, set the delegate of your webview to self and implement this:
- (void)webViewDidFinishLoad:(UIWebView *)_webView {
UIButton *b = [self findButtonInView:_webView];
[b sendActionsForControlEvents:UIControlEventTouchUpInside]; //autoplay :)
[[[[[UIApplication sharedApplication] keyWindow] subviews] lastObject] setTag:1234]; //tag it
}
then start a timer:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(onTimer:) userInfo:nil repeats:YES];
and check:
BOOL playing;
- (void)onTimer:(NSTimer *)t {
id _topView = [[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];
if ([_topView tag]==1234)
{
playing=YES;
}
else {
if (playing==YES) { //was playing, but now not anymore
//dismiss your view, or do other things.
[t invalidate];
playing=NO;
}
}
}
Related
I am using AVPlayer to play music in my code. I know I can use MPVolumeView from MediaPlayer to route between speakers, but I am looking for something different(Because I am developing the application in Ionic and I am not able to find some plugin that can perform such thing, plugin which I use is cordova-plugin-media).
I have searched about how to create it and found some answers like I can switch using AVAudioSession.
I am not able to find some code related to it so if anyone can help it would be great.
Another thing is that if I change this forcefully how will it behave with Control Center.
You can still use MPVolumeView with IONIC as plugin, you just need to control UITouchUpInside through code.
Check this if helps.
- (void) currentOutputs:(CDVInvokedUrlCommand*)command {
if(!mpVolumeView){
mpVolumeView = [[MPVolumeView alloc] initWithFrame:CGRectZero];
mpVolumeView.showsVolumeSlider = FALSE;
[self.webView.superview addSubview:mpVolumeView];
[mpVolumeView setAlpha:0.01];
}
UIButton* btn = nil;
for (UIView *view in [mpVolumeView subviews]){
if ([view.class.description isEqualToString:#"MPButton"]){
btn = (UIButton*)view;
break;
}
}
if(btn){
[btn sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
Working plugin
https://github.com/jaymehtasa/cordova-plugin-audioroute
Have you tried this?
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionPortBluetoothA2DP)
} catch _ {
}
This maybe helpful.
I am trying to use this Library to play youtube video in my ios app, it works for when I load the page for the first time, when I go back to the previous view controller and go into the viewcontroller again which have the youtube video, the video player doesn't show up any more, unless I kill the app and restart again. Not sure Why it is like.
I have a view controller, in the view controller I am using this library to play youtube videos. when I get into this view controller for the first time it all works fine, but when i get to this view controller for the second time, the player not showing up unless I kill the app.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.player loadPlayerWithVideoId:#"M7lc1UVf-VE"];
}
-(YTPlayerView*)player
{
if(!_player)
{
_player = [[YTPlayerView alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, 220)];
_player.delegate = self;
_player.autoplay = NO;
_player.modestbranding = YES;
_player.allowLandscapeMode = YES;
_player.forceBackToPortraitMode = YES;
_player.allowAutoResizingPlayerFrame = YES;
_player.playsinline = NO;
_player.fullscreen = YES;
_player.playsinline = YES;
}
return _player;
}
I have used this library to load youtube video and it's working fine for me in the situation you described....
You should declare YTPlayerView as property in .h file like this.
#property(nonatomic, strong) IBOutlet YTPlayerView *playerView;
It is working well for me.
I am trying to create AVAudioplayer programatically.The audio player successfully playing.But i have some issues.I am displaying 12 audio items in UITableview.If i click first item that should navigate audio player view controller.And i click the play button the song will play.If i click back button the song play continuously.But if i click again same item the Audio view controller the view will display initial state like progress bar should not move and current time and song duration are empty.but song play continuously.
And another issue is there. If i click first item that corresponding song will play.I should not click any pass button.i click back button and click second item.if i click second item the audio view controller will display.I click play button the song display.In background first song play and second song also play.This is my second issue.how to solve these two issues.please help me any body.
-(void)playOrPauseButtonPressed:(id)sender
{
if(playing==NO)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"Pause.png"] forState:UIControlStateNormal];
// Here Pause.png is a image showing Pause Button.
NSError *err=nil;
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSLog(#"%# %d",urlsArray,selectedIndex);
NSString *sourcePath=[urlsArray objectAtIndex:selectedIndex];
NSData *objectData=[NSData dataWithContentsOfURL:[NSURL URLWithString:sourcePath]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];
audioPlayer.numberOfLoops = 0;
[audioPlayer prepareToPlay];
audioPlayer.delegate=self;
[audioPlayer play];
playing=YES;
}
else if (playing==YES)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
playing=NO;
}
if (self.audioPlayer)
{
[self updateViewForPlayerInfo];
[self updateViewForPlayerState];
[self.audioPlayer setDelegate:self];
}
}
-(void)updateViewForPlayerInfo
{
self.songDuration.text = [NSString stringWithFormat:#"%d:%02d", (int)self.audioPlayer.duration / 60, (int)self.audioPlayer.duration % 60, nil];
NSLog(#"%f", self.audioPlayer.duration);
self.progressBar.maximumValue = self.audioPlayer.duration;
self.volumeSlider.value = self.audioPlayer.volume;
}
-(void)updateViewForPlayerState
{
[self updateCurrentTime];
if (self.updatedTimer)
{
[self.updatedTimer invalidate];
}
if (self.audioPlayer.playing)
{
self.updatedTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(updateCurrentTime) userInfo:self.audioPlayer repeats:YES];
}
}
-(void)updateCurrentTime
{
//NSLog(#"self.audioPlayer.currentTime = %f", self.audioPlayer.currentTime);
self.currentTime.text = [NSString stringWithFormat:#"%d:%02d", (int)self.audioPlayer.currentTime / 60, (int)self.audioPlayer.currentTime % 60, nil];
self.progressBar.value = self.audioPlayer.currentTime;
}
-(void)volumeSliderMoved:(UISlider *)sender
{
self.audioPlayer.volume=[sender value];
}
I think the problem is here
audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];
Each time you are creating the audioPlayer object. So my suggestion is check for audioPlayer before creating the object like this
if(audioPlayer)
{
audioPlayer.delegate=nil;
audioPlayer=nil;
}
Then create the object.
In short what's happening is the following:
you click on the table cell
you create an audio player view controller
You play the audio - your audio player itself is retained for some reason (Unclear why - are you using ARC?)
You click the back button - the Audio player view controller is released
you click the table cell again - and create a new audio player view controller with it's own player!
Basically - if you want the previous song continue playing even when your exiting the Audio player view controller - and to have only a single player for the audio - I would hold it in a singleton class that will manage the player , or as a property of the app delegate.
This way - when you enter the Audio Player view controller - It will check the following:
If a player doesn't exist - create it and assign it the item - ready to play
If a player exists but it's the same item - just update the controls to show it's current playing status.
If a player exists but it's another item - either don't update the controls - and when the user hits play - replace the item in the player and start updating the controls - or stop the song as you display the Audio player view controller. (Up to you - I don't know the design of your app obviously)
In working with AVAudioPlayer, I use a property to keep up with the player. Based on looking at your code it isn't clear to me that you are keeping the player around, or that you aren't instantiating a new instance every time. Based on your description, it sounds like you ARE instantiating a new instance - don't think you want that.
So in your .h file, something like this:
#property (nonatomic, strong) AVAudioPlayer *myAVAudioPlayer;
and then the corresponding #synthesize in your .m file.
When you want to move from one song to the next, simply stop playing current - then reload a new URL using an init for your self.myAVAudioPlayer property. You MUST then call the prepareToPlay method again for the AVAudioPlayer option.
You probably will make it easier on yourself by not managing the variables regarding playing or not (it looked like you were doing that from your post). Use your property and check by accessing the setter/getter for the property for state of the player:
if(!self.myAVAudioPlayer)
{
// allocate and initialize using the code you have
[self.myAVAudioPlayer prepareToPlay];
} else
if ([self.myAVAudioPlayer isPlaying])
{
//do whatever you need for isPlaying - looks like pause
} else
if (![self.myAVAudioPlayer isPlaying])
{
// do whatever you need to do if the player isn't playing when the button is pressed
// at this point you will likely just re-init with a new URL and reset other items
// don't forget to call -prepareToPlay again
}
Here is a link to another approach which takes advantage of AVPlayerItem --> click https://stackoverflow.com/a/22254588/3563814
I added a button to my storyboard, and assigned a music to be played when the button is clicked. I used the event touch up inside
My question is, how can I make the button to toggle the music on and off when it is clicked.
Thanks
==================================================================================
For those of you who are interested in seeing the App, I made a repository on github. Here's the link https://github.com/edwinlimantara/IncrediboxV2. Please contribute, if you feel it is an interesting project.
I tried to make something similar to http://incredibox.com/v2/. Check it out! It is a very cool website.
If you are using AVAudioPlayer you can toggle the music player on button tap like:
if(audioPlayer.isPlaying){
[audioPlayer stop];
audioPlayer = nil;
}else{
// initialize audio player and play
}
You can do like below, say below method is called on button tap event then,
-(IBAction)pushClicked:(id)sender
{
UIButton *mButton = (UIButton*)sender;
if (mButton.selected==NO)
{
[mButton setSelected:YES];
//do your stuff here;
}
else if (mButton.selected==YES)
{
[mButton setSelected:NO];
// do your stuff here
}
}
Better you can use UISwitch rather than button to toggle.
If you want to use UIButton then you can use tags and and two different images.
if(soundButton.tag == 1)
{
if(audioPlayer.isPlaying){
[audioPlayer stop];
audioPlayer = nil;
soundButton.tag = 0;
// Change the button image to Off
}
else{
// initialize audio player and play
}
}
else
{
soundButton.tag = 1;
// Play the music & Change the button image to ON
}
I'm a new developer and I'm getting to know music and sound in iOS.
I've managed to make a media picker where the user can select music but when I press the cancel button, nothing happens. This is the method I'm using:
- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
I tried putting an NSLog in it to see if it was actually being called and there was nothing in the console so it's not actually being called at all. Is there a reason and solution that can be concluded with this information? Have I simply missed out something or might have not done something elsewhere?
Any help would be greatly appreciated.
If the code I used for the media picker would be helpful, here it is:
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
[mediaPicker setDelegate:self];
mediaPicker.prompt = NSLocalizedString(#"text1", "text2");
[self presentViewController:mediaPicker animated:YES completion:nil];
I wonder if you need to do:
- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker
{
[mediaPicker dismissViewControllerAnimated:YES completion:nil];
}
instead?
Also, set a break point within your "mediaPickerDidCancel" method and just see it the breakpoint even hits when hitting the cancel button in the picker.
In Swift :
func mediaPickerDidCancel(mediaPicker: MPMediaPickerController){
// Dismiss the picker if the user canceled
dismissViewControllerAnimated(true, completion: nil)
}