终于找到miniblink播放jwplayer不了的原因了

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:

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会先执行

__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_party\WebKit\Source\bindings\core\v8\V8NPObject.cpp 的npObjectInvokeImpl是负责从blink的js层调用到flash npapi里的函数。

webkit类似的地方是Source\WebCore\bridge\c\c_instance.cpp的CInstance::invokeMethod。

webkit的Source\WebKit\win\Plugins\PluginPackage.cpp的NPN_Invoke和blink的third_party\WebKit\Source\bindings\core\v8\NPV8Object.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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券