主要是为了方便压字幕。
之前(很久)弄VapourSynth把电脑环境搞得乱七八糟的,根据官方指南知道是可以搞个便携版的。

需要的物料(目前最新)

x265选的是x265-gcc-multilib-full.exe

解压整理

Simply decompress the portable VapourSynth archive into the Python dir
and overwrite all existing files. Done.
  • 新建一个文件夹EncodeWorker
  • EncodeWorker下新建一个文件夹Tools、一个Fonts文件夹和一个Binaries文件夹
  • 将前面下载的三个压缩包全部解压至EncodeWorker/Tools中
  • 将x264/x265/ffmpeg的exe提取至Binaries中
  • EncodeWorker文件夹下新建go.vpy和go.bat文件

至此准备工作完成,完整压缩包奉上

插件模板等

例如经常需要用到的havsfunc、adjust、mvsfunc和nnedi3_resample可以到HomeOfVapourSynthEvolution下载,
vapoursynth上提到的插件也指出了一些下载。

添加了一些插件和py文件,全部结构如下

由于自用的浏览器cookie管理插件导入导出时用的是字典形式,而python里面对[{}, {}]的cookies加载支持不太友好。
所以根据RFC6265和RequestsCookieJar源码,写了一个适用于此形式cookie的转换脚本,便于python载入使用。
代码如下:

'''
@作者: weimo
@创建日期: 2020-04-11 21:45:46
@上次编辑时间: 2020-04-11 22:37:48
@一个人的命运啊,当然要靠自我奋斗,但是...
'''
import json
from pathlib import Path
from http.cookiejar import Cookie
from requests.cookies import RequestsCookieJar

def convert(cookies_path: str = "cookies.json"):
    # convert [{}, {}] cookies to RequestsCookieJar format
    try:
        _cookies = json.loads(Path(cookies_path).read_text(encoding="utf-8"))
    except Exception as e:
        return
    BASECOOKIE = {
        "version": 0,
        "name": "",
        "value": "",
        "port": None,
        "port_specified": False,
        "domain": "",
        "domain_specified": False,
        "domain_initial_dot": False,
        "path": "/",
        "path_specified": False,
        "secure": False,
        "expires": None,
        "discard": False,
        "comment": None,
        "comment_url": None,
        "rest": {},
    }
    cookies = RequestsCookieJar()
    for c in _cookies:
        BASECOOKIE["name"] = c["name"]
        BASECOOKIE["value"] = c["value"]
        if c["domain"] != "":
            BASECOOKIE["domain"] = c["domain"]
            BASECOOKIE["domain_specified"] = True
            if c["domain"].split(".").__len__() == 3:
                BASECOOKIE["domain_initial_dot"] = True
        BASECOOKIE["path"] = c["path"]
        BASECOOKIE["secure"] = c["secure"]
        BASECOOKIE["expires"] = c.get("expirationDate")
        if c["path"] != "":
            BASECOOKIE["path"] = c["path"]
            BASECOOKIE["path_specified"] = True
        if c["httpOnly"]:
            BASECOOKIE["rest"].update({"httpOnly":None})
        if c["hostOnly"]:
            BASECOOKIE["rest"].update({"hostOnly":None})
        cookies.set_cookie(Cookie(**BASECOOKIE))
    return cookies

if __name__ == "__main__":
    convert("cookies.json")

比如现在有一张图是这样的
彩色原图
转换到HSV空间
请输入图片描述
二值化后是这样的
inrange处理
我想保留文字,尽可能去掉大块的白色部分,
思路:首先将二值化图像进行腐蚀操作,然后进行膨胀操作,这样大块的白色部分不会怎么变,而文字则会再腐蚀的时候被去掉。
腐蚀
膨胀
一来二去现在就剩下白块部分了,如果膨胀的力度比腐蚀大一点,现在对其进行取反。
最后与原二值图像相与,这样文字部分基本都会保留,文字周围的部分不会受到影响,而原来的白块部分则会被“挖”出一个只剩边缘的区域。甚至能完全去掉白块部分。
取反相与
在这运算过程中,需要根据文字把握好腐蚀膨胀的程度。

光猫

型号:PT952G
->宽带设置

5_INTERNET_B_VID_100

桥接+DHCP Server启用+IPv4/IPv6+桥类型PPPoE_Bridged

如图:
光猫配置

路由器

型号:K2A2
固件:Padavan(RT-AC54U-GPIO-1-PSG1218-64M_3.4.3.9-099.trx)

  1. 光猫LAN口接路由器WAN口
  2. 外部网络 (WAN) - 外网设置

    1. 外网连接类型选择PPPoE:拨号
    2. PPP VPN 客户端设置填写宽带账号
      外网设置
  3. 外部网络 (WAN) - IPv6 设置

    1. IPv6 连接类型选择Native DHCPv6
    2. 获取 IPv6 外网地址选择Stateless: RA
    3. 开启通过 DHCPv6 获取内网 IPv6 地址
    4. 开启启用 LAN 路由器通告
      IPv6 设置
  4. ipv6防火墙

    1. ssh登录路由器,用户名密码默认都是admin。
    2. 清空ipv6防火墙规则

      ip6tables -P FORWARD ACCEPT
      ip6tables -F FORWARD

    3. 放行特定端口外部访问

      ip6tables -I INPUT -p tcp -m multiport --dport 45645 -j ACCEPT

最后

现在可以通过ipv6+port访问了

参考:

如有错误,还请指正。

什么是box

根据CFFMediaFormat(Common File Format & Media Formats Specification)的说明,box指的是通过特定标识符和长度定义的面向对象建立的块。
请输入图片描述

什么是pssh

pssh全称是Protection System Specific Header,即用于标识保护系统的特定头(不顺口的解释)

pssh box的构成

目前主流的DRM系统主要是PlayReady,Widevine和Fairplay三家(微软、谷歌和苹果),在它们的DRM系统数据交换中pssh是一个关键的值。

pssh box的标准构成:

  • 4 bytes – the size of the PSSH box
  • 4 bytes – the constant “PSSH”
  • 4 bytes – flags based on the ISOBMFF specification
  • 16 bytes – unique key system identifier
  • 4 bytes – size of the data inside the PSSH box
  • byte array – data itself

通常情况下,pssh能在mpd一类的文件中见到,例如使用widevine的视频网站,其中的mpd文件大致长这样:
请输入图片描述

一个容易见到且典型的pssh一般就是这个样子了(base64编码形式的):

AAAAQHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACAIARIQ+0sI0/UVlrXzdUjHhhmNNRoEa2t0diIEa2t0dg==

为了方便理解,将它转换到十进制形式:

list(base64.b64decode(b'AAAAQHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACAIARIQ+0sI0/UVlrXzdUjHhhmNNRoEa2t0diIEa2t0dg=='))
[0, 0, 0, 64, 112, 115, 115, 104, 0, 0, 0, 0, 237, 239, 139, 169, 121, 214, 74, 206, 163, 200, 39, 220, 213, 29, 33, 237, 0, 0, 0, 32, 8, 1, 18, 16, 251, 75, 8, 211, 245, 21, 150, 181, 243, 117, 72, 199, 134, 25, 141, 53, 26, 4, 107, 107, 116, 118, 34, 4, 107, 107, 116, 118]

按标准依次分解如下(各类进制转换请自行脑补):

  • 0, 0, 0, 64 表示整个pssh box长度64字节
  • 112, 115, 115, 104 对应的ascii字符就是pssh(小写)
  • 0, 0, 0, 0 表示根据ISOBMFF中特定的标识符
  • 237, 239, 139, 169, 121, 214, 74, 206, 163, 200, 39, 220, 213, 29, 33, 237 表示DRM系统的特定ID,这里的ID是widevine类型,参见此处
  • 0, 0, 0, 32 表示pssh box内的数据长度,即从此处偏移这个长度后到达pssh box末尾
  • 8, 1, 18, 16, 251, 75, 8, 211, 245, 21, 150, 181, 243, 117, 72, 199, 134, 25, 141, 53, 26, 4, 107, 107, 116, 118, 34, 4, 107, 107, 116, 118 该部分32字节,这里实际上是对应视频和音频的两个KID。

其他

  • KID是加密的音频轨道或视频轨道等的特定密钥标识符,简单来说加密视频时这个KID和key对应,如果你知道一对KID和key,那么就能解密由该KID标识的视频/音频文件等。
  • pssh末尾部分不一定是直接两个KID,也有可能是其他构成方式