Goodmorning,
I'm working on a video flash player to stream. What I want to do, is to display the total time of the stream and not the time since the user is watching the stream.
I have a problem now, is that when I pause then play the video, the current time restarts.
Do you have any ideas to fix my problem and to solve the other one? :)
**I'm using NetStream
Alright, for the first problem, what you want to do is to setup a function that receives the MetaData of the video and save that value somewhere.
First, when you create your NetStream Object, you need to add a Client to the NetStream that references the function onMetaData.
var ns:NetStream; //your NetStream Object
var client:Object = new Object(); //Create an Object that represents the client
client.onMetaData = onMetaData; //reference the function that catches the MetaData of the Video
ns.client = client; //assign our client Object to the client property of the NetStream
//Once MetaData is available, it'll call onMetaData with all of the information
function onMetaData(metaData:Object):void
{
duration = metaData.duration; //duration is the variable that is supposed to total length of the video
}
Now with the duration value you get the total play time of the movie that is currently playing with that NetStream Object.
You can solve your second problem in a number of ways, for example:
pause() and resume()
pause() and player('currentTime')
Simply keep a Boolean Variable called pause that keeps track if the video is currently playing or not.
var paused:Boolean = false; //assuming the video is currently playing
var currentTime:Number = 0;
var button:Button; //some kind of play/pause button
button.addEventListener(MouseEvent.CLICK,onButtonClick);
function onButtonClick(event:MouseEvent):void
{
if(paused)
{
paused = false;
ns.resume();
//ns.play(currentTime) //this also works
}
else
{
paused = true;
ns.pause();
currentTime = ns.time;
}
}
You have to extract the information from the meta data of the file.
Thank you for you answers :).
DodgerThud, I tried your solution concerning my second problem this morning. I tried your solution and I've got this : duration : NaN. If I understand well, my problem is that I don't have the metadata of the stream...
if(isLiveStream == false) {
if(title == preroll || Number(duree) <= 0) {
duration=infoObject.duration+timeOffset;
} else {
duration=Number(duree);
}
}
Those lines are on the onMetaData function.
Thank you for helping me.
Have a nice day.
Related
I'm trying to write a bit of code that plays a sound while a buttons pressed however if the button has been pressed and the sound is playing then the sound is paused and played again rather then just playing and overlapping.
this is what I have
var sound:alarm = new alarm();
var isPlaying:Boolean = false;
public function Main()
{
button.addEventListener(MouseEvent.CLICK,playSound);
}
public function playSound(e:Event):void
{
if(isPlaying)sound.stop();
sound.play();
isPlaying=true;
}
at first glance It seemed to have worked but then I saw the following in my output
TypeError: Error #1006: stop is not a function.
at Main/playSound()
TypeError: Error #1006: stop is not a function.
at Main/playSound()
so apparently it works although stop is not a method of the Sound class. what would be the proper way of implementing this? Also I've been wondering if there is a more proper condition I can use, because with this code sound.stop() is called every time the function is entered after the first button click, is there a method that allows me to check in real time whether or not a sound is playing?
In your code, the function playSound(e:Event) should be playSound(e:MouseEvent);Also your right stop() is not a method of the Sound class, however your not using the Sound class, your using the alarm class (unless the alarm class extends the Sound class).On another note, I searched google and this popped up, Flash Play/Pause Sound
Update:
import flash.media.SoundChannel;
// Make sure to import the SoundChannel class
var sc:SoundChannel = new SoundChannel();
var sound:Sound = new alarm();
var isPlaying:Boolean = false;
var pausePos:Number = 0;
public function Main()
{
button.addEventListener(MouseEvent.CLICK,playSound);
}
public function playSound(e:MouseEvent):void
{
if(isPlaying) {
pausePos = sc.position;
sc.stop();
isPlaying = false;
} else {
sc = sound.play(pausePos);
isPlaying = true;
}
}
This code should work, however I have not tested it so if any errors are given or the desired result is not met just let me know and I'll see what I can do.
Short answer...okay, entire answer from me :). Instead of using the sound object, try the SoundChannel object. It offers more options, including volume and balance control, and most prominently, stop.
Documentation should provide enough info for using it. It's relatively common.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundChannel.html
I have 4 buttons on stage and I need a code that enables me to click on one of them, loop a specific sound "infinitely", and when it is clicked again, the sound stops. The sound is not initially playing. Also, while one of the sounds is looping, if I press another button, I'd like the previous sound to stop and the new one to play.
To help visualize this more, I will explain my project. I have to create an 'app' that is like an online guitar tuner. This feature is sort of what I would like to recreate:
http://www.gieson.com/Library/projects/utilities/tuner/
I don't even know where to begin with the coding... any help is greatly appreciated. Thank you!
The actual code is quite dependent on how you are loading in the sound, so I will write the "skeleton" for the code.
var currentSound:Sound = null;
var currentSoundChannel:SoundChannel;
var sound1:Sound = /* Load me */
var sound2:Sound = /* Load me */
button1.addEventListener(MouseEvent.CLICK, playSound1);
function playSound1(event:MouseEvent)
{
playSound(sound1);
}
button2.addEventListener(MouseEvent.CLICK, playSound2);
function playSound2(event:MouseEvent)
{
playSound(sound2);
}
function playSound(sound:Sound):void
{
if (currentSound != null)
{
// Stop the current music
currentSoundChannel.stop();
}
if (currentSound == sound)
{
// Stop playing ANY sound
currentSound = null;
currentSoundChannel = null;
}
else
{
// Play a different sound
currentSound = sound;
currentSoundChannel = sound.play();
}
}
I am currently using the following code to play audio recordings from the project library.
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.events.MouseEvent;
var sound1:Sound = new audio1();
var sound2:Sound = new audio2();
var mySoundChannel:SoundChannel = new SoundChannel();
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
{
try
{
mySoundChannel = this[soundname].play(0, 0);
}
catch(error:ReferenceError)
{
trace("playSound: That sound name doesn't exist.");
return;
}
}
//Hook up buttons-->
button1.buttonMode = true;
button1.useHandCursor = true;
button2.buttonMode = true;
button2.useHandCursor = true;
button1.addEventListener(MouseEvent.CLICK, button1click);
button2.addEventListener(MouseEvent.CLICK, button2click);
function button1click(evt:Event):void
{
stopSound();
playSound("sound1");
}
function button2click(evt:Event):void
{
stopSound();
playSound("sound2");
}
I need to pause the currently playing audio when a button is clicked. How do I do this?
You will need to do five things to your current code in order to pause and resume the currently playing sound:
Create a variable that stores the name of the currently playing
sound, and a variable to store the pause position of the audio.
Create a pause function.
Create a resume function.
Expand the current playSound and stopSound functions to work with the new variables.
Hook up the button event listener.
Step 1:
var currentSound:String = "";
var pausePosition:Number = 0;
Step 2: We're going to save the current position of the audio in that second variable we just created. We can get the current play position of the audio using the mySoundChannel.position property, which returns a Number value (matching the Number type we gave the pausePosition variable).
function pauseSound():void
{
//If there's a song to pause...
if(currentSound != "")
{
//Get pause position.
pausePosition = mySoundChannel.position;
//Stop the sound directly.
mySoundChannel.stop();
}
}
Note we didn't call stopSound(). There's a good reason for that. We're going to put an extra line of code in that function shortly that we don't want to use in pauseSound().
Step 3: Now we create the function to resume audio. Note this is NOT the same as playSound(). We're telling it to start playing from pausePosition, not from 0 (the beginning of the sound clip).
function resumeSound():void
{
//If there's a song to resume...
if(currentSound != "")
{
//Start playing the current audio from the position we left off at.
mySoundChannel = this[currentSound].play(pausePosition);
}
}
Step 4: Since we're now working with those variables we declared in step 1, we need to adjust how playSound() and stopSound() work.
In playSound(), instead of just passing soundname to the sound channel, we're going to save the soundname to currentSound.
function playSound(soundname:String):void
{
try
{
currentSound = soundname
mySoundChannel = this[currentSound].play(0, 0);
}
catch(error:ReferenceError)
{
trace("playSound: That sound name doesn't exist.");
return;
}
}
In stopSound(), we need to actually clear the currentSound and pausePosition variables when we stop, to ensure that resumeSound doesn't start audio after we've totally stopped it.
function stopSound():void
{
//This stops all sound in the sound channel.
//If there is nothing playing, nothing happens.
mySoundChannel.stop();
//Clear our variables.
currentSound = "";
pausePosition = 0;
}
GOTCHA WARNING: Ordinarily, you can loop audio by passing an integer other than 0 in the second argument (where I have the 5) in the following code:
mySoundChannel = this[currentSound].play(0, 5);
In the above code, the sound would play from the beginning, and repeat five times.
However, if you are starting the audio from any position other than 0, what will actually happen is that the audio will loop at the position you start at, not at the beginning.
That is to say, if you use this code:
mySoundChannel = this[currentSound].play(1000, 5);
The sound will loop five times, but every time the sound starts over in the loop, it will start playing from position 1000, and NOT the beginning of the sound (0).
I hope that answers your question!
My project has a main loader that load all the assets for the project. I need to load a bit of my video with it.
The video has 16mb, i want to load 3mb to use after the main loader is completed.
I've tried to open a new connection using Netconnection/Netstream to load 3mb and close the connection, but when the project starts and the video is played, a new connection is opened loading it from beginning.
I'm trying to find a way that i can use those 3mb already loaded. Doing this way, the user don't need to wait a main loader and a secondary loader (buffertime).
That's my code, sorry guys.
var loader:Loader = new Loader();
var nc:NetConnection = new NetConnection();
var ns:NetStream = new NetStream(nc);
var client:Object = new Object();
var swfRatio:Number;
var videoRatio:Number;
function init():void
{
nc.connect(null);
client.onCuePoint = cuePointHandler;
client.onMetaData = metaDataHandler;
ns.client = client;
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressLoader);
addEventListener(Event.ENTER_FRAME, progressTotal);
loader.load(new URLRequest("swf/main.swf"));
ns.play("f4v/main_movie.f4v");
ns.pause();
}
function progressLoader(event:ProgressEvent):void
{
swfRatio = (event.bytesLoaded / event.bytesTotal);
}
function progressTotal():void
{
//Here i get the amount that i want to preload from my video, in this case i want 3mb or 3072000 bytes
videoRatio = (ns.bytesLoaded / 3072000);
//This is a variable that i use to fill my loader asset and verify if my content its totaly loaded.
var frameValue:int = ((videoRatio + swfRatio) / 2) * 100;
if (frameValue >= 100)
{
removeEventListener(Event.ENTER_FRAME, progressTotal);
// Here i close my connection, i suppose that i need to use the same connection in my player.
ns.close();
ns = null;
nc.close();
nc = null;
loaderComplete();
}
}
function loaderComplete():void
{
removeChild(assetLoader);
//Here i add my player to the stage, i want to use the preloaded video with him.
addChild(loader.content);
}
function cuePointHandler(infoObject:Object):void {
trace(infoObject.name);
}
function metaDataHandler(infoObject:Object):void {
trace("metaData");
}
Then in my player that i've just loaded and added to the stage i'm using OSMF to help me with controls.
To test the "preloaded video" i'm doing this:
private var mediaPlayer:MediaPlayerSprite;
private function _init(e:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, _init);
mediaPlayer = new MediaPlayerSprite();
addChild(mediaPlayer);
//And here OSMF start to load the entire main_movie.f4v again.
mediaPlayer.resource = new URLResource("f4v/main_movie.f4v");
}
It looks like your strategy would work if you let the video download completely. I'm assuming if the video downloaded completely, the browser may cache it and make it available to the next NetStream that comes along.
Your strategy looks OK otherwise. What you are doing (playing, then pausing the video immediately) is the way to start buffering the video. But since there are two NetStream's being used (one by the main loader, the other by the OSMF player) this won't work.
Perhaps you can devise a scheme where you pass the NetStream from the main loader into the loaded SWF (main.swf). So that it can use the data it's already downloaded. Just a thought, I've never tried this.
Another idea would be to get the OSMF player in your main.swf to do the buffering. That would mean the buffering would start happening only after main.swf is loaded (which may be too late).
Using ONE Sound() object in Actionscript3, how can I play a one MP3 and then, when the user chooses a different one, play a second sound, using the SAME Sound() object?
EDIT: See my answer for how I did it.
You cannot use same Sound object to play multiple files.
Once load() is called on a Sound object, you can't later load a different sound file into that Sound object. To load a different sound file, create a new Sound object.
Ok, I actually did it using the following code. My bug was somewhere else in the FLA file, but this works. I made an uninitialized global variable and created the Sound() object LOCALLY inside of a function. While I'm technically using multiple sound objects, my references are all pointing to ONE object. Additionally, I can call these methods over one another for easier coding. This works for me:
/* -------------
Sound player
functions
------------ */
var snd:Sound; //the sound object
var sndC:SoundChannel; //the soudchannel used as "controller"
var sndT:SoundTransform; //soundTransform used for volume
var vol:Number = 1; //the volume of the song
var pan:Number = 0; //panning of the sound
var pos:Number = 0; //position of the song
var currentSound:String; //currently playing song?
function playSound(s:String){ //this function resets the sound and plays it
stopSound(sndC); //stop the sound from playing
snd = new Sound(); //reset the sound
snd.load(new URLRequest(s)); //load the desired sound
sndC = new SoundChannel(); //(re-)apply the sound channel
applyVolume(vol,pan,sndT,sndC); //apply the volume
sndC = snd.play(pos); //play it
sndC.addEventListener(Event.SOUND_COMPLETE, startSound); //remind it to restart playing when it's done
} //end function
function applyVolume(n:Number, p:Number, st:SoundTransform, sc:SoundChannel){ //takes an argument for the volume, pan, soundTYransform and soundChannel
sndT = new SoundTransform(n,p); //applies the soundTransfrom settings
sndC.soundTransform = sndT; //and attaches it to the soundChannel
} //end function
function stopSound(sndC:SoundChannel){ //this function stops a sound from playing
if(sndC != null){ //if the sound was used before (ie: playing)
if(currentLabel == "video-frame"){ //if we are in the video frame
pos = sndC.position; //store the position of the song to play from at a later time
}else{ //otherwise
pos = 0; //set the position at 0
} //end if
sndC.stop(); //stop it
} //end if
} //end function
function startSound(snd:Sound){ //restarts a sound when it's playing
if(snd != null){ //if the sound exists
sndC = snd.play(pos); //play it
} //end if
} //end function