外部接口和swfobject.js问题

时间:2011-12-15 22:00:01

标签: javascript flash actionscript-3 swfobject externalinterface

几个月前,我正在开发一个使用flash,外部接口和swfobject.js的视频播放器。我使用外部接口来促进javascript和actionscript之间的通信。这非常有效。目前我正在对此进行扩展,这需要我从我已经编写的内容中推断出逻辑。我在两个应用程序中使用相同的swf文件,但在扩展程序中,我无法让flash对象识别我的调用。由于我使用相同的swf对象,我知道我的问题在于javascript,我只是不知道在哪里。我正在使用JQuery库。如果没有进一步说明我的代码。

在我的js文件的底部,我有以下内容:

$(function(){
     //the video player shouldn't be built until the user presses the div with 'video-btn' class
    $('.video-btn').click(function(){
         var videoplayer = new VideoPlayer();
         videoplayer.addVideoPlayer();
         //external interface function
         videoplayer.player.loadVideo();
    });
});

以下是VideoPlayer.addVideoPlayer()及其相关帮助函数的定义:

//inside of VideoPlayer object definition
this.addVideoPlayer = function(){
     var that = this;
     $('body').append('<div id="no-flash"></div>');

     //uses swfobject.js to replace the div i just appended with the flash object
     //This works fine.  the flash object replaces the div as intended
     that.embedFlashObject();
     //that.player is (supposed to be) a reference to flash object
     that.player = that.getFlashObject();
};

this.embedFlashObject = function(){
     var that = this;

     //set up all the variables to pass to swfobject.embedSWF

     //this method removes my div and replaces it with an object element that contains the swf file
     //the object tag gets an id which is specified.  Let's assume it's 'vp'
     swfobject.embedSWF(swfFile, 'no-flash', width, hieght, '9.0.0', ... );
};

this.getFlashObject = function(){
     var that = this;

     //this method returns the flash object to make external interface calls on
     //this the method prescribed by swfobject api  
     var videoObj = swfobject.getObjectById('vp');
     if(typeOf videoObj == 'undefined')
     {
          //check if useragent string is IE
          var isIE = navigator.userAgent.match(/MSIE/i);
          videoObj = isIE ? window['vp'] : document['vp'];
     }
     return videoObj;
};

在我的$(function(){..});区块中,当命令&#39; videoplayer.player.loadMedia();&#39;我收到一条错误,内容为

  

.loadMedia不是一个函数。

在这个项目的先前版本中(我使用完全相同的swf文件)我没有收到此错误。

我不认为我错过了任何严重的逻辑错误,而且我知道很难明确地说这是你的问题,......&#39;在查看缩写和擦除代码时。代替一个明确的答案,我将就如何调试此问题提出建议。我一直在浏览器控制台中玩aorund,我发现该玩家&#39;我的VideoPlayer对象的属性为null。当我针对该项目的工作版本运行相同的控制台查询时,它会回吐对象标记。我无法直接设置对象标记,因为它会破坏我需要维护的先前版本中使用的约定。

HELP !!!!!!!!!!!!!!!

5 个答案:

答案 0 :(得分:3)

SWFObject回调函数

请仔细阅读SWFObject的文档。 https://code.google.com/p/swfobject/wiki/api

创建或嵌入SWF的所有功能都有一个回调参数。您可以将回调函数作为参数传递,该函数将在SWF准备就绪时调用。 在此回调函数中调用ExternalInterface actionscript函数。

示例:

swfobject.embedSWF("/Flash/Player.swf", "flash", "100%", "100%", swfVersionStr, xiSwfUrlStr, flashvars, params, attributes, function (e) {
    document.getElementById("flash").loadMedia();
});

答案 1 :(得分:3)

所以我想出了我的问题。尽管我尽最大努力在描述问题方面做得很好,但我遗漏了一个可能有助于解决我的问题的关键事实。在转移到实际的开发服务器之前,我在本地开发我的应用程序。在本地环境中使用Flash应用程序时,默认情况下禁用来自Internet的通信。如果您使用谷歌的“adobe安全设置”,其中一个顶部链接会将您带到adobe安全设置页面,您可以在该页面上找到您希望允许此外部通信的本地计算机上的文件夹。我的swf文件会尽早尝试与我们的服务器建立连接,以便初始化外部回调,如果它不能这样做它只是等待,因此我的所有函数都没有成为声明的函数。在我完成这个项目的初始迭代时,我确实遇到了这个问题,但直到昨天才想到它。

感谢所有提供解决方案的人。完成这两次后,我可以保证,这里建议的所有内容都可能在尝试编程和外部接口闪存应用程序时阻止一个人。

答案 2 :(得分:1)

有许多可能的原因。最常见的一种是计时 - 如果在SWF准备就绪之前尝试访问ExternalInterface,则会遇到错误。

活动顺序:

  1. SWFObject将<object>写入页面
  2. Flash Player插件初始化
  3. 加载了SWF
  4. ExternalInterface已初始化
  5. 如果您尝试在使用SWFObject后立即调用ExternalInterface方法,则步骤2到4可能尚未完成,这会引发JS错误(找不到方法)。

    在这些情况下,您可能希望尝试使用计时器来查看它是否会改变您的结果。 Here's an example you can use

    另外,我注意到代码中的一些项目可以简化或编辑,以下是一些建议:

    1. embedFlashObject内有拼写错误:hieght应为height
    2. getFlashObject使用swfobject.getObjectById;这不是必需的,只有在使用SWFObject的静态发布技术时才需要swfobject.getObjectById。如果您使用的是动态发布,则可以使用document.getElementById或jQuery的$函数。
    3. getFlashObject检查IE。您也可以使用SWFObject的ua属性来获取信息:swfobject.ua.ie代替navigator.userAgent.match(/MSIE/i)
    4. swfobject.createSWF可以返回对新创建的<object>的引用,因此您可以简化代码。

      //inside of VideoPlayer object definition
      this.addVideoPlayer = function(){
      
          var that = this;
      
          if (swfobject.hasFlashPlayerVersion("9")){
      
              $('body').append('<div id="no-flash"></div>');
      
              //For legibility
              var swfdata = {
                  data: swfFile,
                  width: width,
                  height: height
              };
      
              var params = { bgcolor: color };
      
              var id = 'no-flash';
      
              that.player = swfobject.createSWF(swfdata, params, id);
      
          }
      
      };
      

      可以浓缩为

      //inside of VideoPlayer object definition
      this.addVideoPlayer = function(){
          var that = this;
          if (swfobject.hasFlashPlayerVersion("9")){
              $('body').append('<div id="no-flash"></div>');
              that.player = swfobject.createSWF({data: swfFile, width: width, height: height}, {bgcolor: color}, 'no-flash');
          }
      };
      

      这将消除您对embedFlashObjectgetFlashObject方法的需求。

答案 3 :(得分:0)

我感觉到你的痛苦。我自己和他一起战斗了很长时间......

当您收到“不是函数”消息时,基本上发生的事情是: a)您的JavaScript无法找到您的电影实例。 要么 b)你的动作脚本没有正确地暴露loadMedia()方法。

在js和as中使用check()方法总是一个好主意。它们用于确保每个元件已满载并准备好进行操作/使用。关于此,有很多帖子。

您是否注意到IE和Firefox之间存在差异?有人工作,但另一个不工作吗?

在以下块中:

var videoObj = swfobject.getObjectById('vp');
  if(typeOf videoObj == 'undefined')
  {
       //check if useragent string is IE
       var isIE = navigator.userAgent.match(/MSIE/i);
       videoObj = isIE ? window['vp'] : document['vp'];
  }
  return videoObj;

...你似乎正在使用swfObject的方法来检索电影,但是你正在检查浏览器并且 - 再次 - 查看电影的DOM。您是否尝试过评论以下块:

if(typeOf videoObj == 'undefined')
      {
           //check if useragent string is IE
           var isIE = navigator.userAgent.match(/MSIE/i);
           videoObj = isIE ? window['vp'] : document['vp'];
      }   

...并且只返回swfobject返回的值?

据我了解,swfObject将为您处理浏览器检测。

另外,检查swfobject实际上是否为html对象提供了一个id('vp')。

答案 4 :(得分:0)

在FF中,您需要将代码放在embed元素中以正确执行ExternalInterface,实际上我认为swfobject.js不支持此代码。为了工作,你还需要像这个完整的例子(http://code.google.com/p/flash-videoio/source/browse/trunk/examples/ichatnow/index.html

那样设置一个classid
<!doctype html>
<html style="width:100%; height: 100%;">
  <head>
  <title>I Chat Now</title>
  <style>
    body { margin: 0px; overflow:hidden; }
  </style>
  <script>
    function onCreationComplete(event) {
      console.log('onCreationComplete');
    }
  </script>
</head>
<body scroll="no" style="width:100%; height: 100%;">  
  <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
    id="video1" width="100%" height="100%"
    codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
    <param name="movie" value="VideoIO.swf" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#000000" />
    <param name="allowFullScreen" value="true" />
    <param name="allowScriptAccess" value="always" />
    <param name="flashVars" value="controls=true" />
    <embed src="VideoIO.swf" quality="high" bgcolor="#000000"
        width="100%" height="100%" name="video1" align="middle"
        play="true" loop="false" quality="high" 
        allowFullScreen="true" 
        allowScriptAccess="always" 
        flashVars="controls=true" 
        type="application/x-shockwave-flash" 
        pluginspage="http://www.adobe.com/go/getflashplayer"> 
    </embed> 
  </object>
</body>
</html>