上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

超级星星videojs劫持分析

[复制链接]
  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5966

    回帖

    6764

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6764

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-5 03:07:36 | 显示全部楼层 | 阅读模式

    前言

    予以自乐,好求知,不求甚解

    开始

    之前是对window.videojs进行劫持初始化函数,我们发现这次无法重新赋值

    使用描述符读取函数发现可写为了flase

    这是我们有两种方式

    1.对其object.definproperty进行劫持,设置writable为true

    然后继续进行劫持

    2.对videojs进行核心劫持

    第一种方案为

    +if(unsafeWindow.location.href.indexOf('/modules/video')!==-1){
    +    let fuck=Object.defineProperty
    +    Object.defineProperty=function(...args){
    +        if(args.length>=2){
    +            if(args[1]==='videojs'&&args[2]!==undefined){
    +                args[2].writable=true
    
    +            }
    +        }
    +        return fuck.call(this,...args)
    +    }

    直接对其进行过滤即可

    第二种访问

    我们需要阅读videojs源码

    https://unpkg.com/video.js@7.17.0/dist/video.js

    查看代码

     (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojs = factory());
      }(this, (function () { 'use strict';

    umd格式,直接拖底部

        return videojs;

    发现传出一个函数,我们查找videojs

    是一个

       function videojs(id, options, ready)

    大致阅读代码

          var player = videojs.getPlayer(id);
    
          if (player) {
            if (options) {
              log$1.warn("Player \"" + id + "\" is already initialised. Options will not be applied.");
            }
    
            if (ready) {
              player.ready(ready);
            }
    
            return player;
          }

    首先获取id,判断是否存在,如果存在则不初始化

    这里我一开始试图对Getplayer进行劫持

    后来发现少参,放弃

          var el = typeof id === 'string' ? $('#' + normalizeId(id)) : id;
    
          if (!isEl(el)) {
            throw new TypeError('The element or ID supplied is not valid. (videojs)');
          } // document.body.contains(el) will only check if el is contained within that one document.
          // This causes problems for elements in iframes.
          // Instead, use the element's ownerDocument instead of the global document.
          // This will make sure that the element is indeed in the dom of that document.
          // Additionally, check that the document in question has a default view.
          // If the document is no longer attached to the dom, the defaultView of the document will be null.
    
          if (!el.ownerDocument.defaultView || !el.ownerDocument.body.contains(el)) {
            log$1.warn('The element supplied is not included in the DOM');
          }
    
          options = options || {};
          hooks('beforesetup').forEach(function (hookFunction) {
            var opts = hookFunction(el, mergeOptions$3(options));
    
            if (!isObject$1(opts) || Array.isArray(opts)) {
              log$1.error('please return an object in beforesetup hooks');
              return;
            }
    
            options = mergeOptions$3(options, opts);
          }); // We get the current "Player" component here in case an integration has
          // replaced it with a custom player.

    兼容化处理+options合并,跳过

          var PlayerComponent = Component$1.getComponent('Player');
          player = new PlayerComponent(el, options, ready);
          hooks('setup').forEach(function (hookFunction) {
            return hookFunction(player);
          });
          return player;

    这里发现通过了Component.GetComponent读了Player函数

    然后对其构造,最后调用了Hooks回调钩,传入了一个函数,然后循环遍历

    等等,嗯?

    hooks钩?

    往前翻

          hooks('beforesetup').forEach(function (hookFunction) {
            var opts = hookFunction(el, mergeOptions$3(options));
    
            if (!isObject$1(opts) || Array.isArray(opts)) {
              log$1.error('please return an object in beforesetup hooks');
              return;
            }
    
            options = mergeOptions$3(options, opts);
          });
          hooks('setup').forEach(function (hookFunction) {
            return hookFunction(player);
          });

    经典的beforeCreated钩和Created钩

    查询参数手册

    https://docs.videojs.com/tutorial-hooks.html

    videojs.hook('beforesetup', function(videoEl, options) {
    
      // videoEl will be the video element with id="some-id" since that
      // gets passed to videojs() below. On subsequent calls, it will be
      // different.
    
      videoEl.className += ' some-super-class';
    
      // autoplay will be true here, since we passed it as such.
      if (options.autoplay) {
        options.autoplay = false
      }
    
      // Options that are returned here will be merged with old options.
      //
      // In this example options will now be:
      //   {autoplay: false, controls: true}
      //
      // This has the practical effect of always disabling autoplay no matter
      // what options are passed to videojs().
      return options;
    });
    videojs.hook('setup', function(player) {
    
      // Initialize the foo plugin after any player is created.
      player.foo();
    });
    beforesetup
    beforesetup occurs just before a player is created. This allows:
    
    Modification of the options passed to the Video.js function (e.g., videojs('some-id, options)).
    Modification of the DOM video element that will be used for the player that will be created.
    beforesetup hook functions should:
    
    Take two arguments:
    videoEl: DOM <video> element that Video.js is going to use to create a player.
    options: The options object that Video.js was called with and will be passed to the player during creation.
    Return an options object that will be merged with the originally provided options.
    
    ```js
    setup
    setup occurs just after a player is created. This allows:
    
    Plugins or other custom functionality to initialize on the player.
    Changes to the player object itself.
    setup hook functions:
    
    Take one argument:
    player: the player that Video.js created
    Don't have to return anything

    大概意思就不翻译了

    有兴趣谷歌翻译一下

    直接秒就完了

    结语

    社会摇中万人迷,唯有道总着人迷

    社会摇中没有将与帅,只有实力这一块

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5966

    回帖

    6764

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6764

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-5 03:08:16 | 显示全部楼层
    _b_B2c8b56fef1b9717238b31da7c36c440f.mp4 (920.88 KB, 下载次数: 71)
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-3-19 11:07
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    24

    回帖

    21

    积分

    助理工程师

    积分
    21

    新人报道

    发表于 2022-3-5 08:52:25 | 显示全部楼层
    沙发,顶起,多谢大佬
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-3-19 11:07
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    24

    回帖

    21

    积分

    助理工程师

    积分
    21

    新人报道

    发表于 2022-3-5 09:14:23 | 显示全部楼层
    function hookVideo() {
        _self.alert = console.log;
        var config = arguments[1];
        if (!config) {
            return vjs.apply(this, arguments);
        }
        var line = Ext.Array.filter(Ext.Array.map(config.playlines, function (value, index) {
            return value.label == setting.line && index;
        }), function (value) {
            return Ext.isNumber(value);
        })[0] || 0,
            http = Ext.Array.filter(config.sources, function (value) {
                return value.label == setting.http;
            })[0];
        config.playlines.unshift(config.playlines[line]);
        config.playlines.splice(line + 1, 1);
        config.plugins.videoJsResolutionSwitcher.default = http ? http.res : 360;
        config.plugins.studyControl.enableSwitchWindow = 1;
        config.plugins.timelineObjects.url = '/richvideo/initdatawithviewer?';
        config.plugins.seekBarControl.enableFastForward = 1;
        if (!setting.queue) delete config.plugins.studyControl;
        // config.preload = setting.tip ? 'auto' : 'none';
        var player = vjs.apply(this, arguments),
            a = '<a href="https://d0.ananas.chaoxing.com/download/' + _self.config('objectid') + '" target="_blank">',
            img = '<img src="https://d0.ananas.chaoxing.com/download/e363b256c0e9bc5bd8266bf99dd6d6bb" style="margin: 6px 0 0 6px;">';
        player.volume(Math.round(setting.vol) / 100 || 0);
        Ext.get(player.controlBar.addChild('Button').el_).setHTML(a + img + '</a>').dom.title = '下载视频';
        player.on('loadstart', function () {
            setting.tip && this.play().catch(Ext.emptyFn);
            this.playbackRate(setting.rate > 16 || setting.rate < 0.0625 ? 1 : setting.rate);
        });
        player.one(['loadedmetadata', 'firstplay'], function () {
            setting.two = setting.rate === '0' && setting.two < 1;
            setting.two && config.plugins.seekBarControl.sendLog(this.children_[0], 'ended', Math.floor(this.cache_.duration));
        });
        player.on('ended', function () {
            Ext.fly(frameElement).parent().addCls('ans-job-finished');
        });
        return player;
    }
    那这段怎么改下呢
    回复

    使用道具 举报

  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 882 天

    [LV.10]以坛为家III

    30

    主题

    732

    回帖

    7358

    积分

    荣誉开发者

    精通各种语言的HelloWord!

    积分
    7358

    荣誉开发者油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-3-5 09:21:23 | 显示全部楼层
    社会摇中万人迷,唯有道总着人迷
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5966

    回帖

    6764

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6764

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-5 13:35:09 | 显示全部楼层
    yy550623346 发表于 2022-3-5 08:52
    沙发,顶起,多谢大佬

    已经更新了
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-3-25 15:30
  • 签到天数: 135 天

    [LV.7]常住居民III

    4

    主题

    109

    回帖

    206

    积分

    荣誉开发者

    积分
    206

    荣誉开发者油中2周年

    发表于 2022-3-5 21:37:56 | 显示全部楼层
    绊倒我的人、我们让他永远起不来
    扶起我的人、我们让他永远不会摔倒
    可恃唯我
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表