Actionscript 3 使用Google Chrome的Flash Player中的空摄像机名称

Actionscript 3 使用Google Chrome的Flash Player中的空摄像机名称,actionscript-3,flash,google-chrome,camera,Actionscript 3,Flash,Google Chrome,Camera,所以,似乎我们在与谷歌Chrome PPAPI集成的Flash Player中遇到了另一个设备、摄像头和麦克风的问题。许多Flash开发人员都能记住并修复Google Chrome中实现的这个问题。现在,如果你有一些使用相机或麦克风的应用程序,谷歌浏览器用户必须允许访问他们的设备两次:对于Flash Player,以Flash对象为中心的小窗口;对于谷歌浏览器,地址栏下有按钮的灰色面板 直到最近,授予摄像头访问权限的整个过程都是这样的: 应用程序希望将摄像头连接到视频对象或NetStream。

所以,似乎我们在与谷歌Chrome PPAPI集成的Flash Player中遇到了另一个设备、摄像头和麦克风的问题。许多Flash开发人员都能记住并修复Google Chrome中实现的这个问题。现在,如果你有一些使用相机或麦克风的应用程序,谷歌浏览器用户必须允许访问他们的设备两次:对于Flash Player,以Flash对象为中心的小窗口;对于谷歌浏览器,地址栏下有按钮的灰色面板

直到最近,授予摄像头访问权限的整个过程都是这样的:

应用程序希望将摄像头连接到视频对象或NetStream。 即使未经许可,您也可以获取相机名称并填充一些 使用它们的UI组件。 Flash Player显示带有允许和拒绝按钮的安全面板。 谷歌Chrome展示了它自己的安全面板,所以两个安全面板 同时可见。 用户按下Flash Player安全面板中的允许按钮。 现在,camera.muted属性为false,但camera显示为零 FPS,因为在浏览器中仍然拒绝访问。 用户按下浏览器安全面板中的允许按钮。 赢您可以访问任何地方。 当然,谷歌Chrome的第二个安全面板真的很痛苦。用户只是没有注意到而已。Flash开发人员在应用程序和FAQ页面中通过提示处理了这个问题。但现在我们有另一个大问题

最近,授予摄像头访问权限的过程更改为: 应用程序希望将摄像头连接到视频对象或NetStream

在浏览器中授予访问权限之前,您无法获取相机名称。那里 将仅为空格,camera.name中带有代码32的符号 所有物 Flash Player显示带有允许和拒绝按钮的安全面板。 Google Chrome在获得访问权限之前不会显示其安全面板 在Flash播放器中。 用户按下Flash Player安全面板中的允许按钮。 现在,camera.muted属性为false,但camera显示为零 FPS和没有名称,因为在浏览器中仍然拒绝访问。 谷歌浏览器展示了它自己的安全面板。 用户按浏览器安全面板中的允许按钮此面板 出于某种原因显示了两次。 现在,您可以在任何地方访问,但设备仍然只有 空格而不是实名。 不幸的是,在浏览器中授予访问权限后,AS3将不会更新相机名称。在授予浏览器访问权限之前,Flash Player设置窗口中的相机名称为空事件。所以,现在要在运行于谷歌Chrome的Flash应用程序中获得相机名称而不重新加载是不可能的。用户需要先在浏览器中授予访问权限,然后重新加载应用程序,只有在这之后,我们才能在AS3中获得相机名称。我曾尝试使用flash.media.scanHardware刷新相机名称,但似乎不起作用。 我还创建了一个小示例,并将其发布到网上:

你可以在谷歌浏览器上自己测试。只是别忘了每次都要明确你的选择。您需要从上的列表中删除wonderfl.net条目chrome://settings/contentExceptionsmedia-stream 清除你以前的选择。 我还收到了Opera用户的类似投诉

这是我的密码:

package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.media.Camera;
    import flash.media.Microphone;
    import flash.media.Video;
    import flash.media.scanHardware;
    import flash.text.TextField;
    import flash.utils.Timer;

    public class BrowserPermissionTest extends Sprite
    {
        private var output:TextField;
        private var timer:Timer;

        public function BrowserPermissionTest()
        {
            super();

            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        private function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);

            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            output = new TextField();
            output.border = true;
            output.multiline = true;
            output.wordWrap = true;
            output.x = output.y = 10;
            addChild(output);

            updateView();
            stage.addEventListener(Event.RESIZE, stage_resizeHandler);

            var i:int;
            var numCameras:int = 0;
            var numMicrophones:int = 0;

            if (Camera.isSupported)
            {
                var cameraNames:Array = Camera.names;
                numCameras = cameraNames ? cameraNames.length : 0;
                if (numCameras > 0)
                {
                    log("Cameras:");
                    for (i = 0; i < numCameras; i++)
                    {
                        var cameraName:String = cameraNames[i];
                        log((i + 1) + ". \"" + cameraName + "\"");
                    }
                }
                else
                {
                    log("Camera not found.");
                }
            }
            else
            {
                log("Camera is not supported.");
            }

            log("");

            if (Microphone.isSupported)
            {
                var microphoneNames:Array = Microphone.names;
                numMicrophones = microphoneNames ? microphoneNames.length : 0;
                if (numMicrophones > 0)
                {
                    log("Microphones:");
                    for (i = 0; i < numMicrophones; i++)
                    {
                        var microphoneName:String = microphoneNames[i];
                        log((i + 1) + ". \"" + microphoneName + "\"");
                    }
                }
                else
                {
                    log("Microphone not found.");
                }
            }
            else
            {
                log("Microphone is not supported.");
            }

            log("");

            if (numCameras > 0 || numMicrophones > 0)
            {
                if (numCameras > 0)
                {
                    var defaultCamera:Camera = Camera.getCamera();
                    var video:Video = new Video(1, 1);
                    addChild(video);
                    video.attachCamera(defaultCamera);
                    defaultCamera.muted ? devicesMutedInFlashPlayer() : devicesUnmutedInFlashPlayer();
                }
                else if (numMicrophones > 0)
                {
                    var defaultMicrophone:Microphone = Microphone.getMicrophone();
                    defaultMicrophone.setLoopBack(true);
                    defaultMicrophone.muted ? devicesMutedInFlashPlayer() : devicesUnmutedInFlashPlayer();
                }
                else
                {
                    log("No devices found for test.");
                }               
            }
        }

        private function devicesMutedInFlashPlayer():void
        {
            log("Devices are muted in Flash Player.");
            log("Starting permission check timer...");

            timer = new Timer(100);
            timer.addEventListener(TimerEvent.TIMER, flashPlayerPermissionTimer_timerHandler);
            timer.start();
        }

        private function flashPlayerPermissionTimer_timerHandler(event:TimerEvent):void
        {
            var defaultCamera:Camera = Camera.getCamera();
            if (!isDevicesMutedInFlashPlayer())
            {
                timer.stop();
                timer.removeEventListener(TimerEvent.TIMER, flashPlayerPermissionTimer_timerHandler);
                timer = null;

                devicesUnmutedInFlashPlayer();
            }
        }

        private function devicesUnmutedInFlashPlayer():void
        {
            log("Devices are unmuted in Flash Player.");
            isDevicesMutedInBrowser() ? devicesMutedInBrowser() : devicesUnmutedInBrowser();
        }

        private function devicesMutedInBrowser():void
        {
            log("Devices are muted in browser.");
            log("Starting permission check timer...");

            timer = new Timer(100);
            timer.addEventListener(TimerEvent.TIMER, browserPermissionTimer_timerHandler);
            timer.start();
        }

        private function browserPermissionTimer_timerHandler(event:TimerEvent):void
        {
            scanHardware();
            if (!isDevicesMutedInBrowser())
            {
                timer.stop();
                timer.removeEventListener(TimerEvent.TIMER, browserPermissionTimer_timerHandler);
                timer = null;

                devicesUnmutedInBrowser();
            }
        }

        private function devicesUnmutedInBrowser():void
        {
            log("Devices are unmuted in browser.");
        }

        private function isDevicesMutedInFlashPlayer():Boolean
        {
            var cameraNames:Array = Camera.names;
            var numCameras:int = cameraNames ? cameraNames.length : 0;
            if (numCameras > 0)
            {
                var defaultCamera:Camera = Camera.getCamera();
                return defaultCamera.muted;
            }
            else
            {
                var microphoneNames:Array = Camera.names;
                var numMicrophones:int = microphoneNames ? microphoneNames.length : 0;
                if (numMicrophones > 0)
                {
                    var defaultMicrophone:Microphone = Microphone.getMicrophone();
                    return defaultMicrophone.muted;
                }
            }
            return true;
        }

        private function isDevicesMutedInBrowser():Boolean
        {
            var cameraNames:Array = Camera.names;
            var numCameras:int = cameraNames.length;
            for (var i:int = 0; i < numCameras; i++)
            {
                var cameraName:String = cameraNames[i];
                if (cameraName != " ")
                {
                    return false;
                }
            }

            var microphoneNames:Array = Microphone.names;
            var numMicrophones:int = microphoneNames.length;
            for (i = 0; i < numMicrophones; i++)
            {
                var microphoneName:String = microphoneNames[i];
                if (microphoneName != " ")
                {
                    return false;
                }
            }

            return true;
        }

        private function log(text:String):void
        {
            output.appendText(text + "\n");
        }

        private function updateView():void
        {
            output.width = stage.stageWidth - 2 * output.x;
            output.height = stage.stageHeight - 2 * output.y;
        }

        private function stage_resizeHandler(event:Event):void
        {
            updateView();
        }
    }
}
所以,我想知道这是一个bug还是Google Chrome团队实现的某种新的安全功能?也许有人已经遇到了这个问题,可以分享更多的信息。 现在,它看起来像是现代浏览器用所有这些功能和丑陋的解决方案扼杀了Flash


附言:你可以在我的留言中发现一些愚蠢的错误。对不起,我的英语不好。

我没有检查你的代码,只是说。。谷歌或Chrome从来没有在定制的Flash播放器上做对过。只要在可能的情况下使用官方的Adobe插件,并给出同样的建议。即使是像文本这样简单的东西,特别是对外来字符的编码,也几乎无法使用,但是官方的插件工作得很好。为了避免重新加载相机名称。。如果PPAPI==true,则可以使应用程序在特定函数运行之前不检查任何相机名称。然后,只有当用户在您的U.I中确认,如果他们撒谎,他们就授予浏览器访问权限时,才运行该功能,只需单击“确定”,然后太糟糕了,他们必须重新加载,否则现在您的应用程序可以安全地检查。谢谢VC.One。不幸的是,我不能强迫用户使用官方的Flash播放器,因为他们中的许多人很难深入研究chrome://plugins. 此外,也没有办法强迫Chrome使用NPAPI闪存而不是PPAPI闪存。这将是一个安全问题,因为PPAPI沙箱。至于主浏览器访问检查。。。你看,问题是大多数用户在遇到一两个小问题后就会离开网站,而浏览器的这一点是个问题。但是关于浏览器的整个想法是好的。也许可以先在JavaScript中调用getUserMedia,而不是等待用户选择,然后再检查Flash中的摄像头。经过两次测试,我发现了PPAPI Flash的奇怪行为。该测试是在两个主权财富基金同时工作在同一页上进行的。第一个是要求像一些普通用户一样访问设备 通过调用video.attachCamera应用程序。第二个SWF是由JavaScript循环创建/删除的,以避免出现这种情况:扫描硬件寻找摄像头需要时间。当运行时发现至少一个摄像头时,在播放器实例的生命周期内不会再次扫描硬件。