最近把家里的HDPC终于改成Debian了,起初一直在Windows 10下,但经过长时间的使用,装着E5200芯的老机器终于拉不动了,启动都要卡半天。思索了半天,干脆换到了Debian下。没去试现在的安卓X86版本和凤凰系统,是因为不想过于折腾了,虽说Debian并不是个好的娱乐平台,但好在安装Kodi倒是很方便对这个系统也比较熟悉,而我也仅仅用它就可以了。
安装的是Debian 9.4版本, Kodi是17.6的。设置什么的轻车熟路,电影、电视、直播啥的都基本没问题,但找遍了网上现有的中文字幕插件,就没一个可以用的,有的说是给15的版本可以用,但我没试而且也不想换版本。没办法了,只有自己改吧。
在这里真要吐槽一下Kodi的官方资料,英文的不说,而且是积极的简单,什么函数基本上就是一句话解释,连示例都没有一个,不过还好,综合了很多现成的源码,基本上了解了它字幕插件的思路和一些函数方法。代码是基于网络现有的插件基础上改的,字幕来源于字幕库。
首先是搜索函数,一番查验这个到是简单,原先的代码找不到内容是因为网站页面div的class改了,所以把bs的查找规则调整就ok了。
def Search( item ): subtitles_list = [] log( __name__ ,"Search for [%s] by name" % (os.path.basename( item['file_original_path'] ),)) if item['mansearch']: url = ZIMUKU_API % (item['mansearchstr']) else: url = ZIMUKU_API % (item['title']) try: socket = urllib.urlopen(url) data = socket.read() socket.close() soup = BeautifulSoup(data,'html.parser') except: return results = soup.find_all("div", class_="item prel clearfix") for it in results: moviename = it.find("div", class_="title").a.text.encode('utf-8') iurl = it.find("div", class_="title").a.get('href').encode('utf-8') movieurl = '%s%s' % (ZIMUKU_BASE, iurl) try: socket = urllib.urlopen(movieurl) data = socket.read() socket.close() soup = BeautifulSoup(data,'html.parser').find("table", class_="table") soup = soup.find("tbody") except: return subs = soup.find_all("tr") for sub in subs: name = sub.a.text.encode('utf-8') if name.split('.')[-1] not in ['zip','Zip','ZIP']: continue flag = sub.img.get('src').split('/')[-1].split('.')[0].encode('utf-8') lang = FLAG_DICT.get(flag,'unkonw') link = '%s%s' % (ZIMUKU_BASE, sub.a.get('href').encode('utf-8')) if lang == '英': subtitles_list.append({"language_name":"English", "filename":name, "link":link, "language_flag":'en', "rating":"0", "lang":lang}) else: subtitles_list.append({"language_name":"Chinese", "filename":name, "link":link, "language_flag":'zh', "rating":"0", "lang":lang})
而下载函数就麻烦了一点,看原来代码是获取下载地址后直接下载,而实际上我在网站下载时发现网站使用了301重定向,并且在访问下载地址时,网站做了防爬虫处理,需要在头里带上Referer,否则系统是不会给你正确的定向地址的,经过改动的代码如下:
def Download(url,lang): try: shutil.rmtree(__temp__) except: pass try: os.makedirs(__temp__) except: pass exts = [".srt", ".sub", ".smi", ".ssa", ".ass" ] try: socket = urllib.urlopen( url ) data = socket.read() soup = BeautifulSoup(data,'html.parser') url = soup.find("li", class_="li dlsub").a.get('href').encode('utf-8') socket = urllib.urlopen(url) socket = urllib.urlopen(url) data = socket.read() soup = BeautifulSoup(data,'html.parser') div = soup.find('div',class_='down clearfix') li = div.find('li') headers['Referer'] = url req = urllib2.Request(li.a.get('href'),headers=headers) resp = urllib2.urlopen(req) socket = urllib.urlopen(resp.geturl()) data = socket.read() socket.close() except: return [] if len(data) < 1024: return [] tempfile = os.path.join(__temp__, "subtitles.zip") xbmc.log(tempfile) with open(tempfile, "wb") as subFile: subFile.write(data) subFile.close() xbmc.sleep(500) lists = unZip(tempfile) lists = [i for i in lists if os.path.splitext(i)[1] in exts] if len(lists) == 1: return lists[0] else: index = [i.split('/')[-1] for i in lists] sel = xbmcgui.Dialog().select('请选择压缩包中的字幕', index) if sel == -1: sel = 0 return lists[sel]
经过调整,大的问题没有了,不过些小的地方,原代码里貌似是只能在Windows下用的,因为好像它是用Winrar来解压的,而我在Debian下使用,所以只能考虑Zip文件了,至于能不能用rar包还有单独的srt等文件,以后折腾吧。
def getFileList(path): fileslist = [] for d in os.listdir(path): if os.path.isdir(path+d): fileslist.extend(getFileList(path+d+'/')) if os.path.isfile(path+d): fileslist.append(path+d) return fileslistdef unZip(filepath): zip_file = zipfile.ZipFile(filepath,'r') for names in zip_file.namelist(): if type(names) == str and names[-1] != '/': utf8name = names.decode('gbk') data = zip_file.read(names) fo = open(os.path.join(__temp__, utf8name), "w") fo.write(data) fo.close() else: zip_file.extract(names,__temp__) return getFileList(__temp__+'/')
总结一下啊,用惯了Python3后用2真的不习惯,并且在Kodi里测试也是非常的不方便,改动一下需要重新进入才行,经过测试在Linux和Windows下都没问题,版本从17到最新的18,至于更低的版本则没测试,接下来要把各种字幕扩展名的文件下载功能补全,等到某一天有心情折腾了再说吧。附地址:https://pan.baidu.com/s/1GxAod4Xdll-3pvM_OOru8A
更新:由于上次改的有太多的局限性,所以继续抽时间改了改,现在这个版本继续支持Linux和Windows,并且文件格式由单纯的zip扩展到rar的压缩,还包括了各种未压缩的字幕格式,由于网上并没有发现7z的字幕压缩包,所以就没有考虑这个格式了。但现在由于格式的增多,就带来了一些问题,为了这个插件的正常使用,在Windows下必须要安装WinRAR并且目录还得是C:\Program Files\WinRAR,在Linux下需要安装unrar,否则的话会下载失败,其他没有要求,注意这点即可。
贴上代码:
def getFileList(path): fileslist = [] for d in os.listdir(path): if os.path.isdir(path+d): fileslist.extend(getFileList(path+d+'/')) if os.path.isfile(path+d): fileslist.append(path+d) return fileslistdef extractCompress(file): path = __temp__ + '/subtitles/' if os.path.isdir(path): shutil.rmtree(path) if not os.path.isdir(path): os.mkdir(path) if file.lower().endswith('zip'): zipFile = zipfile.ZipFile(file,'r') for names in zipFile.namelist(): if type(names) == str and names[-1] != '/': utf8name = names.decode('gbk') data = zipFile.read(names) with open(path+utf8name, 'wb') as f: f.write(data) else: zipFile.extract(names,path) return getFileList(path) if file.lower().endswith('rar'): if platform.system() == 'Windows': rarPath = 'C:\Program Files\WinRAR' sysPath = os.getenv('Path') if 'winrar' not in sysPath.lower(): os.environ["Path"] = sysPath+';'+rarPath command = "winrar x -ibck %s %s" % (file, path) if platform.system() == 'Linux': command = 'unrar x %s %s' % (file, path) res = os.system(command) if res == 0: return getFileList(path)def Search( item ): subtitles_list = [] log(__name__ ,"Search for [%s] by name" % os.path.basename(item['file_original_path'])) if item['mansearch']: url = ZIMUKU_API % (item['mansearchstr']) else: url = ZIMUKU_API % (item['title']) try: socket = urllib.urlopen(url) data = socket.read() socket.close() soup = BeautifulSoup(data,'html.parser') except: return results = soup.find_all("div", class_="item prel clearfix") for it in results: moviename = it.find("div", class_="title").a.text.encode('utf-8') iurl = it.find("div", class_="title").a.get('href').encode('utf-8') movieurl = '%s%s' % (ZIMUKU_BASE, iurl) try: socket = urllib.urlopen(movieurl) data = socket.read() socket.close() soup = BeautifulSoup(data,'html.parser').find("table", class_="table") soup = soup.find("tbody") except: return subs = soup.find_all("tr") for sub in subs: name = sub.a.text.encode('utf-8') flag = sub.img.get('src').split('/')[-1].split('.')[0].encode('utf-8') .get(flag,'unkonw') link = '%s%s' % (ZIMUKU_BASE, sub.a.get('href').encode('utf-8')) if lang == '英': subtitles_list.append({"language_name":"English", "filename":name, "link":link, "language_flag":'en', "rating":"0", "lang":lang}) else: subtitles_list.append({"language_name":"Chinese", "filename":name, "link":link, "language_flag":'zh', "rating":"0", "lang":lang}) if subtitles_list: for it in subtitles_list: listitem = xbmcgui.ListItem(label=it["language_name"], label2=it["filename"], iconImage=it["rating"], thumbnailImage=it["language_flag"] ) listitem.setProperty( "sync", "false" ) listitem.setProperty( "hearing_imp", "false" ) url = "plugin://%s/?action=download&link=%s&lang=%s" % (__scriptid__, it["link"], it["lang"] ) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=listitem,isFolder=False)def Download(url,lang): try: shutil.rmtree(__temp__) except: pass try: os.makedirs(__temp__) except: pass exts = [".srt", ".sub", ".smi", ".ssa", ".ass" ] try: socket = urllib.urlopen( url ) data = socket.read() soup = BeautifulSoup(data,'html.parser') url = soup.find("li", class_="li dlsub").a.get('href').encode('utf-8') socket = urllib.urlopen(url) socket = urllib.urlopen(url) data = socket.read() soup = BeautifulSoup(data,'html.parser') div = soup.find('div',class_='down clearfix') li = div.find('li') headers['Referer'] = url req = urllib2.Request(li.a.get('href'),headers=headers) resp = urllib2.urlopen(req) fileName = resp.headers['Content-Disposition'].replace('"','').split('=')[1] socket = urllib.urlopen(resp.geturl()) data = socket.read() socket.close() except: return [] if len(data) < 1024: return [] tempfile = os.path.join(__temp__, "subtitles.%s" % fileName.split('.')[-1]) xbmc.log(tempfile) with open(tempfile, "wb") as subFile: subFile.write(data) xbmc.sleep(100) if fileName.split('.')[-1].lower() in ('zip','rar'): lists = extractCompress(tempfile) else: lists = [tempfile] lists = [i for i in lists if os.path.splitext(i)[1] in exts] if len(lists) == 1: return lists[0] else: index = [i.split('/')[-1] for i in lists] sel = xbmcgui.Dialog().select('请选择压缩包中的字幕', index) if sel == -1: sel = 0 return lists[sel]
贴上下载地址:点击下载