zoukankan      html  css  js  c++  java
  • chrome 45以上flash被拦截的一种可能解决方案

    chrome 45以上不自动播放"非必要"flash的一种可能解决方案
    chrome 45以上flash被拦截的一种可能解决方案

    问题

    1、chrome 45以上(包含45)版本默认不自动播放"非必要"flash,对于非自动播放的广告,chrome会在flash上悬浮一个播放按钮,点击后可播放
    2、对于国内情况来说,flash目前还是很多中小客户的主力素材,展现效果好,且技术成熟。
    3、目前flash广告大多数使用覆盖a链接来进行落地页和tracker的承载,无法点中chrome贴心提供的播放按钮,结构大概如下:

    1 <div style="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以上版本会自动暂停播放flash
    45     //所以这里只针对这两个条件进行增加逻辑处理
    46     //在生成的swfHTML的前面增加注释节点,用来保存当前flash的name,实际宽度和实际高度,格式如下
    47     //<!--fakesize:name|width|height-->
    48     //在后面配套使用的过程中判断是否有这个注释来决定是否需要恢复flash的尺寸
    49     //@link: https://news.ycombinator.com/item?id=10133771
    50     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("^salignx24", "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自动播放, 具体方法请百度。。

  • 相关阅读:
    实现JSON数据的存储和读取
    MediaPlayer类——播放视频和音乐
    网络编程浅析
    线程浅析
    I/O浅析
    fragment之间的信息交互——onActivityResult()不经过Activity
    命名规则
    String方法(一)
    面试小结
    找工作中......
  • 原文地址:https://www.cnblogs.com/zqifa/p/html-flash-1.html
Copyright © 2011-2022 走看看