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="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以上版本會自動暫停播放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("^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自動播放, 具體方法請百度。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM