【问题标题】:ActionScript 3.0 Switching Video by pressing a keyActionScript 3.0 通过按键切换视频
【发布时间】:2017-08-16 09:25:45
【问题描述】:

我正在编写一个简单的程序,当我按下两个不同的键时,它会从一个视频切换到另一个。如果我按 F 键将显示视频 1,如果按 2 键将显示视频 2。如果按 F 或 2 键将显示视频 1 或视频 2,我在两个视频之间切换。我有个问题。如果我快速按下 2 和 F fps 开始下降,快速按下 2 和 F 后 .swf 崩溃。我认为这是我的代码的问题,因为它没有优化。基本思想是,每当用户在显示视频时按 F 或 2 键时,我都会关闭该视频的流并开始流式传输另一个视频,依此类推。这是代码:

package {
import flash.display.MovieClip;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.AsyncErrorEvent;
import flash.media.Video;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.utils.getTimer;


public class MainDisplayDifferentVideoOnCLick extends MovieClip {

    public function MainDisplayDifferentVideoOnCLick() {
        keyPressed();
        fpsNumber();

    }
    public function keyPressed(): void {
        stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        function onKeyDown(myKey: KeyboardEvent): void {
            if (myKey.keyCode == 70) {
                playVideo1();
            }
            if (myKey.keyCode == 50) {
                playVideo2();
            }
        }
    }

    function playVideo1(): void {
        var networkConnection: NetConnection = new NetConnection();
        networkConnection.connect(null);
        var networkStream: NetStream = new NetStream(networkConnection);
        networkStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
        networkStream.play("Damiani.mp4");
        function errorHandler(error1: AsyncErrorEvent): void {
            // ingoro l' evento
        }
        var myVideo1: Video = new Video();
        myVideo1.attachNetStream(networkStream);
        myVideo1.width = 1920;
        myVideo1.height = 1080;
        addChild(myVideo1);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, on2Down);
        function on2Down(ev: KeyboardEvent): void {
            if (ev.keyCode == 50) {
                networkStream.close();
            }
        }

    }
    function playVideo2(): void {
        var networkConnection: NetConnection = new NetConnection();
        networkConnection.connect(null);
        var networkStream: NetStream = new NetStream(networkConnection);
        networkStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
        networkStream.play("Sfelab.mp4");
        function errorHandler(error1: AsyncErrorEvent): void {
            // ingoro l' evento
        }
        var myVideo2: Video = new Video();
        myVideo2.attachNetStream(networkStream);
        myVideo2.width = 1920;
        myVideo2.height = 1080;
        addChild(myVideo2);

        stage.addEventListener(KeyboardEvent.KEY_DOWN, onFDown);
        function onFDown(ev: KeyboardEvent): void {
            if (ev.keyCode == 70) {
                networkStream.close();
            }
        }
    }
    public function fpsNumber(): void {
        var frames: int = 0;
        var prevTimer: Number = 0;
        var curTimer: Number = 0;

        this.addEventListener(Event.ENTER_FRAME, performFrameTest);

        function performFrameTest(e: Event): void {
            frames += 1;
            curTimer = getTimer();
            if (curTimer - prevTimer >= 1000) {
                trace("FPS: ");
                trace(Math.round(frames * 1000 / (curTimer - prevTimer)));
                prevTimer = curTimer;
                frames = 0;
            }
        }
    }
}

}

你有什么建议吗?谢谢!

【问题讨论】:

  • 不要在函数内部声明函数。然后,改变逻辑。使唯一的方法 playVideo 接受视频 url。如果 url 是当前正在播放的 url,什么也不做。如果 url 不同,请关闭当前视频并开始新视频。然后制作 KEY_DOWN 监听器,它只使用相关的 url 调用上面的方法。您可能还想在按键和实际更改视频之间设置一定的超时时间,例如 100 毫秒。用户不会注意到,但这对程序来说是一种解脱。
  • 您需要同时加载两个视频,然后通过隐藏其中一个来切换(使用.visible=false;)并使用soundTransform 关闭不可见的声音i> 视频。此外,每次按下按键时,您都不需要在 RAM 中创建 new 任何东西。只需为视频播放一次创建一个设置,然后重复使用(例如:您的 playVideoX 函数应该只是 .play("fileName"),而不是添加更多 new netStream's 和 new netConnection' s(如果创建太多,您的应用会崩溃)

标签: actionscript-3 flash video video-processing frame-rate


【解决方案1】:

如果你想让两件事在你的程序中做同样的事情。不要只是复制粘贴适用于单一事物的代码。例如,您可以对任意数量的视频使用单个视频实例。

目前尚不清楚您是否真的想关闭视频,然后在选择回来后重新开始,或者只是在播放之间快速切换。下面的代码做第二件事,但我希望很清楚如何修改它。 当然,如果您想拥有返回到流的功能,则无需在选择另一个流后立即停止流。

package adnss.projects.tchqs 
{
    import flash.display.MovieClip;
    import flash.events.KeyboardEvent;
    import flash.media.Video;
    import flash.ui.Keyboard;

    public class Main extends MovieClip {

        /**List of all video streams that suppose to played.**/
        private var vids:Vector.<VideoPlayback> = Vector.<VideoPlayback>(
        [new VideoPlayback("AlexD.mp4", Keyboard.F),
         new VideoPlayback("Nike AIR.mp4", Keyboard.NUMBER_2)]);

        /**Current video playback. Should be one of "vids" items.**/
        private var currVid:VideoPlayback;
        /**Common Video view used to display stream on stage.**/
        private var _video:Video = new Video();

        public function Main() {
            prepareVideoView(1680, 1050);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
        }

        /**Hangles switching between videos accordingly to key that was pressed.**/
        private function onKDown(e:KeyboardEvent): void {
            for each (var vp:VideoPlayback in vids) {
                if (vp.keyCode != e.keyCode) continue; //not our key
                if (vp == currVid) return; //the video of hited key is already playing - not need to change.
                if (currVid) currVid.stream.pause(); //If you stat fist video by default, you can remove if(...)
                if (!vp.stream) vp.openStream(); //open stream if not oppened already.
                _video.attachNetStream(vp.stream); //change stream of our video view.
                vp.stream.resume(); //I hope it's clear what "vp" is...
                currVid = vp; return;  
            }
        }

        /**
         * Setup _video:Video view and adds it to stage.
         * @param   w width of video view.
         * @param   h height of video view.
         */
        private function prepareVideoView(w:Number, h:Number) {
            _video.width = w;
            _video.height = h;
            stage.addChild(_video);
        }

    }

}
import flash.events.AsyncErrorEvent;
import flash.net.NetConnection;
import flash.net.NetStream;

/**
 * This class define particular video playback - bind video address to shortcut key,
 * and opens unique stream for it if necessary. 
 */
class VideoPlayback {
    private var _adrs:String;
    private var _kCode:uint;
    private var _s:NetStream;

    public function VideoPlayback(adress:String, keyCode:uint) {
        _adrs = adress;
        _kCode = keyCode;
    }

    /**Open NetStream for this playback accordingly to video adress passed in constructor.
     * Until this method is called "stream" property is not available.**/
    public function openStream() {
        var c: NetConnection = new NetConnection();
        c.connect(null);
        _s = new NetStream(c);
        _s.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
        _s.play(_adrs);
        function errorHandler(error1: AsyncErrorEvent): void {
            // ingoro l' evento
        }
    }

    public function get adress():String{return _adrs;}

    public function get keyCode():uint{return _kCode;}

    public function get stream():NetStream{return _s;}
}

请注意 VideoPlayback 类在包之外。它可以在一个文件中正常工作,但您可能希望将其移动到单独的文件中,以便让事情更有条理。

【讨论】:

  • 我的目标是,当我按 F 或 2 键更改视频时,我开始流式传输相应的视频,但我不想从中断的点开始流式传输.对不起,我的英语不好,我希望你能理解。!谢谢!
  • vp.stream.play(vp.adress); 替换vp.stream.resume(); 对您不起作用吗?
  • 我尝试使用您的代码,但它不起作用。我的意思是,如果我按 2 或 F 键没有任何反应。我在另一个文件中创建了 VideoPlayback 类,并在主类中导入了 VideoPlayback 类。您能帮我找到解决方案吗?谢谢!
  • 好的,那么你是如何测试它的呢?你的设置是什么?你有跟踪输出表单onKDown 功能吗?如果它对我有用,我无法猜测如何解决您的问题...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多