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

[油猴脚本开发指南]h5视频倍速,时间加速和run-at

[复制链接]
  • TA的每日心情
    开心
    前天 13:37
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4196

    回帖

    4061

    积分

    管理员

    积分
    4061

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2020-12-24 14:55:21 | 显示全部楼层 | 阅读模式
    本节主要内容:
    视频加速与时间加速,会写一个用于:http://time.tianqi.com/的时间加速和用于bilibili的一个视频倍速:https://www.bilibili.com/video/BV1ys411p7To

    时间加速例子已经失效,请去http://110.42.220.200/time.html实战


    时间加速
    首先来介绍一下时间加速的原理.一般情况下,都是使用setInterval来做定时器,我们只要把这个定时器的时间缩短,比如之前是1s触发一次,现在变成500ms触发一次,那么就相当于时间缩短了一倍.

    怎么缩短呢?我们可以劫持setInterval这个函数,传入值为1000,我们把他变为500.代码类似下面这样:
    ```
    let hookSetInterval=window.setInterval;//将系统提供的setInterval保存
    window.setInterval=function(a,b){//将系统的setInterval替换为我们自己的
        return hookSetInterval(a,b/2);//经过处理后再调用系统的setInterval
    }
    ```


    在脚本中也是类似的代码,不过如果使用//@grant unsafeWindow的话,window替换为unsafeWindow,

    视频倍速
    视频倍速的话,其实也很简单,主要牵扯到h5的video,里面有一个播放速度的属性:playbackRate,最高为16倍.
    https://developer.mozilla.org/zh ... lement/playbackRate

    像b站这个页面,里面只有一个视频,我们直接document.querySelector('video')就可以获取到了,如果有多个选择器写好也没问题.代码如下:
    ```
    document.querySelector('video').playbackRate=2;
    ```
    RUN-AT
    注意这里还有一个比较重要的属性:// @run-at,:https://www.tampermonkey.net/documentation.php#_run_at
    主要是设置脚本运行的时候.这里我们设置为:// @run-at document-start 希望脚本尽快的被注入,因为我们要抢在前端调用setInterval之前来替换掉setInterval函数.

    脚本
    知道上面的做法后,脚本也很容易写了,这次我们再来复习下之前的unsafeWindow和//@match.
    代码我另外发帖了:https://bbs.tampermonkey.net.cn/thread-179-1-1.html

    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。

    该用户从未签到

    0

    主题

    4

    回帖

    20

    积分

    助理工程师

    积分
    20
    发表于 2021-1-24 13:32:04 | 显示全部楼层
    为什么我自己写了一个计时器hook不了  设置grant none 和不设置都不行  也设置了run-at
    可以打印出提示 但是 计时器还是1秒的
    html:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <span id="timer"></span>
    </body>
        <script>
            var now = new Date();   
            var hour,minute,second;
            hour = now.getHours();
            minute = now.getHours();
            second = now.getSeconds();

            var func = () => {
                document.querySelector('#timer').innerText = hour+':'+minute+':'+second;
                second++;
            };

            setInterval(func, 1000);
        </script>
    </html>

    脚本:
    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        http://127.0.0.1:5500/web/timer/index.html
    // @run-at       document-start
    // @grant        unsafeWindow
    // ==/UserScript==

    (function() {
        'use strict';

    /*     alert('hook');
        let hookInterval = window.setInterval;
        let cnt = 0;
        let newInterval = (a,b)=>{
            console.log('new interval',cnt);
            cnt++;
            return hookInterval(a,b*100);
        };
        window.setInterval = hookInterval;
        console.log('ok'); */

        console.log('begin');
        let hookSetInterval=unsafeWindow.setInterval;//将系统提供的setInterval保存
        unsafeWindow.setInterval=function(a,b){//将系统的setInterval替换为我们自己的
        console.log('ok');
        return hookSetInterval(a,7000);//经过处理后再调用系统的setInterval

    }
    })();
    回复

    使用道具 举报

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

    [LV.7]常住居民III

    712

    主题

    5966

    回帖

    6763

    积分

    管理员

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

    积分
    6763

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

    发表于 2021-1-24 13:58:20 | 显示全部楼层
    cao 发表于 2021-1-24 13:32
    为什么我自己写了一个计时器hook不了  设置grant none 和不设置都不行  也设置了run-at
    可以打印出提示 但 ...

    这点应该是你是本地服务器,加载过快,脚本管理器还没有注入脚本
    你试着卡一下网速看看
    当输入run-at 只能保证管理器相对普通脚本尽快被注入,不能保证100%被注入
    这点我视频提到过
    不同的插件由于实现原理不同也存在不同的表现特性我记得
    这是浏览器插件特性导致的,目前来看没什么特别好的解决方案

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

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

    使用道具 举报

  • TA的每日心情
    开心
    前天 13:37
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4196

    回帖

    4061

    积分

    管理员

    积分
    4061

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2021-1-24 14:02:33 | 显示全部楼层
    cao 发表于 2021-1-24 13:32
    为什么我自己写了一个计时器hook不了  设置grant none 和不设置都不行  也设置了run-at
    可以打印出提示 但 ...
    [md]
    你的代码太简单了,hook计时器的时候,已经被调用了

    油猴的能力是尽可能的快,但是不能**完全保证**能够在页面的代码执行**前运行脚本**,这是浏览器扩展机制导致的

    页面代码修改成这样就可以(增加了window.onload)

    ```html
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>

    <body>
        <span id="timer"></span>
    </body>
    <script>
        window.onload = function() {
            var now = new Date();
            var hour, minute, second;
            hour = now.getHours();
            minute = now.getHours();
            second = now.getSeconds();

            var func = () => {
                document.querySelector('#timer').innerText = hour + ':' + minute + ':' + second;
                second++;
            };

            setInterval(func, 1000);
        }
    </script>

    </html>
    ```
    [/md]
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    4

    回帖

    20

    积分

    助理工程师

    积分
    20
    发表于 2021-1-24 14:55:31 | 显示全部楼层
    谢谢哥哥们
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    4

    回帖

    20

    积分

    助理工程师

    积分
    20
    发表于 2021-1-26 14:23:57 | 显示全部楼层
    哥哥们 我又遇到问题了 比如这个网站 https://player.alicdn.com/aliplayer/index.html
    直接在网页控制台中设置 window.document.querySelector('video').playbackRate=8; 是可以加速的
    但是 写在脚本里就不行
    b站是正常的 。。aliplayer不知道为啥不行
    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://www.bilibili.com/video/*
    // @match        https://player.alicdn.com/aliplayer/index.html
    // @run-at       document-start
    // @grant        unsafeWindow

    // ==/UserScript==

    let rate = 8;


        'use strict';
        unsafeWindow.onload=function(){
            //在元素都加载完成后再监听video的播放时间,再进行倍速设置
            unsafeWindow.document.querySelector('video').onplay=function(){

                unsafeWindow.document.querySelector('video').playbackRate=rate;
            }
        }
    回复

    使用道具 举报

  • TA的每日心情
    开心
    前天 13:37
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4196

    回帖

    4061

    积分

    管理员

    积分
    4061

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2021-1-26 14:46:03 | 显示全部楼层

    cao 发表于 2021-1-26 14:23

    哥哥们 我又遇到问题了 比如这个网站 https://player.alicdn.com/aliplayer/index.html
    直接在网页控制台中 ...

    image.png

    我调试了一下

    1.每次暂停再播放,网站的代码会重置播放速度

    2.第一次播放时应该是autoplay,onplay事件没有监听到,所以没有执行设置速率的那个代码

    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://www.bilibili.com/video/*
    // @match        https://player.alicdn.com/aliplayer/index.html
    // @run-at       document-start
    // @grant        unsafeWindow
    
    // ==/UserScript==
    
    let rate = 8;
    
    'use strict';
    unsafeWindow.onload=function(){
        unsafeWindow.document.querySelector('video').playbackRate=rate;
    }
    

    另外还可以加个计时器,定时设置速率,如果更复杂的话,就用hook,object.defineproperty(猜的,没实验)之类的技术,固定playbackRate属性,或者让他网页的js不重置倍速,暴力点可以直接计时器(计时器yyds)

    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-6-5 00:59
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    9

    主题

    42

    回帖

    233

    积分

    管理员

    积分
    233

    管理员油中3周年

    发表于 2021-1-26 15:12:07 | 显示全部楼层
    cao 发表于 2021-1-26 14:23
    哥哥们 我又遇到问题了 比如这个网站 https://player.alicdn.com/aliplayer/index.html
    直接在网页控制台中 ...

    这种情况一般因为程序自身跟脚本冲突了
    脚本先执行一次速度,然后网页又复写了一次速度
    解决这种办法一种是追终溯源,另外一种比较简单,直接加个延时跟网页错开
    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://www.bilibili.com/video/*
    // @match        https://player.alicdn.com/aliplayer/index.html
    // @run-at       document-start
    // @grant        unsafeWindow

    // ==/UserScript==

    let rate = 8;


        'use strict';
        unsafeWindow.onload=function(){
            //在元素都加载完成后再监听video的播放时间,再进行倍速设置
            unsafeWindow.document.querySelector('video').onplay=function(){
                console.log('set')

    unsafeWindow.setInterval(function(){ unsafeWindow.document.querySelector('video').playbackRate=rate; }, 3000);

            }
        }
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-6-5 00:59
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    9

    主题

    42

    回帖

    233

    积分

    管理员

    积分
    233

    管理员油中3周年

    发表于 2021-1-26 15:12:55 | 显示全部楼层
    cao 发表于 2021-1-26 14:23
    哥哥们 我又遇到问题了 比如这个网站 https://player.alicdn.com/aliplayer/index.html
    直接在网页控制台中 ...

    哥哥有小作品记得论坛发布一下~
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    4

    回帖

    20

    积分

    助理工程师

    积分
    20
    发表于 2021-1-29 21:24:42 | 显示全部楼层
    ok~ 谢谢大佬们
    回复

    使用道具 举报

    发表回复

    本版积分规则

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