ActionScript 3.0 通过按键切换视频

Posted

技术标签:

【中文标题】ActionScript 3.0 通过按键切换视频【英文标题】:ActionScript 3.0 Switching Video by pressing a key 【发布时间】: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(如果创建太多,您的应用会崩溃) 【参考方案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():Stringreturn _adrs;

    public function get keyCode():uintreturn _kCode;

    public function get stream():NetStreamreturn _s;

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

【讨论】:

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

以上是关于ActionScript 3.0 通过按键切换视频的主要内容,如果未能解决你的问题,请参考以下文章

(ActionScript 3.0)我的函数没有通过按钮事件更新全局变量

[ActionScript 3.0] 通过内联函数对addFrameScript方法传递参数

Actionscript 3.0 中的 MovieClip 与 Sprite

使用 javascript 与 actionscript 3.0 交互

ActionScript 3.0 套接字无法重新连接

如何在 ActionScript 3.0 中写入文本文件?