i have a problem about action script 3. i have a flv video and its totaltime is 6 seconds. i want to start it from 2. seconds with seekSeconds(). if i write bigger than 6 values in seekSeconds it will only play the video from head to end.İf i write smaller than 6 ,it won't work.what can i write in seekSeconds() to start the video from 2 seconds?
function useParams()
{
var obj:Object = new Object();
var j;
for (j in this.myParams)
{
if (j == "url")
{
src = this.myParams[j];
}
else if (j=="bas")
{
startTime = int(this.myParams[j]);
}
else
{
stopTime = int(this.myParams[j]);
}
txt.text += j + " - " + this.myParams[j];
}
//fk.source = src;
txt.text = String(startTime);
}
fk.addEventListener(VideoEvent.READY, bitti);
function bitti(eventObject:VideoEvent):void
{
//fk.play();
trace(fk.totalTime);
fk.seek(2);
trace(fk.playheadTime);
//trace(fk.playheadTime);
}
According to the documentation for VideoPlayer, Event.READY is dispatched:
Event dispatched when an FLV file is loaded and ready to display. It starts the first time you enter a responsive state after you load a new FLV file with the play() or load() method. It starts only once for each FLV file that is loaded.
It is possible the video is ready but it hasn't buffered to an adequate amount for seeking. You can change the bufferTime to a value greater than 2 although I am not certain that will guarantee Event.READY will get fired at the time you need. Also note the property of seek for progressive downloads:
For a progressive download, you can seek only to a keyframe; therefore, a seek takes you to the time of the first keyframe after the specified time.
So make sure you set a bufferTime that is adequately advanced passed 2 seconds to ensure you are passed a keyframe.
Note: there is a bufferTime on both a VideoPlayer and the NetStream so you may have to adjust one or the other or both.
Related
I'am trying to make a scoring system by using a timer so that it work on the basis that as the player keeps on going the timer/score keeps on going up and I got that to work with this code.
var nCount:Number = 0;
var myScore:Timer = new Timer(10, nCount);
score_txt.text = nCount.toString();
myScore.start();
myScore.addEventListener(TimerEvent.TIMER, countdown);
function countdown(e:TimerEvent):void{
nCount++;
score_txt.text = nCount.toString();
}
However say for example the player crashes I want the game to remember the score and then display it on another frame where I have a game over screen so that it shows the final score to the player and this is the part that I have no idea how to do. Any help would be appreciated.
Many Thanks
You can't modify objects on "another frame". You can only modify objects on the current frame. The frames simply represent state that is baked into the SWF to be actualized when the timeline reaches those frames; you cannot change SWF frame data at runtime. You can only change the resulting objects once those frames are constructed by the player.
What you can do is store your score in a variable (available across all frames) and simply set the correct text objects when you are on those frames.
For your code, you simply need to only set the nCount to 0 when the SWF loads (or you want to reset it), and set the score_txt immediately on the frame it exists. For example, you could do it like this:
// Don't initialize a value, that would overwrite
// it every time this frame is visited
var nCount:Number;
// Only the first time, when the value is NaN, set the score to 0
if(isNaN(nCount)){
nCount = 0;
}
// Immediately show the current score text
score_txt.text = nCount.toString();
// The rest stays the same
var myScore:Timer = new Timer(10, nCount);
score_txt.text = nCount.toString();
myScore.start();
myScore.addEventListener(TimerEvent.TIMER, countdown);
function countdown(e:TimerEvent):void{
nCount++;
score_txt.text = nCount.toString();
}
In my WP application I'm playing a lengthy sound effect and i am trying to
update progressBar with song state, but I just can't find a way, any help would
be appreciated.
My sound is standard SoundEffectInstance sound;
and:
if (sound.State == SoundState.Paused)
{
sound.Resume();
}
else
{
try
{
sound.Stop();
}
catch { }
Stream stream = TitleContainer.OpenStream("Sounds.wav");
var effect = SoundEffect.FromStream(stream);
sound = effect.CreateInstance();
FrameworkDispatcher.Update();
sound.Play();
}
If you have any way to get the length of the sound, either in bytes or units of time, you can use that value. Just compare the number of bytes streamed or the amount of time elapsed (depending on which you can get) to the total, and set the loading bar accordingly.
Instead of loading 9 different audio files with a distinct sound effect, I have compiled my sound effects into one .ogg file and I have the various start and stop times for each effect. However, I don't see any way to handle this in the WebAudio API. I'm sure there is. Anyone know?
Here's how to do it.
var context = new AudioContext();
var mainNode = context.createGainNode(0);
mainNode.connect(context.destination);
function play_sound(sound, start, length) {
var source = context.createBufferSource();
source.buffer = get_buffer(sound); // assume get_buffer gets a file that has already been
source.connect(mainNode); // loaded and decoded with context.decodeAudioData()
source.start(0, start, length);
}
// lets say I want to play a 0.2 second sound effect in sfx.ogg starting at 0.5 seconds.
play_sound('sfx.ogg', 0.5, 0.2);
Normally my preloader is 20 frames and looks like this:
Frame 1 Actionscript:
var amountLoaded:Number = _root.getBytesLoaded()/_root.getBytesTotal();
preloader._width = amountLoaded * 200;
loadText.text = Math.round(amountLoaded * 100) + "%";
if(_root.getBytesLoaded() == _root.getBytesTotal()) {
gotoAndPlay(21);
}
else {
gotoAndPlay(1);
}
On Frame 20, we obviously have:
this.gotoAndPlay(1);
This works fine, but it is only the home page I want the intro of my flash to play. Therefore, I use FlashVars on every other page than the home page to tell the animation where it should skip to.
To do this, I have placed this on the first frame after the preloader:
gotoAndPlay(AdFrame);
and in every page except the home page, I have added this Flash Variable:
<param name="FlashVars" value="AdFrame=39" />
My question:
How can I skip the preloader entirely if the animation is loaded?
My failed attempt:
I have tried moving my preloader to start on frame 2, and on frame one, changed:
var amountLoaded:Number = _root.getBytesLoaded()/_root.getBytesTotal();
preloader._width = amountLoaded * 200;
loadText.text = Math.round(amountLoaded * 100) + "%";
if(_root.getBytesLoaded() == _root.getBytesTotal()) {
gotoAndPlay(AdFrame);
}
else {
gotoAndPlay(2);
}
But it still does not bypass the preloader.
Any idea on how I can skip the preloader entirely if the content is loaded?
If I understand this correctly, your condition does not evaluate to true because on the first frame the values returned by the getBytesLoaded and getBytesTotal methods are not the same even when the SWF is loaded from the browser cache.
If this is the case, you could try waiting before checking the load status. Simply moving your code to frame 2 and the start of your preloader animation to frame 3 might be enough. (It's a long time since I've had to work with the timeline but I seem to remember that waiting a frame was often a good rule of thumb).
Alternatively you could pause for a short interval on the first frame before executing your check:
stop();
var interval = setInterval(function() {
clearInterval(interval);
var amountLoaded:Number = _root.getBytesLoaded()/_root.getBytesTotal();
preloader._width = amountLoaded * 200;
loadText.text = Math.round(amountLoaded * 100) + "%";
if(_root.getBytesLoaded() == _root.getBytesTotal()) {
gotoAndStop(3);
}
else {
gotoAndStop(2);
}
}, 500);
You can play around with the interval duration (half a second may be excessive). Note that the interval will be executed each time the play-head is returned to the first frame which, depending on the length of your interval, may not be a problem. If it is a problem, you could consider setting a boolean flag the first time the interval is executed so you can avoid executing it again on subsequent loops.
I'm using the AS3WavSound (http://code.google.com/p/as3wavsound/) class to playback externally loaded wavs. This is working successfully. The library is simple and effective.
After decoding the Wav ByteArray the method the library employs for playback is using the SampleDataEvent.SAMPLE_DATA event and then writing the mixed samples to the output stream.
player.addEventListener(SampleDataEvent.SAMPLE_DATA, onSamplesCallback);
private function onSamplesCallback( evt : SampleDataEvent ):void
{
for (var i:int = 0; i < samplesLength; i++)
{
if(_mute == false){
outputStream.writeFloat(samplesLeft[i]);
outputStream.writeFloat(samplesRight[i]);
}
}
}
My problem is that I need to silence this audio output immediately but whatever method I have tried there is a distinct (1 second approx) delay before the silence takes effect.
As you can see I've attempted to add a boolean to block any samples being written to the output stream but this has had no effect on the delay.
My suspicion is that this is a fundamental part of how the samples are buffered and then written out. Essentially by the time a user action on screen (clicking a mute button) has been called and the _mute boolean is set to true there are already samples waiting to be written to the output that cannot be affected.
Any advice or confirmation of my suspicion would be greatly appreciated.
Thanks,
gfte.
Your suspicion is probably right - but why stop it at that level? If you want to turn off the sound, would it not be better to set the volume on the soundTransform-property on the SoundChannel-object returned by the play method? (I assume the wav library returns this in some way)
It looks like the library you are using has a similar design to the native Flash Sound API wherein a SoundChannel object is returned from the play() method. This SoundChannel instance has a stop() method which should stop the sound right away.
var sound:WavSoundPlayer = new WavSoundPlayer();
var channel:WavSoundChannel = new WavSoundChannel();
sound.addEventListener( SampleDataEvent.SAMPLE_DATA, onSampleData );
channel = sound.play();
private function onSamplesData( evt : SampleDataEvent ):void
{
for (var i:int = 0; i < samplesLength; i++)
{
outputStream.writeFloat(samplesLeft[i]);
outputStream.writeFloat(samplesRight[i]);
}
}
channel.stop()
The _mute variable in your example will only be able to change either before or after the loop, not while it is looping.