How can I measure duration of SpeechSynthesierStream before playing it please?
SpeechSynthesizer ss = new SpeechSynthesizer();
SpeechSynthesisStream sss;
ss.Voice = SpeechSynthesizer.AllVoices[3];
sss = await ss.SynthesizeTextToStreamAsync("Hello world.");
MediaElement mediaElement = new MediaElement();
mediaElement.SetSource(sss, sss.ContentType);
//here I want to get the duration
mediaElement.Play();
This code works just fine and speaks "Hello world.". After some time the mediaElement.NaturalDuration has also correct value. But I need to know duration of speech as soon as possible and before playing the speech. I added handler for mediaElement.MediaOpen, but this "SetSource" probably doesn't fire this event. Thank you.
In order for MediaOpen to fire, you need to attach the MediaElement to the visual tree. Once you've attached the MediaElement to the visual tree, NaturalDuration should be available within the MediaOpen event.
Related
I want to monitor the microphone audio input with flash ( as3 ).
This is just a tiny part of my code, but actually the problem is in there.
var mic:Microphone = Microphone.getMicrophone();
mic.setLoopBack(true);
addEventListener( Event.ENTER_FRAME, loop );
function loop( event:Event ):void {
trace( mic.activityLevel );
}
If i use the code like it is, i can trace the activityLevel and actually can see some values.. ( i think it is the volume ? )
Well, the only problem is, that the audio is also outputed to the speakers, what i DON'T want... ( mic.setLoopBack(true); )
But when i try mic.setLoopBack(false);, flash doesn't ask for microphone premissions anymore and the traced activityLevel stays "-1".....
So what can i do to disable the audio loopback OR to just monitor the audio data from the mic. ?
( when i say "audio data", i mean all the data that is necessary for later BPM detection... i think it's an byte array of the audio, isn't it ? )
As a temp solution to mute the mic you can try :
var st:SoundTransform = new SoundTransform(0);
mic.soundTransform = st;
You should still see the activity level.
Instead of using setLoopBack(), you just need to listen for SampleDataEvent's from the Microphone. Note the section titled "Detecting Microphone Activity" in this Adobe article, and in particular this note that talks about ways you can listen for microphone activity:
Note: A Microphone object only dispatches Activity events when your application is monitoring the microphone. Thus, if you do not call setLoopBack( true ), add a listener for sample data events, or attach the microphone to a NetStream object, then no activity events are dispatched.
var mic:Microhpone = Microphone.getMicrophone;
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
function onSampleData(event:SampleDataEvent):void
{
trace("activity from: " + mic.name + " level: " + mic.activityLevel);
}
This should be a more optimal solution, as the SampleDataEvent's are only dispatched when the microphone detects sound, as opposed to your current approach that works on every frame.
I'm making a game with AS3. I would like to put a different music in each background.
So far, I've succeed to start the music when the player enters in a scene. But if he goes out, the music is still playing...(I want the music to stop when the players leave a scene).
I don't understand why the music is still playing.. Here's my code :
public function newBackground(thisBack:String):void{
var room = back.currentBack;
switch (thisBack){
case "maisonExt":
var mySound:Sound = new exterieur ();
mySound.play ();
My mp3 file is named "exterieur.mp3".
If you can think of anything it would be a great help.
Thanks !
You need to stop the music again. If you don't stop it, it will keep on playing :)
When you call .play it will return a SoundChannel which lets you control the playback -- changing position, stopping the playback, and accessing the SoundTransform which lets you control the volume. Here is some example code for you:
public var currentSoundChannel:SoundChannel;
public function newBackground(thisBack:String):void
{
var room = back.currentBack;
if (currentSoundChannel != null)
{
currentSoundChannel.stop()
}
var nextSong:Sound;
switch (thisBack){
case "maisonExt":
nextSong = new exterieur ();
break;
}
currentSoundChannel = nextSong.play();
}
If you want to learn more about sound, I would recommend this tutorial http://gamedev.michaeljameswilliams.com/2009/03/03/avoider-game-tutorial-9/. It's part of a larger tutorial which teaches you many aspects of game making, taking you from novice to capable of creating a game. You should really check that out.
I have a website in ActionScript 3 that has lots of FLV animations that happen when you press buttons. Right now this is how I have it set up.
in AS3,
im loading FLv's (which are animations I exported in FLV form from After Effects)
with net stream. I have a timer set up for the same amount of length of time that the animations (FLV's) play and when the timer stops it calls a function that closes the stream, opens a new one and plays another video. The only problem I noticed using timers is that if the connection is slow and (animation)stops for a second, the timer keeps going, and calls the next flv too early.
Does anyone know a way to load a flv, or swf for that matter, at the end of play of the flv? so that the next FLV will always play at the end of the run time of the previous FLV, rather than using timers?
im thinking onComplete but I don't know how to implement that!?
Sequential playing is pretty easy to achieve with the OSMF framework, you should check it out. Google "osmf tutorials" and you should find a few tutorials online.
The framework is fairly recent, but it looks like it may become the de facto solution for media delivery in Flash as it's not limited to video but also audio & images.
As a developer you won't have to bother with the NetStream & NetConnection classes. Developing video solutions , as well as audio & images solutions should be streamlined and easier to handle. Only limitation is that it requires Flash 10
Here's some code for checking when a FLV ends with NetStream. I just provide snippets as I assume you got the FLV up and running already.
//create a netstream and pass in your connection
var netStream:NetStream = new NetStream(conn);
//add callback function for PlayStatus -event
var client : Object = {};
client.onPlayStatus = onPlayStatus;
netStream.client = client;
//attach your NetStream to the connection as usual
//---
//function that gets called onPlayStatus
function onPlayStatus(info : Object) : void {
trace("onPlayStatus:" +info.code + " " + info.duration);
if (info.code == "NetStream.Play.Complete") {
//play the next FLV and so on
}
}
EDIT: With your example code it will look something like this.
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
var listener:Object = new Object();
listener.onMetaData = function(md:Object):void{};
listener.onPlayStatus = function(info : Object) : void {
trace("onPlayStatus:" +info.code + " " + info.duration);
if (info.code == "NetStream.Play.Complete") {
//play the next FLV and so on
}
};
ns.client = listener;
vid1.attachNetStream(ns);
const moviename1:String = "moviename2.flv";
const moviename1:String = "moviename3.flv";
var movietoplay:String = "moviename.flv";
ns.play(movietoplay);
I have the following piece of code:
var song:Sound;
var sndChannel:SoundChannel;
var context:SoundLoaderContext = new SoundLoaderContext(2000);
function songLoad():void {
song.load(new URLRequest(songs[selected]),context);
sndChannel = song.play();
}
Now I want to be able to check if the song is buffering or not. Is there a way to do this? Or should I approach it differently?
Seems like you could use the isBuffering property of the Sound object.
Maybe you could check it periodically with a Timer or an Event.EnterFrame listener, as long as the sound has not been completely downloaded (i.e. until Event.COMPLETE fires). After that point, it makes no sense to check isBuffering, for obvious reasons, so you could remove the Timer or EnterFrame.
For a project I want to show all available webcams and microphones, so that the user can easily select whichever webcam/microphone combination they prefer. I run into an issue with the microphones listing though.
Each microphone is listed with an activity animation and it's name. I am able to list all Microphones just fine (using the Microphone.names Array), but it seems like I can only get the activity viewer to work for one microphone. The other microphones show up with '-1' activity, which (as far as I know) is Flex for 'present, but not in use'. When unplugging the microphone that does show activity, the next one (in my case, the mic-in line on my motherboard) shows up with '0' activity (it's not connected, so that makes sense).
During my testing I have a total of 3 microphones available, the not-connected onboard mic-in port, and two connected microphones.
For testing purposes I use a timer that traces the current microphone activity each 100ms and the graph is also shown.
It does not seem to matter what default microphone I set via flash' settings panel.
The code
I've only attached the revelant code snippets below to make it easier for you to read through them. Please let me know if you prefer the entire code.
Main application.mxml
Note: cont is a VBox. i is defined before this code snippet.
var mics:Array = Microphone.names;
for(i=0; i < mics.length; i++){
var mic:settingsMicEntry = new assets.settingsMicEntry;
mic.d = {name: mics[i], index: i};
cont.addChild(mic);
}
assets/settingsMicEntry.mxml
timer is defined before this code snippet. the SoundTransform is added to silence local microphone playback. Excluding this code does not solve the problem, sadly (I've tried). display is an MXML Canvas object.
mic = Microphone.getMicrophone(d.index);
if(mic){
// Temporary: The Microphones' visualizer
var bar:Box = new Box();
bar.y = 50;
bar.height = 0;
bar.width = 66;
bar.setStyle("backgroundColor", 0x003300);
display.addChild(bar);
var tf:SoundTransform = new SoundTransform(0);
mic.setLoopBack(true);
mic.soundTransform = tf;
timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void{
var h:int = Math.floor((display.height/100)*mic.activityLevel);
bar.height = (h>-1) ? h : 0;
bar.y = (h>-1) ? display.height-h : display.height;
trace('TIMER: '+h+' from '+d.name);
});
timer.start();
}
I'm pulling my hear out here, so any help is much appreciated!
Thanks,
-Dave
Ps.: Pardon the messiness of the code!
You can set up a mock NetStream connection using the OSMF library.
You'll need to import the classes from the NetMocker project (under libs/adobe - org.osmf.netmocker) and the classes NetConnectionCodes and NetStreamCodes (under framework/OSMF - org.osmf.net).
Check out that you need to create one NetStream for each microphone