music = game.sound.play('loop4');
music.loopFull();
music.stop();
thiese code work well in chrome except firefox
how can I play loop sound in fireFox and then stop it
Try this:
//Add sound
var music = game.add.audio('loop4');
//Start loop
music.loopFull();
//Stop loop
music.stop();
I don't know, it could be a bug. But it's also weird that you start and then immediately on the next line stop the music. Maybe that is not the intended use. If you try something like this, does it then start playing and stop after 2 seconds?
music = game.sound.play('loop4');
music.loopFull();
// wait 2 seconds then stop
game.time.events.add(Phaser.Timer.SECOND * 2, doStopMusic, this);
// separate function to stop music
function doStopMusic() {
// note: music must be global variable
music.stop();
}
Related
I'm having a little trouble working with the linearRampToValueAtTime on a BiQuadFilter applied to a WebAudio.
The audio works ok, and the initial lowpass filter is applied.
Problem is, as soon as I use the linearRamp method to bring up the frequency, it seems to ignore the endTime parameter (or better, it's not time correctly).
Some code to explain it better.
Here's the instancing:
this.audioLoader.load( 'public/media/soundtrack-es_cobwebs_in_the_sky.mp3', buffer => {
this.sounds.soundtrack = new THREE.Audio(this.listener);
const audioContext = this.sounds.soundtrack.context;
this.biquadFilter = audioContext.createBiquadFilter();
this.biquadFilter.type = "lowpass"; // Low pass filter
this.biquadFilter.frequency.setValueAtTime(200, audioContext.currentTime);
this.sounds.soundtrack.setBuffer(buffer);
this.sounds.soundtrack.setFilter(this.biquadFilter);
this.sounds.soundtrack.setVolume(0.5);
this.sounds.soundtrack.play();
})
Until here, everything looks ok. The sound plays muffled as needed.
Then, after a certain event, there's a camera transition, where I want the sound to gradually open up.
As a endTime parameter, I'm passing 2 seconds + the internal context delta.
this.sounds.soundtrack.filters[0].frequency.linearRampToValueAtTime(2400, 2 + this.sounds.soundtrack.context.currentTime);
Expecting to hear the ramp in two seconds, but the sound opens up immediately.
What am I missing?
The linear ramp will be applied using the previous event as the startTime. In your case that will be audioContext.currentTime at the point in time when you created the filter. If that is sufficiently long ago it will sound as if the ramp jumps right to the end value. You can fix that by inserting a new event right before the ramp.
const currentTime = this.sounds.soundtrack.context.currentTime;
const filter = this.sounds.soundtrack.filters[0];
filter.frequency.setValueAtTime(200, currentTime);
filter.frequency.linearRampToValueAtTime(2400, currentTime + 2);
So I am animating an avatar, and this avatar has its own animator with states and such.
When interacting with props, the props itself has an animator with states in it. In both case, I transition to some animations through parameters in the animator (bool type).
For example, for a door, the character will have "isOpeningDoor", while the door will have "isOpen".
Now the question: when I change the value on an animator on GO1, and then change the bool on GO2; do the first animation finish and then the second start? Because in my case, it does not happen; they start almost at the same time.
void OnTriggerEnter (collider door)
{
if (door.gameObject.tag=="door")
{
GOAnimator1.SetBool("isOpeningDoor", true);
GOAnimator2.SetBool("isOpen", true);
}
}
I believe that I am doing it wrong, since I change the parameter on the animator, but I do not check for the animation to end; is this even possible or am I doing something not kosher?
I really think it might be doable!
As you have it in your code now, the animations on GO1 and GO2 start at almost the same time because that's how it's written. The OnTriggerEnter() function will complete the execution in the frame it is called, and return the control to Unity.
What I think that might help you are coroutines and sendMessage between gameobjects:
http://docs.unity3d.com/Manual/Coroutines.html
http://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html
The idea is to:
Create a coroutine in GO2 that waits an amount of time until it sets the GOAnimator2 variable to activate the door animation.
Create a function in GO2 that calls the aforementioned coroutine
From the OnTriggerEnter() send a message to GO2 to execute the newly created function
It reads complicated, but it's fairly simple. The execution would be like this:
1.Code for the coroutine:
function GO2coroutine(){
float timeToWait = 0.5f; //Tweak this
for ( float t = 0f; t < timeToWait; t+=time.deltaTime)
yield;
GetComponent<Animator>().SetBool("isOpen",true);
}
Code for the function calling it:
function callCoroutine() {
StartCoroutine("Fade");
}
And the code modification for your OnTriggerEnter():
void OnTriggerEnter (collider door)
{
if (door.gameObject.tag=="door")
{
GOAnimator1.SetBool("isOpeningDoor", true);
GO2.SendMessage("callCoroutine");
}
}
I didn't have a chance to test the code, so please don't copy paste it, there might be slight changes to do.
There is another way, but I don't like it much. That is making the animation longer with an idle status to wait for the first game object animation to end... but it will be a hassle in case you shorten the animation because you have to, or have any other models or events.
Anyway, I think the way to go is with the coroutine! Good Luck!
I have 0.2sec long sound file "beep.caf" that I am trying to get to play rapidly. If I set the sounds to play 1 second apart, they play just fine, but if I set them to play any less like 0.8, only the first sound plays. I have the same problem using AudioServicesPlaySystemSound too.
To play the sound twice rapidly I have the following function:
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue(), block)
}
I first setup my sound in the viewDidLoad with the following:
let path = NSBundle.mainBundle().pathForResource("beep", ofType: "caf")!
let url = NSURL(fileURLWithPath: path)
do{
self.startBeep = try AVAudioPlayer(contentsOfURL: url)
self.startBeep.prepareToPlay()
}catch{
print("Audio didn't load")
}
Then when a button is pressed the following code is run:
let start_time:Double = 1.0
let end_time:Double = start_time + 0.8
runAfterDelay(start_time ) {
self.startBeep.play()
}
runAfterDelay(end_time ) {
self.startBeep.play()
}
I have tried to stop the sound before the next play, but that doesn't help either. I have even duplicated the should file (beep & beepStop) to see if it had something to do with playing the same sound file and I get the same problems.
Any ideas??
The problem is with the time and not the players. The delay time was supposed to be in a 10th of a millisecond but was a 100th of a millisecond (.1 vs .01) which was so short of time between beeps that it often didn't fire accurately. A false positive was created when the time was set to 1.0 seconds.
I'm just getting started with TVOS and was wondering if anyone has addressed looping in TVOS / TVJS / TVML. I'm using this tutorial to create a simple interface for playing videos. My wrinkle is that I want these videos to play in a continuous seamless loop - basically a moving screensaver type effect - see example videos at art.chrisbaily.com.
Is there a simple way to do this, or do I need to build some kind of event listener to do the looping manually? I'd like the videos to be fairly hi res, and the videos would be somewhere between 1 and 3 minutes.
I was looking for an answer for this question as well. And found that the only way this would be possible is to create an event listener and adding a duplicate media item to the playlist. But honestly it is not that hard, given if you followed the tutorial that you listed in your post.
So the code would be something like
player.playlist = playlist;
player.playlist.push(mediaItem);
//Again push the same type of media item in playlist so now you have two of the same.
player.playlist.push(mediaItem);
player.present();
This will make sure that once your first video ends the second one starts playing which is essentially a loop. Then for the third one and on you implement an event listener using "mediaItemWillChange" property. This will make sure that once a video ends a new copy of the same video is added to the playlist.
player.addEventListener("mediaItemWillChange", function(e) {
player.playlist.push(mediaItem);
});
Just put the event listener before you start the player using
player.present();
Note this question and idea of this sort was already asked/provided on Apple's discussion board. I merely took the idea and had implemented it in my own project and now knowing that it works I am posting the solution. I found that if I pop the first video out of the playlist and add then push a new on the playlist as mentioned in the linked thread below, my videos were not looping. Below is the link to the original post.
How to repeat video with TVJS Player?
You could also set repeatMode on the playlist object
player.playlist.repeatMode = 1;
0 = no repeat
1 = repeat all items in playlist
2 = repeat current item
There's really no need to push a second media item onto the. Simply listen for the media to reach its end, then set the seek time back to zero. Here's the code.
Play the media.
private func playVideo(name: String) {
guard name != "" else {
return
}
let bundle = NSBundle(forClass:object_getClass(self))
let path = bundle.pathForResource(name, ofType:"mp4")
let url = NSURL.fileURLWithPath(path!)
self.avPlayer = AVPlayer(URL: url)
if (self.avPlayerLayer == nil) {
self.avPlayerLayer = AVPlayerLayer(player: self.avPlayer)
self.avPlayerLayer.frame = previewViews[1].frame
previewViews[1].layer.addSublayer(self.avPlayerLayer)
avPlayer.actionAtItemEnd = .None
//Listen for AVPlayerItemDidPlayToEndTimeNotification
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidReachEnd:", name: AVPlayerItemDidPlayToEndTimeNotification, object: self.avPlayer.currentItem)
}
avPlayer.play()
}
Play Again
func playerItemDidReachEnd(notification: NSNotification) {
let item = notification.object as? AVPlayerItem
item?.seekToTime(kCMTimeZero)
}
Basically, I'm looking for all the events that happen as a swf is loading, getting starting, playing the first frame, etc. Ideally, I'd like it broken down by flash version....
I ran this code:
var events:Array = [
Event.ACTIVATE,
Event.ADDED,
Event.ADDED_TO_STAGE,
Event.CANCEL,
Event.CHANGE,
Event.CLEAR,
Event.CLOSE,
Event.COMPLETE,
Event.CONNECT,
Event.COPY,
Event.CUT,
Event.DEACTIVATE,
Event.ENTER_FRAME,
Event.EXIT_FRAME,
Event.FRAME_CONSTRUCTED,
Event.FULLSCREEN,
Event.ID3,
Event.INIT,
Event.MOUSE_LEAVE,
Event.OPEN,
Event.PASTE,
Event.REMOVED,
Event.REMOVED_FROM_STAGE,
Event.RENDER,
Event.RESIZE,
Event.SCROLL,
Event.SELECT,
Event.SELECT_ALL,
Event.SOUND_COMPLETE,
Event.TAB_CHILDREN_CHANGE,
Event.TAB_ENABLED_CHANGE,
Event.TAB_INDEX_CHANGE,
Event.TEXT_INTERACTION_MODE_CHANGE,
Event.UNLOAD
];
for each(var i:String in events)
{
addEventListener(i, _response);
}
function _response(e:Event):void
{
trace(e.type);
removeEventListener(e.type, _response);
}
And found that a few of the events initially dispatched include:
exitFrame
activate
enterFrame
frameConstructed
This only applies to the MainTimeline, but you can perform the same test on other automatically initialized entities as well.
Here is a list of events that happen when the first frame is about to be played: The MovieClip life cycle
Other than that, there are Loader specific events before that, if you are loading a swf from another one:
Event.INIT when the swf is ready to play. Event.COMPLETE when the download is complete.