如何在使用 Flash 停止播放视频后自动录制视频响应

Posted

技术标签:

【中文标题】如何在使用 Flash 停止播放视频后自动录制视频响应【英文标题】:how to automatically record a video response after the video stops playing using flash 【发布时间】:2016-05-22 04:41:39 【问题描述】:

使用Mediaelementjs,我成功实现了一个视频播放器,并触发一个end event,它立即弹出了一个Adobe Flash Recorder。在网站隐私设置面板中列出网站可以通过浏览器直接访问麦克风和摄像头。

问题: 有没有办法在用户允许访问麦克风和摄像头后触发某些功能,比如开始录制视频?

在用户允许使用闪光灯访问麦克风和摄像头后,我们能否以某种方式立即录制视频。

【问题讨论】:

我没有看到你的问题。在您获得用户使用摄像头和麦克风的授权后,您只需开始录制... 这正是问题所在,我不知道如何启动 flash 的开始录制事件,因为它是一个与 html dom 无关的 flash 事件。 -_- @AlexRumbaNicked 澄清一下:[用户允许的麦克风]在 HTML 端触发的事件,您需要在 Flash 端执行一些 [操作] 作为响应?如果是这样,那么很少有方法可以让页面上的 flash 和 javascript 相互播放。这些并不总是可靠的(从某种意义上说是跨浏览器),但在大多数情况下它们都可以解决问题。如果您对此感兴趣 - 我可以使用通信方法创建答案 [从 HTML 到 Flash,只允许单向] 我知道。 @JoanSparrow 继续前进,伙计,我会调查一下,我尝试过修改,但不得不在动作脚本中编写程序,所以我放弃了,因为时间有限。但是,我们正在考虑使用一些第三方软件。因此,仍然很乐意研究您的解决方法。 @AlexRumbaNicked 你说的“启动 flash 的开始录制事件”是什么意思?您知道 ActionScript 3 吗?您是否知道 Flash Player 将请求独立于浏览器的其 Cam 和/或 Mic 用户的自动化? ...请尝试更多地解释您的目标和当前的问题... 【参考方案1】:

我的回答质量很差,因为我多年前就对 Flash 失去了兴趣。最客气的说法:我的Flash技能生疏了。 (生锈的意思是 Flash-8 ActionScript 2.0 / Flash CS4 ActionScript 2.0 生锈的级别)。真正的问题是什么 - 我目前的计算机上没有 Flash 测试环境。因此,这将是一个盲目的建议。当心错误。

但是,从好的方面来说,我确实有集成 Flash 和 Javascript 的经验。在我看来,其中一些仍然是相关的。

我知道的技术的简短列表:

Javascript 到 Flash:

    Flash 提供的ExternalInterface 对象允许Javascript 在Flash 内部执行方法 - 这可以开始动画或返回数据。 缺点:ExternalInterface 可能会被安全设置或插件的错误实现所禁止。

    document.getElementById('exampleMovie').SetVariable("someVariableName", "some text"); - 将其用作消息系统 - 添加正在监听的 Flash 计时器 - 变量有变化吗

Flash 到 Javascript:

    Flash 提供的ExternalInterface 对象允许Flash 从Javascript 执行函数。 缺点:ExternalInterface 可能会被安全设置或插件的错误实现所禁止。

    getUrl('javascript:someJavascriptFunction("a", "b", true);'); 我不确定它是否出于安全原因被禁止,但 它可以工作。主要缺点是它是一种单向交互。

我认为使用外部接口是实现交互的最合乎逻辑的方式。

是的,你可以使用单向交互 2. 和 2. 来构建通信协议 - 我什至可以想象那个系统......但这有点太不正常了 ^ ^。 + 我找不到任何有关“SetVariable”浏览器支持的数据。 + *** 报告了 SetVariable 在 Firefox 中的奇怪行为SetVariable is not working in Firefox


这里是外部接口的官方文档: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html

该页面有一个浏览器兼容性表。也许文档需要更新 - 没有 Google Chrome 的痕迹,这在我看来很奇怪......

从概念上讲,您可以像这样使用外部接口:

// HTML
// id must be equal to name here
// and shouldn't contain symbols . - + * / \
<object id="exampleFlash" name="exampleFlash" ... >
    ...
</object>

// Javascript:
document.getElementById('exampleFlash').methodExposedForJavascript('value')

// ActionScript in Flash:
import flash.external.ExternalInterface;
ExternalInterface.addCallback( "methodExposedForJavascript", someInternalFunction );
function someInternalFunction( msg ) 
    // do something with msg - for example output it to existing txt field:
    _root.txtExampleTxt.text = msg;

最相关的示例是该手册页上的最后一个示例http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html

如何编译这样的复杂示例的简短说明:http://help.adobe.com/en_US/as3/dev/WS9b644acd4ebe5999-2734bf3c124372a52ff-8000.html

它们实际上很简单。大多数感知到的复杂性来自于它们以编程方式生成 Flash 元素的事实——比如

// all that this code does - is creating simple TextField in your movie
import flash.text.TextField;
package  
    public class ABC extends Sprite 
    
        private var output:TextField;
        public function ABC() 
        
            output = new TextField();
            output.y = 25;
            output.width = 450;
            addChild(output);
        
    

这样做是为了使示例更易于表达 - 但这与“使用您的 GUI 在第一帧中创建名为 output 的文本字段”基本相同。

我将尝试删除该示例中不需要的任何内容。 注意“receivedFromJavaScript” - 这是一个将由Javascript触发的功能 - 你可以在里面添加反应。

Flash部分:

package  

    import flash.display.Sprite;
    import flash.events.*;
    import flash.external.ExternalInterface;
    import flash.text.TextField;
    import flash.utils.Timer;
    import flash.text.TextFieldType;
    import flash.text.TextFieldAutoSize;
    import flash.system.Security;

    public class ExternalInterfaceExample extends Sprite 
    
        private var output:TextField;

        public function ExternalInterfaceExample() 
        
            // constructor code
            Security.allowDomain("*");


            output = new TextField();
            output.y = 25;
            output.width = 450;
            output.height = 325;
            output.multiline = true;
            output.wordWrap = true;
            output.border = true;
            output.text = "Initializing...\n";
            addChild(output);


            if (ExternalInterface.available) 
                try 
                    output.appendText("Adding callback...\n");
                    ExternalInterface.addCallback("sendToActionScript", receivedFromJavaScript);
                    if (checkJavaScriptReady()) 
                        output.appendText("JavaScript is ready.\n");
                     else 
                        output.appendText("JavaScript is not ready, creating timer.\n");
                        var readyTimer:Timer = new Timer(100, 0);
                        readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
                        readyTimer.start();
                    
                 catch (error:SecurityError) 
                    output.appendText("A SecurityError occurred: " + error.message + "\n");
                 catch (error:Error) 
                    output.appendText("An Error occurred: " + error.message + "\n");
                
             else 
                output.appendText("External interface is not available for this container.");
            
        
        private function receivedFromJavaScript(value:String):void 
            output.appendText("JavaScript says: " + value + "\n");
        
        private function checkJavaScriptReady():Boolean 
            var isReady:Boolean = ExternalInterface.call("isReady");
            return isReady;
        
        private function timerHandler(event:TimerEvent):void 
            output.appendText("Checking JavaScript status...\n");
            var isReady:Boolean = checkJavaScriptReady();
            if (isReady) 
                output.appendText("JavaScript is ready.\n");
                output.appendText("ExternalInterface.objectID = " + ExternalInterface.objectID + "\n");
                Timer(event.target).stop();
            
        
    

HTML:

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ExternalInterfaceExample</title>
<script>
    var jsReady = false;
    function isReady() 
        return jsReady;
    
    function pageInit() 
        jsReady = true;
        document.forms["form1"].output.value += "\n" + "JavaScript is ready.\n";
    
    function sendToActionScript(value) 
        document.getElementById("ExternalInterfaceExample").sendToActionScript(value);
    
</script>
</head>
<body onload="pageInit();">

<object id="ExternalInterfaceExample"  name="ExternalInterfaceExample" 
type="application/x-shockwave-flash" data="ExternalInterfaceExample.swf"  >
<param name="movie" value="ExternalInterfaceExample.swf"/>
<param name="quality" value="high"/>
<param name="allowscriptaccess" value="always"/>
<a href="http://www.adobe.com/go/getflash">
    <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" />
</a>
</object>

    <form name="form1" onsubmit="return false;">
        <input type="text" name="input" value="" />
        <input type="button" value="Send" onclick="sendToActionScript(this.form.input.value);" /><br />
        <textarea cols="60" rows="20" name="output" readonly="true">Initializing...</textarea>
    </form>

</body>
</html>

【讨论】:

我已经实现了这一点,但是出现的问题是闪存文件的逆向工程。将文件修改并重新编译为 swf 后,我无法生成工作文件。为你的努力点赞。 这是一个悲伤的故事。如果您正在玩逆向工程,这意味着您没有源文件和说明 - 在哪个 Flash 版本中以及使用哪个 ActionScript-version 编译它? 如果我没记错的话,flash 可以动态加载其他 Flash 电影。有时这可能会导致错误——当那些“客串”电影中的代码严格依赖于它们是 _root 的假设时。但大多数情况下,大多数“客串”电影都可以以客串的身份存在——很好。所以黑客是 - 你创建自己的电影做了两件事 - 1. 它加载了“不可能逆向工程”的客座电影 - 2. 它与你的 Javascript 事件对话。 这正是问题所在,我没有实际的源文件,我只有 swf 文件,否则使用 as3 proj 会更容易。但是,您的答案值得被打勾,我现在将不得不使用第三方 api 重构整个架构。

以上是关于如何在使用 Flash 停止播放视频后自动录制视频响应的主要内容,如果未能解决你的问题,请参考以下文章

如何录制视频并保持音乐在后台播放?

网页插入SWF视频,如何带有播放控制按钮、进度条等!

Red5视频流录制正在中断

如何在网站上显示类似YouTube的视频播放器?

在同一视频标签上录制和播放时 MediaStream 关​​闭

网络录制的视频未在 ipad 中播放