var loadConfig = [{ // this.load = function(e)
type: "qt",
levels: e.list
}];
A().load(loadConfig);
A().play(!0);
_.init({
player: p(),
game_id: 1 * w.game_id || 0,
room_id: 1 * w.roomid || 0,
subroom_id: 1 * w.subroomid || 0,
file: A().getPlaylistItem().file,
use_p2p: I ? 1 : 0
});
起因是网友“国王与乞丐”反馈的http://lpl.qq.com/es/live.shtml页面播放不了flash。
看了下,有两个问题,一个是这个是windowless flash,播放的时候如果滚动会花屏。这个bug好改,是我在拿到flash传过来的贴图的时候,贴的位置不对。
还有个就是flash一直提示在加载中。
调试了下js,发现是http://gpcd.gtimg.cn/qt/gpack/zhibo/js/2.b4f5f94d.chunk.min.js里面负责加载jwplayer的。jwplayer是一个曾经开源的flash播放器,看来腾讯的同事也是拿来就用啊。
现在的主要问题就是
这几句之后,getPlaylistItem获取到的播放列表是空的。我用原版webkit也试了下,
居然是能正常加载的。所以就怀疑这个 A().load没加载成功。这个A().load其实内部,就是拿到<object>对象后,直接obj["jwLoad"](loadConfig);这种形式加载的。
这一阶段的时候我陷入了很长时间的困惑,一直没搞明白哪里没成功。甚至还把jwplayer的代码找来对比。开始怀疑是权限,后来又怀疑是我少写了什么辅助函数。
最后发现原因是NPV8Object.cpp里的createValueListFromVariantArgs问题。这个函数会在flash调用到blink里用来转换 NPVariant* arguments到v8参数,在_NPN_Invoke里用到。而我的NPVariant的结构体,是从qq浏览器里代码拷出来的,没想到被同事多加了一个字段!
附一些调试记录:
flash会事先加载一段js:
代码语言:javascript复制function __flash__arrayToXML(obj) {
var s = "<array>";
for (var i=0; i<obj.length; i ) {
s = "<property id="" i "">" __flash__toXML(obj[i]) "</property>";
}
return s "</array>";
}
function __flash__argumentsToXML(obj,index) {
var s = "<arguments>";
for (var i=index; i<obj.length; i ) {
s = __flash__toXML(obj[i]);
}
return s "</arguments>";
}
function __flash__objectToXML(obj) {
var s = "<object>";
for (var prop in obj) {
s = "<property id="" prop "">" __flash__toXML(obj[prop]) "</property>";
}
return s "</object>";
}
function __flash__escapeXML(s) {
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
function __flash__toXML(value) {
var type = typeof(value);
if (type == "string") {
return "<string>" __flash__escapeXML(value) "</string>";
} else if (type == "undefined") {
return "<undefined/>";
} else if (type == "number") {
return "<number>" value "</number>";
} else if (value == null) {
return "<null/>";
} else if (type == "boolean") {
return value ? "<true/>" : "<false/>";
} else if (value instanceof Date) {
return "<date>" value.getTime() "</date>";
} else if (value instanceof Array) {
return __flash__arrayToXML(value);
} else if (type == "object") {
return __flash__objectToXML(value);
} else {
return "<null/>"; //???
}
}
function __flash__request(name) {
return "<invoke name="" name "" returntype="javascript">" __flash__argumentsToXML(arguments,1) "</invoke>";
}
这样到as里绑定js的函数:ExternalInterface.addCallback("toASS", callHandler); 的时候,如果你在js里调用了toASS(["sdfasdfasdf"])这个函数,flash会先执行
代码语言:javascript复制__flash__request("toASS", ["sdfasdfasdf"]
把js的调用转成xml,类似
<invoke name="toASS" returntype="javascript"> <arguments> <array> <property id="0"> <string>asdfasdfasdf</string> </property> </array> </arguments> </invoke> 这样,再传给as处理,as内部根据这个xml识别成as里的对应对象,如数组、字符串等。
另外third_partyWebKitSourcebindingscorev8V8NPObject.cpp 的npObjectInvokeImpl是负责从blink的js层调用到flash npapi里的函数。
webkit类似的地方是SourceWebCorebridgecc_instance.cpp的CInstance::invokeMethod。
webkit的SourceWebKitwinPluginsPluginPackage.cpp的NPN_Invoke和blink的third_partyWebKitSourcebindingscorev8NPV8Object.cpp的NPV8Object.cpp做的事情是flash npapi调用到blink的js。
String json = JSC::JSONStringify(exec, resultObj, 4);可以用来转换jsc的js object成json。
更多as注入js的,可以看http://blog.csdn.net/zhongxiucheng/article/details/7978515