几个月前,我在一个工作项目中使用 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(){..}); 中
块,当命令 'videoplayer.player.loadMedia();
' 时,我收到一条错误消息:
.loadMedia 不是函数。
在该项目的先前版本(其中我使用完全相同的 swf 文件)中,我没有收到此错误。
我不认为我错过了任何严重的逻辑错误,而且我知道在查看缩写和清理的代码时很难明确地说“这是你的问题,......”。我将采取有关如何调试此问题的建议来代替明确的答案。我一直在浏览器控制台中播放 aorund,发现我的 VideoPlayer 对象的“player”属性为空。当我针对该项目的工作版本运行相同的控制台查询时,它会返回对象标签。我无法直接设置对象标签,因为它将打破我需要维护的先前版本中使用的约定。
帮助!!!!!!!!!!!!!!!
Several months ago for a project at work i developed a video player using flash, external interface and swfobject.js. I used external interface to facilitate communication between javascript and actionscript. This works great. Currently I am working on an extension to this that requires me to extrapolate logic from what i already written. I am using the same swf file in both applications, but in the extension i can't get the flash object to recognize my calls. Since i am using the same swf object i know that my problem is in the javascript, i just don't know where. I am using the JQuery Library. Without further adieu here's my code.
At the bottom of my js file i have the following:
$(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();
});
});
Here's the definition for VideoPlayer.addVideoPlayer()
and it's relevant helper functions:
//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;
};
In my $(function(){..});
block, when the command 'videoplayer.player.loadMedia();
' I get an error that reads
.loadMedia is not a function.
In the previous version of this project (in which i use the exact same swf file) i do not get this error.
I don't think i am missing any severe logical errors, and i know its difficult to say definitively 'this is your issue,....' when looking at abbreviated and scrubbed code. In lieu of a definite answer i'll take suggestions as to how to debug this issue. I've been playing aorund in the browser console and i've found that the 'player' attribute of my VideoPlayer object is null. When i ran the same console query against the working version of this project it spits back the object tag. I can't directly set the object tag, because it will break with the conventions used in the previous version which i need to maintain.
HELP!!!!!!!!!!!!!!!
发布评论
评论(5)
SWFObject 回调函数
请仔细阅读SWFObject 的文档。
https://code.google.com/p/swfobject/wiki/api
所有用于创建或嵌入SWF 的函数都有一个回调参数。您可以将回调函数作为参数传递,该函数将在 SWF 准备就绪时调用。
在此回调函数中调用您的ExternalInterface动作脚本函数。
例子:
SWFObject Callback function
Please go through the documentation of SWFObject.
https://code.google.com/p/swfobject/wiki/api
All the functions for creating or embedding SWF has a callback parameter. You can pass a callback function as parameter which will be invoked when SWF is ready.
Invoke your ExternalInterface actionscript function in this callback function.
Example:
所以我明白了我的问题是什么。尽管我尽了最大努力对问题进行有力的描述,但我还是遗漏了一个可能有助于解决我的问题的关键事实。在迁移到实际的开发服务器之前,我在本地开发我的应用程序。在本地环境中使用 Flash 应用程序时,默认情况下会禁用来自 Internet 的通信。如果您在 google 上搜索“adobe 安全设置”,顶部链接之一会将您带到 adobe 安全设置页面,您可以在其中选择本地计算机上希望允许此外部通信的文件夹。我的 swf 文件会在初始化外部回调之前尽早尝试与我们的服务器建立连接,如果它不能做到这一点,它只会等待,因此我的函数都没有成为声明的函数。实际上,我在完成该项目的初始迭代时遇到了这个问题,但直到昨天才想到。
感谢所有提供解决方案的人。完成此操作两次后,我可以保证这里建议的所有内容都可能会在尝试编程和外部接口闪存应用程序时阻碍人们。
So i figured out what my problem was. Despite my best efforts to be robust in description of the problem, i left out one key fact that would probably have helped to solve my issue. I was developing my application locally before moving to an actual development server. When using a flash application in a local context, communications from the internet are disabled by default. If you google 'adobe security settings', one of the top links will take you to an adobe security settings page where you can cchose folders on your local machine that you want to allow this external communication. My swf file would tries early on to make a connection to our servers befor initializing the external call backs, if it can't do that it just waits, and thus none of my functions were becoming declared functions. I actually had this problem when working through my initial iteration of this project, but didn't think of it until yesterday.
Thank you for everyone who supplied solutions. Having done this twice i can vouch for the fact that everything that has been suggested here is something that might hold a person up while trying to program and external interface flash application.
有许多可能的原因。最常见的问题之一是计时 - 如果您在 SWF 准备就绪之前尝试访问ExternalInterface,则会遇到错误。
事件顺序:
如果您尝试在使用 SWFObject 后立即调用ExternalInterface 方法,则步骤 2 到 4 可能不会执行尚未完成,这会抛出 JS 错误(未找到方法)。
在这些情况下,您可能需要尝试使用计时器,看看它是否会改变您的结果。 这是一个您可以使用的示例 。
另外,我注意到您的代码中的一些项目可以简化或编辑,这里有一些建议:
embedFlashObject
中有一个拼写错误:hieght
应该是height< /code>
getFlashObject
使用swfobject.getObjectById
;这不是必需的,仅当您使用 SWFObject 的静态发布技术时才需要swfobject.getObjectById
。如果您使用动态发布,则只需使用document.getElementById
或 jQuery 的$
函数即可。getFlashObject
对 IE 进行检查。您也可以使用 SWFObject 的 ua 属性来获取信息:用 swfobject.ua.ie 代替 navigator.userAgent.match(/MSIE/i)< /code>swfobject.createSWF
可以返回对新创建的There are a number of possible causes. One of the most common is timing -- if you try to access ExternalInterface before the SWF is ready, you will encounter an error.
Order of events:
<object>
to the pageIf you try to invoke the ExternalInterface method immediately after using SWFObject, steps 2 through 4 might not have completed yet, which would throw a JS error (method not found).
In these cases, you might want to experiment with a timer to see if it changes your outcome. Here's an example you can use.
Also, I noticed some items in your code that could be simplified or edited, here are some suggestions:
embedFlashObject
:hieght
should beheight
getFlashObject
usesswfobject.getObjectById
; this is not necessary,swfobject.getObjectById
is only required if you're using SWFObject's static publishing technique. If you're using dynamic publishing, you can just usedocument.getElementById
or jQuery's$
function.getFlashObject
has a check for IE. You can use SWFObject'sua
property to get the info, too:swfobject.ua.ie
in place ofnavigator.userAgent.match(/MSIE/i)
swfobject.createSWF
can return a reference to the newly created<object>
, so you might be able to simplify your code.Which could be condensed to
This would eliminate the need for your
embedFlashObject
andgetFlashObject
methods.我感受到你的痛苦。我自己也为此奋斗了很长时间......
当你收到“不是一个函数”消息时,基本上发生的事情是:
a) 您的 JavaScript 找不到您的电影实例。
或者
b) 您的动作脚本未正确公开 loadMedia() 方法。
在 js 和 as 中使用 check() 方法总是一个好主意。它们用于确保每个元素已完全加载并准备好进行操作/使用。有很多关于此的帖子。
您注意到 IE 和 Firefox 之间的区别了吗?一个有效,但另一个无效?
在下面的块中:
...您似乎正在使用 swfObject 的方法来检索电影,但随后您正在检查浏览器并 - 再次 - 在 DOM 中查找电影。您是否尝试过注释掉以下块:
...并仅返回 swfobject 返回值?
据我了解,swfObject 将为您处理浏览器检测。
另外,检查 swfobject 实际上是否为 html 对象提供了 id ('vp')。
I feel your pain. I fought with this for a long time myself...
When you get the "is not a function" message, basically what's happening is that either:
a) your javascript can't find your movie instance.
or
b) your actionscript is not properly exposing the loadMedia() method.
It's always a good idea to have check() methods in your js and your as. They are used to ensure each element has fully loaded and is ready for manipulation/use. There are a number of posts regarding this.
Have you noticed a difference between IE and Firefox? Does one work, but the other not?
In the following block:
...you seem to be using swfObject's method to retrieve the movie, but then you are checking the browser and - AGAIN - looking in the DOM for the movie. Have you tried commenting out the following block:
...and just return the swfobject returned value?
As I understand it, swfObject will handle the browser detection for you.
Also, check that swfobject is actually giving the html object an id ('vp').
在 FF 中,您需要将代码放入嵌入元素中才能正确执行ExternalInterface,实际上我认为 swfobject.js 不支持此代码。为了工作,您还需要设置一个 classid,如这个完整示例(http://code.google.com/p/flash-videoio/source/browse/trunk/examples/ichatnow/index.html)
In FF you need to put your code inside an embed element for the correct execution of ExternalInterface and actually I think this code is not supported in swfobject.js. In order to work you need also to set a classid like this full example (http://code.google.com/p/flash-videoio/source/browse/trunk/examples/ichatnow/index.html)