Play one of a set of audio clips randomly? - html

So I'm trying to setup a web-page where when you open it, it will play a random piece of music, and when that one finishes, it will play another directly after so you get a constant stream of music, but not in the same order every time. If this goes outside the bounds of HTML and I'm looking at for instance JavaScipt than that's fine.
I know this is probably a rather easy solution, but I'm new to HTML and trying to understand it better.
Thanks in advance if I don't get back to you soon!

This is best solved using JavaScript, which is used to add behavior to a website. HTML is primarily used to structure your site.
We can get a collection of all audio elements with the querySelectorAll function. Then we find a random element with the next line and call the play method.
var audio = document.querySelectorAll("audio");
function playRandom() {
audio[Math.floor(Math.random() * audio.length)].play()
}();
For the second part of your question, you would want to listen for the ended event. Inside the event listener function, you would then call the playRandom() function.
audio.addEventListener("ended", function() {
playRandom();
});

Related

Animating from within classes in Actionscript 3 (Not on the timeline), what's the best way?

I've found some stuff online about how to animate in actionscript 3 from within a class, but haven't been able to find a really good tutorial. I want to control the animations from a class because at some point I intend to move from the flash IDE to using flash develop, where I won't have access to the Flash IDE's timeline.
I have to be able to control an initial animation (opening a bag) which joins onto an animation loop (searching through a bag).
The only way I have been able to do this so far is to add an event listener to listen for the initial animation's final frame. Then when initialAnimation.currentFrameLabel = "Last" then I gotoAndStop("animationLoop").
This has been working fine, if a bit time-consuming. I'm just wondering if there's a better, easier way to do it? Can anyone tell me or point me towards a tutorial that does it better? Thanks very much!
Romano
I recommend instead of using an event listener, you use the method addFrameScript. Essentially you can fire a method when a specific frame number is reached.
Read the following question for more information.
actionscript3 whats the point of addFrameScript
It depends on what it is you want to do:
Usually if you are working together with an artist or want to do animations that are non-code driven, the "best way" is usually to listen for something to happen, and then start animations and on last frame of animation (or when you want to return control to code) you create an event, or use a callback or something else to let code notify that animation is complete or reached a certain point.
If you want to do something from code, the easiest way is to use an external animation library.
Tweener (https://code.google.com/p/tweener/)
TweenLite (http://www.greensock.com/tweenlite/)
Using those libraries, you would write something similar to:
function fadeOut():void {
mc.alpha = 1;
Tweener.addTween(mc, {alpha:0, time:0.275, delay:1, onComplete:onDone});
}
function onDone():void {
trace("Animation finished");
}

Catch video HTML5 play/stop event

How can I listen to the events play/stop/pause of a HTML5 video?
I tried with the following code:
$("video").on('play',function(){
//my code here
});
but it does not work.
Alternatively I would be fine also intercept the click that stop and start the video (in fact I would prefer), but even this code not works:
$('video').on('click', function(event) {
//my code here
});
I think because often above the video element is placed a div with associated events start and stop, but I do not know how to select via jQuery or Javascript:
P.S. This code should work on pages that are composed dynamically / not generated by me, so I can not refer the elements indicating their ID or a specific class.
UPDATE
I did not realize that the page on which I was testing had a video inside an iframe.
The syntax is best suited to my needs:
doc.querySelector("video").addEventListener('play', function(e) {
//my code here
}, true);
See here:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
So... :
$("video")[0].onplay = function () {
// Do play stuff here
};
Hope that helps!
Your first attempt should work. But you need to make sure that jQuery is actually finding video elements. You say that the page is generated dynamically, so perhaps it's possible that your code is running before the video elements are added. This would also be the case if your script is higher up in the document than the video elements (e.g., in the <head>).
Try placing the following code immediately before the code you have there and check the output:
console.log($("video"));
If the output is an empty array, then you aren't finding any video elements. Try placing your script at the very end of the page or inside a DOMContentLoaded event. Or, if another script is generating the video elements, make sure your script runs after that one.
A few other notes on your question:
There is no stop event. Here's a list of media events.
I don't think the click event is what you want. That will fire no matter where on the video the user clicks: play button, volume control, etc.
The video being placed inside a div shouldn't have any effect on these events. I'm not sure why you'd have start and end events on a div, so maybe I'm not following.
Give this a try!
//Direct
<video id="videoThis" src="blahhh.mp4" onended="yourFunction()"></videoThis>
-or-
//JavaScript (HTML5)
document.querySelector("#videoThis").addEventListener("ended",yourFunction,false);
-or-
//jQuery
$("#videoThis").bind("ended",yourFunction);

Actionscript to play/pause audio on different buttons

I've created a few buttons in Flash. I'm trying to make it so that if you click one button, the audio starts playing for that button. If you click another button, the active audio stops and the new audio of the button you clicked last start playing.
Any help please?
What you're describing is actually quite easy to do.
First things first, I recommend importing the audio into your Flash project. Alternatively, there is a way to play it directly from an external file. This is beyond the scope of my answer, so if you need help on that, you should post a question specifically covering it.
Assuming you have imported the audio file into your Flash project's library, make an as3 instance of it. (Right click the file in the library, click Properties --> ActionScript [tab] --> [Check] Export for ActionScript & [Enter name in] Class)
Now, create a definition of the sound in your code. (Assuming your two sounds were named "mySound1" and "mySound2" in the Class field of the previous step.)
var mySound1:Sound = new mySound1();
var mySound2:Sound = new mySound2();
Now, define your sound channel.
var mySoundChannel:SoundChannel = new SoundChannel();
There are two alternate ways of stopping one sound and playing another. The first is to create one function that does both every time. The second method is to create two formulas, one for "play" and one for "stop". You will need to decide which method works best for you. I'll use the two-function method below:
function stopSound():void
{
//This stops all sound in the sound channel.
//If there is nothing playing, nothing happens.
mySoundChannel.stop();
}
//In this function, we create an argument that allows us to tell the function
//what sound to we want it to play.
function playSound(soundname:String):void
{
mySoundChannel = this[soundname].play(0, 0);
}
[Note, you can tweak the play() properties to meet your needs, doing things like starting in the middle of the song, or looping it forever. 0,0 starts at the beginning, and doesn't loop. See the documentation for this.]
Now you hook up the event listeners for the buttons. (If you need help with event listeners, read the documentation.)
myButton1.addEventListener(Mouse.CLICK, btn1Click);
myButton2.addEventListener(Mouse.CLICK, btn2Click);
function btn1Click(evt:Event):void
{
stopSound();
playSound(mySound1);
}
function btn2Click(evt:Event):void
{
stopSound();
playSound(mySound2);
}
This should be enough information to get you started. In my game core, I actually have a custom class for dealing with sound playback that gives me the ability to repeat sounds, change volume, and keep sounds from conflicting with each other. I say that to emphasize that you can do quite a bit with the sound class. Do some digging in that documentation for ideas and help.
You may also consider putting a try-catch statement in the playSound function, since it will throw an reference error if you pass a name for a sound that doesn't exist.

SVG onload event called too early?

I have code like this, using jQuery-svg
function replaceRaster(){
$('#png').remove()
a = $('#graphic')
b = a.svg(a)
a.load('IDC_Energy.svg',
{onLoad:bind} )
svg = document.getElementById("graphic").children[0]
console.log(svg)
svg.addEventListener('load', bind)
}
The event handler, bind, is fired before jQuery-svg-dom is able to select elements within the SVG data. My code is supposed to look over the SVG and assign various classes and attach listeners to various elements, but it's not able to find any. If I call bind in the console after everything is loaded it can find alll the SVG elements.
Am I doing something wrong? Is there another way to detect when the SVG DOM is available? I've thought of using a timer, but that's really hacky, especially considering my SVG files could be a few MB large.
Have you tried using a timer with a timer delay of '0' or perhaps just '10'? I've frequently used this technique to push the work out of the current run loop as timers are fired after the redraw ghas completed. With luck the bind will only be fired once the repaint has finished. I'm not sure whether this will help in your particular instance because I don't know what else you are doing in the page - it won't help, for example, if you have some asynchronous data handling going on.

StageWebView Lack on URLs with target="_blank"

is there any solution on StageWebView.loadURL(), how I can handle URLs in HTML Pages which have target="_blank"?
It's a mobile Android App. (TabbedViewApplication)
Hope someone can help.
Thx
One option is StageWebViewBridge.
StageWebViewBridge is an extended version of flash.media.StageWebView.
Extends loadString method with AS3 - JS communication.
-Extends Bitmap class, you can modify his x,y,alpha,rotation,visible, etc ( Version 1 Beta )
-Communicates Actionscript with Javascript.
-Communicates Javascript with Actionscript.
-Load local files and resources in a easy way.
-Extends loadString method with AS3 - JS communication.
-Extends loadString method to load local resources.
-Lets you take an SnapShot to use as the bitmapData of the bitmap.
StageWebViewBridge source: https://code.google.com/p/stagewebviewbridge/
I never worked with the StageWebView but I know it's really limited. When using an HTMLLoader, you can set a custom HTMLHost instance that specifies to use current HTMLLoader when opening to _blank. However, I don't think it's possible with StageWebView.
public class MyHTMLHost extends HTMLHost
{
public function MyHTMLHost(defaultBehaviors:Boolean=false)
{
super(defaultBehaviors);
}
override public function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader
{
// all JS calls and HREFs to open a new window should use the existing window
return htmlLoader;
}
}
OK, so the only solution for this problem i could found is to load the page (containing the links) as String with the URLLoader and replace its specified parts. Finally loading it via StageWebView.loadString() method.
Problems occur when the Site is dynamic and contains JavaScript. I had also replace some relative links with absolute pathes.
That's it... but I really hope that adobe makes it possible to load those "_blank" links with the StageWebView.loadURL() method.
If you want to capture when a user clicks on a link inside your StageWebView add an an event listener for location changing event (LocationChangeEvent).
This LocationChangeEvent will include the URL they are going to and target. Then you can prevent the URL from loading, let it continue (by doing nothing) or handle it any other way including loading another URL.
If you want to load another URL first stop the loading with stageWebView.stop(). You should also call event.preventDefault(). You can then attempt to
Note: There is another event called locationChange that may be helpful.
As it was declared as an official bug, adobe QA Owner Sanjay C. added a comment: "Able to reproduce the issue with the attached project. Sending to IRB."
So, hope the next Build will come up with the fix wit it.
Best regards