第三个脚本——时间加速and视频倍速

目录

本文主要内容

granr属性介绍

run-at属性

时间加速原理

视频倍速原理

完整示例


本文主要内容

介绍grant属性,run-at属性以及时间加速,视频倍速原理

granr属性介绍

相关函数四个:

GM_setValue
GM_getValue
GM_listValues
GM_deleteValue

当然,还有存储内容变动时相关的函数

GM_addValueChangeListener
GM_removeValueChangeListener

接下来分别介绍一下

GM_setValue: 

假设代码 GM('myName', 'woonigh'

在Tampermonkey管理的存储中,把名字是myName的存储,设置值为 'woonigh' 

GM_getValue:

GM_getValue('myName', 'woonigh')

就是把名字是 myName 的存储的值读取出来,

如果找不到myName的值呢?那就用默认的值 'woonigh' 

GM_listValues: 

这个没有参数,就是把所有存储的名字罗列出来。

返回结果是 Array类型 

适合于:

  • 你的应用很大,需要做存储数据管理
  • 你的应用数据很乱

GM_deleteValue:

假设代码 GM_deleteValue('myName')

就是删除名字叫做 myName 的存储。

和上面 GM_listValues 一样,多用于数据管理。两者是一对。  

GM_addValueChangeListener:

对指定的名字进行监听,该函数返回一个id

该函数可以跨函数通信

格式为

GM_addValueChangeListener(name, function(name, old_value, new_value, remote) {

})

name为值的名称

函数的name也是

old_value为旧值

new_value为新值

remote区分这个值的改变的所属,如果是由本标签页引起的,则为false,如果由其他标签页引起的,为true。

GM_removeValueChangeListener:

移除一个监听器

GM_removeValueChangeListener(listener_id)
根据监听器的 ID,把监听器移除

示例如下:

// 存储中 增加一个存储量,名字叫 'myName', 值是'woonigh'
let my_name = GM_setValue('myName', 'Woonigh');

// 读取存储中的,名字叫 'hisName' 的值, 如果没有这个名字的存储的话,那返回来的值就叫 'Tony'
let his_name = GM_getValue('hisName', 'Tony');

// 把存储中所有的存储名字罗列出来
let all_value_names = GM_listValues();
console.log(all_value_names); // 输出  ["myName"]

// 给名字叫 'myName' 的存储添加一个监听器
let listener1 = GM_addValueChangeListener('myName', function (name, old_value, new_value, remote) {
  console.log(`
    发生变化的存储名是: ${name},
    ${name} 原来的值是 ${old_value},
    ${name} 新的值是 ${new_value},
    这个值的变动是由${remote ? '本标签页' : '其他标签页'} 引起的。
  `);
});

GM_setValue('myName', 'Maxwell');

// 把 id 是listener1 的监听器移除
GM_removeValueChangeListener(listener1);

// 把名字叫 'myNamae' 的存储删除掉
GM_deleteValue('myName');

run-at属性

一个比较重要的属性

当我们设置为:// @run-at document-start  

表示希望脚本能尽快注入,在时间加速时希望抢在前端调用setInterval之前来替换掉setInterval函数

时间加速原理

  如网站:时间校准_北京时间校准_北京时间在线校准_现在北京时间

但是该网站的时间加速已经失效了

一般情况下,都是使用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,
也就是:

// @grant        unsafeWindow
let hookSetInterval=unsafeWindow.setInterval;//将系统提供的setInterval保存
unsafeWindow.setInterval=function(a,b){//将系统的setInterval替换为我们自己的
    return hookSetInterval(a,b/2);//经过处理后再调用系统的setInterval
}

视频倍速原理

视频倍速主要涉及h5的video,里面有一个播放速度的属性:playbackRate,最高为16倍.

解释网址如:HTMLMediaElement.playbackRate - Web API 接口参考 | MDN

像B站的视频页面,我们可以直接通过document.querySelector('video')获取,,如果有多个选择器写好也没问题.代码如下:

document.querySelector('video').playbackRate=2;

完整示例

但是关于时间加速的网站,已经不能通过此方法实现,B站可以但也有一定局限性,大家可以仿照写其他网站的,我们也可能遇到一下问题

1.视频暂停再取消会重置倍速

2.网站代码与脚本冲突

解决方法

1.固定playbackRate属性,或者让他网页的js不重置倍速,再暴力点可以通过计时器定时设置倍速

2.进行延迟注入

3.追根溯源,找到最根本的问题,一次性解决

// ==UserScript==
// @name         视频加速与时间加速
// @namespace    https://bbs.tampermonkey.net.cn/
// @version      0.1
// @description  用于:http://time.tianqi.com/的时间加速和用于bilibili的一个视频倍速:https://www.bilibili.com/video/BV1ys411p7To
// @author       You
// @match        http://time.tianqi.com/
// @match        https://www.bilibili.com/video/*
// @run-at       document-start
// @grant        unsafeWindow
// ==/UserScript==

let rate=4;//倍速

if(unsafeWindow.location.href.indexOf('time.tianqi.com')!=-1){
    //时间网站,用时间加速
    let hookSetInterval=unsafeWindow.setInterval;//将系统提供的setInterval保存
    unsafeWindow.setInterval=function(a,b){//将系统的setInterval替换为我们自己的
        return hookSetInterval(a,b/rate);//经过处理后再调用系统的setInterval
    }
}else{
    //bilibili用视频加速
    unsafeWindow.onload=function(){
        //在元素都加载完成后再监听video的播放时间,再进行倍速设置
        unsafeWindow.document.querySelector('video').onplay=function(){
            unsafeWindow.document.querySelector('video').playbackRate=rate;
        }
    }
}

俺是初学者,请大佬们不要见笑,请多多指点,谢谢!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我了解了你的问题。你想要编写一个 ArcGIS Python 脚本,能够根据要素类(shp)的一个字段内容,将这个要素类拆分成多个要素类,对吗? 那么,你可以按照以下步骤来编写这个脚本: 1. 首先,导入必要的 Python 模块和 ArcGIS 模块,包括 arcpy 和 os 模块。 ``` import arcpy import os ``` 2. 定义输入要素类的路径和字段名称。 ``` in_fc = r"path/to/input/feature/class.shp" split_field = "field_name" ``` 3. 使用 arcpy.da.SearchCursor 函数遍历要素类中的每个要素,并根据指定字段的值创建一个字典,其中键为字段值,值为要素类中包含该字段值的所有要素的列表。 ``` split_dict = {} with arcpy.da.SearchCursor(in_fc, [split_field]) as cursor: for row in cursor: if row[0] not in split_dict: split_dict[row[0]] = [] split_dict[row[0]].append(row) ``` 4. 遍历字典中的每个键值对,使用 arcpy.CopyFeatures_management 函数将包含每个键值对所对应字段值的所有要素复制到一个新的要素类中。 ``` out_folder = r"path/to/output/folder" for value, rows in split_dict.items(): out_name = "split_" + str(value) + ".shp" out_path = os.path.join(out_folder, out_name) arcpy.CopyFeatures_management(rows, out_path) ``` 5. 完整的代码如下所示: ``` import arcpy import os in_fc = r"path/to/input/feature/class.shp" split_field = "field_name" out_folder = r"path/to/output/folder" split_dict = {} with arcpy.da.SearchCursor(in_fc, [split_field]) as cursor: for row in cursor: if row[0] not in split_dict: split_dict[row[0]] = [] split_dict[row[0]].append(row) for value, rows in split_dict.items(): out_name = "split_" + str(value) + ".shp" out_path = os.path.join(out_folder, out_name) arcpy.CopyFeatures_management(rows, out_path) ``` 这个脚本将会根据输入要素类的指定字段值,将要素类拆分成多个要素类,并将这些要素类保存到指定的输出文件夹中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值