as3 + red5/fms: recording audio from soundmixer - actionscript-3

i'm wondering if there's a way to record live audio from flash' SoundMixer (NOT from the microphone).
Might be a simple question but i'm a noob with red5/fms technologies and can't find anything online that answers my question :\
TIA for your attention.

There's a lot involved in getting this all working, but the core of the solution is to configure your Flash app to:
Create a NetConnection object
Create a NetStream object, passing the NetConnection to the constructor
Call your NetStream object's attachAudio method, passing it an instance of whatever audio source you want to use.
When you want to stop recording, simply close the NetStream object.
in code, that would look something like:
private var myMic:Microphone;
private var nc:NetConnection;
private var ns:NetStream;
// get connected
private function get_connected():void {
nc = new NetConnection();
nc.connect("rtmp://your.domain.tld:1935");
}
// get audio source
private function init_audio():void {
myMic = Microphone.getMicrophone();
}
// start recording
private function start_recording(fileName:String):void {
ns = new NetStream(nc);
ns.attachAudio(myMic);
ns.publish(fileName, "record");
}
// stop recording
private function stop recording():void {
ns.play(false); // flushes the recording buffer
ns.close();
}
I realize that's a pretty broad overview, but it's a pretty broad topic. Please comment if you have questions on the specifics.

Related

TotalTime of a stream - Video Flash Player AS3

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.

How to stop sound in the middle of playing

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

Sounds play delay wrong

I am writing simple metronome component using Flex + AS3. I want it playing 'tick1' sound after, for example, each 500 millisecond and each 4th time plays another sound 'tick2'. But actually delay between sound is not equivalent - sometimes lesser, sometimes greater a bit. I testing it on latest Chrome.
Here my code:
//Somewhere here button bound to the 'toggle' function
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.media.SoundTransform;
import flash.media.SoundChannel;
private var bpm:Number = 120; //2 bit per second, delay=500ms
private var period:Number = 4;
private var timer:Timer = new Timer(bpm, period);
[Embed(source='sounds/1.mp3')]
private var tickSound1Class:Class;
private var tickSound1:Sound;
[Embed(source='sounds/2.mp3')]
private var tickSound2Class:Class;
private var tickSound2:Sound;
private var trans:SoundTransform = new SoundTransform(1);
private function init():void {
....
tickSound1 = new tickSound1Class() as Sound;
tickSound2 = new tickSound2Class() as Sound;
update();
timer.addEventListener(TimerEvent.TIMER, onTimerEvent);
....
}
private function update():void {
timer.delay = 1000 * 60/bpm;
timer.repeatCount = 0;
}
private function toggle():void {
if (timer.running) {
timer.reset();
startStopButton.label = "Start";
} else {
update();
timer.start();
startStopButton.label = "Stop";
}
}
private function onTimerEvent(event:TimerEvent):void {
var t:Timer = event.currentTarget as Timer;
if (t.currentCount % period == 0)
tickSound1.play(0, 0, trans);
else
tickSound2.play(0, 0, trans);
}
I think there are two main reasons:
It is known that Timer object in Flash Player is inaccurate, delay between it's fires fluctuates.
Sound.play() method also introduces some delay before the sound actually starts to play, and theoretically this delay can fluctuate. The delay is especially noticeable in PPAPI version of Flash Player being used in Chrome.
There are several solutions. I would suggest one of these:
Use pre-composed sound of the whole metronome cycle (tick1-pause1-tick2-pause2) and just loop it using the second argument of Sound.play() method;
use dynamic sound generation.
The second option is more flexible but is more difficult to implement. Basicaly, you'll need to create a new instance of Sound object, subscribe to it's SAMPLE_DATA event and call it's play() method. In the handler you'll check event.position / 44.1, which will give you current position of sound generation in ms. Then, if you decide that it's time to play tick1 or tick2 sound, you'll call tickN.extract(event.data, ...), where tickN is tick1 or tick2 Sound object, or write the silence otherwise.
You can read more about dynamic sound generation here.
Also, notice that when you call Sound.play() it returns a SoundChannel object, which has the position property. Is it a position in ms of a sound that is being played (not generated) at the moment, and it is accurate. So, using this property, you can come up with the third approach: create a Sound object and setup a SAMPLE_DATA handler like in the dynamic sound generation solution, but write the silence (zeros) to the event.data object inside the handler all the time. This is needed to obtain a sound channel without actually playing a sound. Then, use high frame rate (60 FPS) and a Timer with the smallest possible delay (1 ms). Each time the Timer fires, check soundChannel.position to determine whether it is time to play the tick sound, and, if it so, just play it like you're doing in your example. This approach is likely to solve the problem of the Timer inaccuracy, but it cannot deal with the delay caused by tickSound.play() method.

AS3 Code - Sound not playing

I'm trying to play sound in as3 code using an external mp3 file.
So here's the code I am using:
private function playSound():void
{
trace("loading sound");
var mySound:Sound = new Sound();
mySound.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
mySound.load(new URLRequest("Menu.mp3"));
mySound.play();
trace("playing sound");
}
private function handleIOError(evt:IOErrorEvent):void
{
//handle error if needed
}
The music just doesn't play at all.
The traces "loading sound" and "playing sound" appear so the code is being run.
The mp3 file Menu.mp3 is in the same folder as the .fla file used to run the project. Is this the correct directory? I tried moving it around but still couldnt play the sound.
Any help will be appreciated, thanks!
I have a few suggestions that might help:
Declare mySound as a class level property. The garbage collector might be disposing of the variable prematurely since it is local.
mySound.play() returns a SoundChannel object. Try storing this in a class level property.
Add an event listener to the sound for Event.COMPLETE, right before loading the sound. Try playing the sound after this event occurs. As it is, you might be trying to play the sound before it has loaded.
private var mySound:Sound;
private var mySoundChannel:SoundChannel;
private function playSound():void
{
mySound = new Sound();
mySound.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
mySound.addEventListener(Event.COMPLETE, handleLoadCompletion);
mySound.load(new URLRequest("Menu.mp3"));
}
private function handleLoadCompletion(evt:Event):void
{
mySoundChannel = mySound.play();
}
private function handleIOError(evt:IOErrorEvent):void
{
//handle error if needed
}
Edit:
After reviewing the docs, I think that suggestion 3 isn't necessary.

AS3 playing audio and looping it

I'm trying to get an audio file to play in the background of my project but so far have been unsuccessful so far. Heres what I've gotten so far.
package {
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.media.*;
public class Music extends MovieClip {
// Create a sound
private var music:Sound;
// Use a URLRequest for file path
private var request:URLRequest;
// Create a sound buffer
private var buffer:SoundLoaderContext;
// Create a sound channel
private var channel:SoundChannel;
public function Music() {
// constructor code
//Instantiate all sound objects
buffer = new SoundLoaderContext(1000);
request = new URLRequest("SMB3-Grassland-Map.mp3");
music = new Sound(request, buffer);
// Play music and assign it to a channel
channel = music.play();
// Add an event listener to the channel
channel.addEventListener(Event.SOUND_COMPLETE, loopMusic);
}
// playMusic method restarts music
private function playMusic()
{
channel = music.play();
channel.addEventListener(Event.SOUND_COMPLETE, loopMusic);
}
// Channel event listener call playMusic method
private function loopMusic(e:Event)
{
if (channel != null)
{
channel.removeEventListener(Event.SOUND_COMPLETE, loopMusic);
playMusic();
}
}
}
}
this is just to play an external audio file and have it continually loop.
Rather than having an event listener that plays the sound again upon sound complete, you can add parameters to the .play() method. The first parameter indicates at what point in the sound you would like it to begin playing, the second parameter indicates how many times you would like it to play, and the third is used if you want to apply sound transform. In your case you can do .play(0, int.MAX_VALUE); this will give you the continuous loop you are looking for.
"the problem is it's not playing anything at all."
I copied your code and created an AS3 class file (substituting my own local MP3 URL)
Then created an AS3 file with the following:
import Music;
var mus:Music = new Music();
and ran it. The sound played and looped correctly.
It's working for me, so maybe that's why there are no errors. Sorry for the question but are your speakers on; is your system playing sound from another source... cd, mp3 player?
I've used the play(0, 1000); #Goose mentioned and it worked great; simple and effective.