Actionscript 3 使用AS3录制和回放动作

Actionscript 3 使用AS3录制和回放动作,actionscript-3,audio,drawing,record,audiovideoplayback,Actionscript 3,Audio,Drawing,Record,Audiovideoplayback,我正在制作一个绘图应用程序,允许用户在画布上自由绘图,在坐标x,y的特定范围内会有声音出来。我的目标是允许用户稍后录制和回放整个动作,并像观看视频一样观看。虽然我能让画笔正常工作,但我在录音和回放部分有问题,特别是内部音频的录音。我已经搜索了很长时间,我发现这与我的概念非常相似 这是一个伟大的例子,我发现这是由罗尼所做的 资料来源: 我有没有办法将钢琴键替换为绘图笔划,根据坐标生成声音,并像示例一样记录和播放笔划和声音 我在试图找到一种方法时感到困惑和困惑。如果您可以执行代码来绘制笔划,那么您所

我正在制作一个绘图应用程序,允许用户在画布上自由绘图,在坐标x,y的特定范围内会有声音出来。我的目标是允许用户稍后录制和回放整个动作,并像观看视频一样观看。虽然我能让画笔正常工作,但我在录音和回放部分有问题,特别是内部音频的录音。我已经搜索了很长时间,我发现这与我的概念非常相似

这是一个伟大的例子,我发现这是由罗尼所做的 资料来源:

我有没有办法将钢琴键替换为绘图笔划,根据坐标生成声音,并像示例一样记录和播放笔划和声音


我在试图找到一种方法时感到困惑和困惑。

如果您可以执行代码来绘制笔划,那么您所需要做的就是为这些笔划命令的执行添加时间戳。有很多方法可以实现这一点。我已经为你写了一个例子

您可以将其粘贴到新的Flash文档中并运行它

/* First we'll create some variables */

var recording:Array = new Array(); // This is where we'll store all the instances of user action.
var playStart:Number = 0; // Playback will depend on whether this variable is greater than 0.
stage.addEventListener(Event.ENTER_FRAME, tic); // This will run once every frame update.

/* Next we'll create some helper functions */

function createButton(name:String, hue:uint):MovieClip {
    // We'll use this to make some fancy buttons.
    var box:MovieClip = new MovieClip();
    var shape:Sprite = new Sprite();
    shape.graphics.beginFill(hue);
    shape.graphics.drawRect(0, 0, 100, 25);
    box.addChild(shape);

    var txt:TextField = new TextField();
    txt.text = name;
    txt.x = 10;
    txt.y = 3;
    txt.mouseEnabled = false;
    box.addChild(txt);

    return box;
}

function drawCircle(X:Number, Y:Number, Hue:uint = 0x000000):void {
    // This creates circles on stage.
    var circle:Shape = new Shape();
    circle.graphics.beginFill(Hue);
    circle.graphics.drawCircle(0, 0, 10);
    circle.graphics.endFill();
    circle.x = X;
    circle.y = Y;
    addChild(circle);
}


/* Now lets create some buttons; Record, Stop, and Play. And rig'em up to some actions. */

var recordBtn:MovieClip = createButton("Record", 0x10ab00);
addChild(recordBtn);
recordBtn.addEventListener("mouseUp", startRecording);

var stopRecordBtn:MovieClip = createButton("Stop", 0xe90000);
stopRecordBtn.x = 101;
addChild(stopRecordBtn);
stopRecordBtn.addEventListener("mouseUp", stopRecording);

var playBtn:MovieClip = createButton("Play", 0x0069ab);
playBtn.x = 202;
addChild(playBtn);
playBtn.addEventListener("mouseUp", playRecording);


/* In the same order, we'll create those functions */

function startRecording(e:Event):void {
    // Here we'll store a timestampe of when the recording started.
    recording[0] = flash.utils.getTimer();
    // Register for mouseclicks on the stage; we need some kind of input to track.
    stage.addEventListener("mouseUp", recordAction);
}

function stopRecording(e:Event):void {
    // Conversely, we stop recording by not listening anymore.
    stage.removeEventListener("mouseUp", recordAction);
}

function playRecording(e:Event):void {
    // Just like recording, we keep track of when we started.
    playStart = flash.utils.getTimer();
}


function recordAction(e:Event):void {
    if (recording.length >= 1) {
        // First, we create the timestamp, and other relavent info.
        var tick:Object = {
            "time":flash.utils.getTimer(),
            "x":e["stageX"],
            "y":e["stageY"]
        }

        // And store it in our numerical index
        recording.push(tick);
        trace("Time: " + (tick.time - recording[0]) + " Coords: " + tick.x + "," + tick.y);

        // Then we do whatever action we were supposed to do (draw line, play sound, etc.).  Here, we'll draw a circle at the mouse coordinates.
        drawCircle(tick.x, tick.y);
    }
}

function tic(e:Event):void {
    if (playStart > 0) { // Assuming we've indexed a start time...
        if (recording.length > 1) { // and we actually have actions to playback.
            // We'll first normalize those bizzare numbers to a zero starting number.
            var nextAction:Number = recording[1].time - recording[0];
            var playHead:Number = flash.utils.getTimer() - playStart;
            if (playHead > nextAction) {
                // Now that we've matched the time, we execute the same action we did before.
                drawCircle(recording[1].x, recording[1].y, 0xFFFFFF);
                // ... and in this example, I'm removing that instance since we no longer need it.
                recording.splice(1, 1);
            }
        } else {
            // If the length of the recording reaches zero, we'll automatically stop playback too.
            playStart = 0;
        }
    }

}

如果它正在记录基于鼠标移动的绘图笔划以及基于坐标生成的声音,这将生成大量数据,那么这组代码能够处理它吗?基本上,我的应用程序将非常类似于流行的应用程序:画一些东西,只是它可以播放声音。这是一个例子的基本步骤,你可以在编写你的应用程序。虽然这是一个很好的起点,但这段代码的有效性完全取决于您编写高效代码的能力。很有可能,您不需要存储录制的声音,而需要存储播放声音的操作(想想“保存乐谱”而不是“磁带录音”)。同样,如果鼠标事件驱动了所有这些,那么您只需要存储这些鼠标事件。我提前告诉您,这样以后就不会感到意外:当快进、慢进(或倒带)时,您必须将声音静音。