Skip to content

Instantly share code, notes, and snippets.

@springzfx
Last active November 23, 2023 02:24
Show Gist options
  • Save springzfx/cfa5fde3dbd3c6717ab3ed5936407f24 to your computer and use it in GitHub Desktop.
Save springzfx/cfa5fde3dbd3c6717ab3ed5936407f24 to your computer and use it in GitHub Desktop.
MPV-射手影音字幕插件
'use strict'
var search_subtitles = function(){
//var savedir="~/.cache/mpv/";
//mp.command("run","mkdir","-p",savedir);
var fname=mp.get_property("path","");
mp.osd_message("正在搜索字幕...",1);
var HOME=mp.utils.subprocess({args:['printenv','HOME']}).stdout.trim(); //get $HOME env
var result=mp.utils.subprocess({args: ["python",HOME+"/.config/mpv/scripts/SPlayerSub.py",fname],capture_stdout:true,capture_stderr:true});
if (result.status>=0 && result.stdout){
mp.osd_message("字幕下载成功",1);
mp.command("rescan-external-files");
}else if (result.status<0) {
mp.osd_message("执行错误:"+result.status,2);
}else{
mp.osd_message(result.stderr,2);
}
};
mp.add_key_binding('a',search_subtitles);
save-position-on-quit
keep-open=yes
slang=zh,en
sub-auto=fuzzy
sub-file-paths=~/.cache/mpv/
#! /usr/bin/python
'''
Download subtitles using SPlayer API
@author: [email protected]
https://docs.google.com/document/d/1ufdzy6jbornkXxsD-OGl3kgWa4P9WO5NZb6_QYZiGI0/preview#
射手影音智能字幕查询API(JSON)
功能: 根据客户端提交的信息,返回匹配字幕信息和字幕数据包
通讯协议: HTTP POST
接口地址: https://www.shooter.cn/api/subapi.php
上行参数:
|参数名称|类型|含义|备注|示例|
|--------|----|----|----|----|
|filehash|String|视频文件的hash码|必填|参考“文件Hash算法协议”|
|pathinfo|String|视频文件的所在路径名和文件名|必填|D:/Matrix.720p.HDTV.X264-DIMENSION/md.mkv|
|format|String|结果输出格式,值必须为 json|必填|json|
|lang|String|字幕语言|可选|eng或者chn|
注:参数均以标准的RFC 3986协议编码传送。即以文字的UTF8值进行URLEncode编码传送。例如“中国”,将以“%E4%B8%AD%E5%9B%BD”传送。
下行数据:
尚不能提供字幕时将返回一个字节,值为0xff(-1)。
可提供字幕时会返回json格式的Subinfo结构的Array数据,结构如下:
type Fileinfo struct {
Ext string // 文件扩展名
Link string // 文件下载链接
}
type Subinfo struct {
Desc string // 备注信息
Delay int32 // 字幕相对于视频的延迟时间,单位是毫秒
Files []Fileinfo // 包含文件信息的Array。 注:一个字幕可能会包含多个字幕文件,例如:idx+sub格式
}
https://docs.google.com/document/d/1w5MCBO61rKQ6hI5m9laJLWse__yTYdRugpVyz4RzrmM/preview
SVPlayer视频文件hash算法 (草)
Version. 0.1 Date: 2008-11-04
方案
取文件第4k位置,再根据floor( 文件总长度/3 )计算,取中间2处,再取文件结尾倒数第8k的位置, 4个位置各取4k区块做md5。共得到4个md5值,均设为索引。可以进行智能匹配。 (可以应用于不完全下载的p2p文件)
'''
import os
import sys
import json
import hashlib
import requests
def fileHash(fname):
file = open(fname, 'rb')
file.seek(0,2)
length = file.tell()
hash = []
for i in [4096, int(length*2/3), int(length/3), length-8192]:
file.seek(i, 0)
buf = file.read(4096)
hash.append(hashlib.md5(buf).hexdigest())
return ';'.join(hash)
def makeData(fname, lang='chn'):
''' makeData(fname, lang)
lang = 'chn' or 'eng' '''
data = {}
data['filehash']=fileHash(fname)
data['pathinfo']=fname
data['format']='json'
data['lang']=lang
return data
def getSubInfo(data):
url = r'https://www.shooter.cn/api/subapi.php'
try:
q = requests.post(url, data=data)
except:
sys.stderr.write('network error!\n')
sys.exit()
if q.content == b'\xff':
return None
else:
res = json.loads(q.text)
info = [] #[[(url, ext)], delay, desc]
for sub in res:
urls = [(file['Link'], file['Ext']) for file in sub['Files']]
delay = sub['Delay']
desc = sub['Desc']
info.append([urls, delay, desc])
return info
def writeSub(info, fname, lang='chn'):
''' lang = 'chn' or 'eng' '''
try:
fname = os.path.basename(fname)
fname = os.path.splitext(fname)[0]
except:
pass
for no, subs in enumerate(info):
name = fname + '.' + lang + str(no)
if len(subs[0]) == 1:
url = subs[0][0][0]
try:
data = requests.get(url).content
except:
sys.stderr.write('network error while downloading !\n')
with open(name+'.'+subs[0][0][1],'wb') as f:
f.write(data)
else:
for noo, sub in enumerate(subs[0]):
url = sub[0]
try:
data = requests.get(url).content
except:
sys.stderr.write('network error while downloading !\n')
with open(name+'.'+str(noo)+'.'+sub[1],'wb') as f:
f.write(data)
sys.stdout.write("Subtitle: {}\nDelay: {}\nDescription: {}\n\n".format(name, subs[1], subs[2]))
sys.stdout.flush()
def downloadSub(fname, subsavepath='./', lang='all'):
''' lang = 'chn' or 'eng' or 'all' '''
if lang in ('chn', 'eng'):
langs = [lang]
else:
langs = ('chn', 'eng')
for lang in langs:
data = makeData(fname, lang)
info = getSubInfo(data)
if info:
oldcwd=os.getcwd()
subpath=os.path.expanduser(subsavepath)
os.makedirs(subpath, exist_ok=True)
os.chdir(subpath)
writeSub(info, fname, lang)
os.chdir(oldcwd)
else:
sys.stderr.write("no subtitle found\n")
sys.stderr.flush()
if __name__ == '__main__':
downloadSub(sys.argv[1], "~/.cache/mpv/", lang='chn')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment