chrome 45以上flash被拦截的一种可能解决方案
来源:互联网 发布:java单例模式的优点 编辑:程序博客网 时间:2024/06/06 05:09
chrome 45以上flash被拦截的一种可能解决方案
问题
1、chrome 45以上(包含45)版本默认不自动播放"非必要"flash,对于非自动播放的广告,chrome会在flash上悬浮一个播放按钮,点击后可播放
2、对于国内情况来说,flash目前还是很多中小客户的主力素材,展现效果好,且技术成熟。
3、目前flash广告大多数使用覆盖a链接来进行落地页和tracker的承载,无法点中chrome贴心提供的播放按钮,结构大概如下:
1 <div style="width:1000px;height:90px;position:relative;overflow:hidden;">2 <embed width="1000px" height="90px" wmode="opaque" align="middle" src="http://d1.sina.com.cn/201511/09/1394644_1000x90_30k.swf" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">3 </div>
思路
对于chrome, 什么是"非必要"
非必要在chrome定义上大概包含以下两点:
不在同域
尺寸不够大(小于398*298,这个我做过测试,确实如此,也不知道这两个数字怎么拍脑门想出来的,不贴demo了)
参考文件:https://news.ycombinator.com/item?id=10133771 文章内有两个chrome源码的连接,也可以到下面去查看
https://code.google.com/p/chromium/codesearch#chromium/src/content/renderer/pepper/plugin_power_saver_helper.cc&sq=package:chromium&type=cs&l=87
https://code.google.com/p/chromium/codesearch#chromium/src/content/renderer/pepper/plugin_instance_throttler_impl.cc&q=plugin_instance_throttler_impl&sq=package:chromium&type=cs&l=5
尝试一种解决思路
在广告中,由于各种情况限制,要求广告主的素材同域肯定是不方便的,所以只能从尺寸上解决 通过尝试,可以在flash渲染的时候暂时把尺寸设置成大于398*298,在实际展现的时候在设置回来,这里需要createFlash的方法动下小手脚
** 这里的尺寸有几个注意点: 1、不只是flash自己的尺寸而是真正展现的尺寸,有可能flash设置了足够大,但是它外面包含的容器overflow了,导致flash实际尺寸没有这么大,这样也是无法自动播放的 2、经过尝试,opacity:0 的flash只要尺寸足够大,也是可以自动播放的
直接看代码
改造过的swf.createHTML
1 /** 2 * 创建flash的html 3 * @param {Object} options 选项 4 * @return {String} flash的html 5 * http://www.w3help.org/zh-cn/causes/HO8001 修改成仅用embed标签渲染flash 6 */ 7 sinaadToolkit.swf.createHTML = function (options) { 8 options = options || {}; 9 var item,10 k,11 tmpOpt = {},12 encodeHTML = sinaadToolkit.string.encodeHTML;13 14 // 复制options,避免修改原对象15 for (k in options) {16 tmpOpt[k] = options[k];17 }18 options = tmpOpt;19 20 var vars = options.vars;21 22 // 初始化flashvars参数的值23 if ('string' === typeof vars) {24 options.flashvars = vars;25 } else {26 var fvars = [];27 for (k in vars) {28 item = vars[k];29 fvars.push(k + "=" + encodeURIComponent(item));30 }31 options.flashvars = fvars.join('&');32 }33 34 var str = [];35 36 // 使用embed时,flash地址的属性名是src,并且要指定embed的type和pluginspage属性37 options.name = options.id || 'sinaadtk_swf_uid_' + (sinaadToolkit.swf.uid++);38 options.align = options.align || 'middle';39 options.src = options.url || '';40 options.type = 'application/x-shockwave-flash';41 options.pluginspage = 'http://www.macromedia.com/go/getflashplayer';42 43 //这里是hack的关键处44 //因为尺寸小于398*298,在chrome的45以上版本会自动暂停播放flash45 //所以这里只针对这两个条件进行增加逻辑处理46 //在生成的swfHTML的前面增加注释节点,用来保存当前flash的name,实际宽度和实际高度,格式如下47 //<!--fakesize:name|width|height-->48 //在后面配套使用的过程中判断是否有这个注释来决定是否需要恢复flash的尺寸49 //@link: https://news.ycombinator.com/item?id=1013377150 if (sinaadToolkit.browser.chrome > 44 && !(options.width >= 398 && options.height >= 298)) {51 str.push('<!--fakesize:' + options.name + '|' + parseInt(options.width, 10) + '|' + parseInt(options.height, 10) + '-->');52 options.width = '398px';53 options.height = '298px';54 }55 56 delete options.id;57 delete options.url;58 delete options.vars;59 60 str.push('<embed');61 62 // 在firefox、opera、safari下,salign属性必须在scale属性之后,否则会失效63 // 经过讨论,决定采用BT方法,把scale属性的值先保存下来,最后输出64 var salign;65 for (k in options) {66 item = options[k];67 if (item || item === false || item === 0) {68 if ((new RegExp("^salign\x24", "i")).test(k)) {69 salign = item;70 continue;71 }72 73 str.push(' ', k, '="', encodeHTML(item), '"');74 }75 }76 77 if (salign) {78 str.push(' salign="', encodeHTML(salign), '"');79 }80 str.push('/>');81 82 return str.join('');83 };
解析并将生成的flashhtml填充进节点,根据条件决定是否恢复尺寸
1 sinaadToolkit.swf.fill(element, html) { 2 var fake, flash, cachePosition; 3 //如果匹配中<!--fakesize:name|width|height-->开头的 4 if ((fake = html.match(/<\!--\s*fakesize\:([0-9a-zA-Z_]+)\|(\d+)\|(\d+)\s*-->/))) { 5 //防止抖动 6 cachePosition = element.style.position; 7 cacheOpacity = element.style.opacity; 8 element.style.position = 'absolute'; 9 element.style.opacity = 0;10 element.innerHTML = html;11 12 //稍微延迟并恢复尺寸,这里的延迟没有经过考证13 setTimeout(function () {14 flash = core.swf.getMovie(fake[1]);15 flash.width = fake[2];16 flash.height = fake[3];17 18 //恢复原来状态19 element.style.position = cachePosition || 'relative';20 element.style.opacity = cacheOpacity || 1;21 }, 100);22 } else {23 //否则直接填充就是了24 element.innerHTML = html;25 }26 };
对于重排的性能肯定会有影响,等后续做测试和优化,先当一种想法
PS
当然你也可以在浏览器上面加个提示条:请您开启chrome的flash自动播放, 具体方法请百度。。
- chrome 45以上flash被拦截的一种可能解决方案
- flash在android上的延迟可能的解决方案
- mac cpu温度持续超高,风扇转速4000转以上的其中一种可能
- Chrome浏览器flash player问题的终极解决方案
- Google浏览器 chrome老是拦截flash
- chrome 的 flash cookie
- 在ubuntu 10.04及以上版本为chrome安装flash
- ubuntu chrome安装adobe flash player解决方案
- 此页的状态信息无效,可能已损坏的一种解决方案
- [VNC] CentOS6.5中VNC无法启动服务的一种可能解决方案
- Android AVD 出现No content provider found for permission revoke可能的一种解决方案
- 异常问题not allowed to send broadcast android.intent.action.BATTERY_CHANGED可能的一种解决方案
- Adobe Flash Player已经终止一项可能不安全的操作,解决方案
- Adobe Flash Player已经终止一项可能不安全的操作,解决方案
- window.open被浏览器拦截的解决方案
- chrome 无 flash的解决办法!
- director与flash通讯的一种解决方案(同样适用于dir 11.X 与 AS3通讯)
- QT5.0以上版本 incomingConnection不能被调用的解决方案
- php curl上传文件$_FILES为空问题
- javascript apply|call的使用
- php curl文件上传兼容php5.0~5.6各版本
- php curl curl_getinfo()返回参数详解
- php curl伪造来源ip和refer实例代码
- chrome 45以上flash被拦截的一种可能解决方案
- base64编码的原理及实现
- 使用js提交form表单的两种方法
- PHP安全相关的配置(1)
- VC++编程通过Bluetooth API调用对话框选择蓝牙设备并显示设备信息
- 深入分析ConcurrentHashMap1.8的扩容实现
- PHP安全相关的配置(2)
- mysql 中find_in_set()和in()用法比较
- Yii2 环境配置生产环境和测试环境