默认变成直接进字幕池,颜色红色,18号小字,冷却0.1秒。
封号不负责。
https://github.com/cnbeining/srt2bilibili
代码下面。
#!/usr/bin/env python
#coding:utf-8
# Author: Beining --<ACICFG>
# Purpose: A batch poster of srt file to danmaku on Bilibili.
# Created: 11/23/2014
# srt2Bilibili is licensed under GNUv2 license
'''
srt2Bilibili 0.02
Beining@ACICFG
cnbeining[at]gmail.com
http://www.cnbeining.com
https://github.com/cnbeining/srt2bilibili
GNUv2 license
'''
import sys
import os
import random
import requests
import urllib
import pysrt
import logging
import hashlib
import time as time_old
import getopt
from xml.dom.minidom import parse, parseString
import xml.dom.minidom
global APPKEY, SECRETKEY, VER, rnd, cid
APPKEY = '85eb6835b0a1034e'
SECRETKEY = '2ad42749773c441109bdc0191257a664'
VER = '0.02'
#----------------------------------------------------------------------
def calc_sign(string):
"""str/any->str
return MD5.
From: Biligrab, https://github.com/cnbeining/Biligrab
MIT License"""
return str(hashlib.md5(str(string).encode('utf-8')).hexdigest())
#----------------------------------------------------------------------
def find_cid_api(vid, p):
"""find cid and print video detail
str,int?,str->str
TODO: Use json.
From: Biligrab, https://github.com/cnbeining/Biligrab
MIT License"""
cid = 0
if str(p) is '0' or str(p) is '1':
str2Hash = 'appkey={APPKEY}&id={vid}&type=xml{SECRETKEY}'.format(APPKEY = APPKEY, vid = vid, SECRETKEY = SECRETKEY)
biliurl = 'https://api.bilibili.com/view?appkey={APPKEY}&id={vid}&type=xml&sign={sign}'.format(APPKEY = APPKEY, vid = vid, SECRETKEY = SECRETKEY, sign = calc_sign(str2Hash))
else:
str2Hash = 'appkey={APPKEY}&id={vid}&page={p}&type=xml{SECRETKEY}'.format(APPKEY = APPKEY, vid = vid, p = p, SECRETKEY = SECRETKEY)
biliurl = 'https://api.bilibili.com/view?appkey={APPKEY}&id={vid}&page={p}&type=xml&sign={sign}'.format(APPKEY = APPKEY, vid = vid, SECRETKEY = SECRETKEY, p = p, sign = calc_sign(str2Hash))
logging.debug(biliurl)
logging.info('Fetching webpage...')
try:
request = urllib.request.Request(biliurl, headers=BILIGRAB_HEADER)
response = urllib.request.urlopen(request)
data = response.read()
dom = parseString(data)
for node in dom.getElementsByTagName('cid'):
if node.parentNode.tagName == "info":
cid = node.toxml()[5:-6]
logging.info('cid is ' + cid)
break
return cid
except: # If API failed
logging.warning('Cannot connect to API server! \nIf you think this is wrong, please open an issue at \nhttps://github.com/cnbeining/Biligrab/issues with *ALL* the screen output, \nas well as your IP address and basic system info.')
return 0
#----------------------------------------------------------------------
def convert_cookie(cookie_raw):
"""str->dict
'DedeUserID=358422; DedeUserID__ckMd5=72682a6838d150dd; SESSDATA=72e0ee97%2C1419212650%2C6b47a180'
cookie = {'DedeUserID': 358422, 'DedeUserID__ckMd5': '72682a6838d150dd', 'SESSDATA': '72e0ee97%2C1419212650%2C6b47a180'}"""
cookie = {}
logging.debug('Raw Cookie: ' + cookie_raw)
try:
for i in [i.strip() for i in cookie_raw.split(';')]:
cookie[i.split('=')[0]] = i.split('=')[1]
except IndexError:
#if someone put a ; at the EOF
pass
return cookie
#----------------------------------------------------------------------
def getdate():
"""None->str
2014-11-23 10:39:46"""
return time_old.strftime("%Y-%m-%d %X", time_old.localtime())
#----------------------------------------------------------------------
def post_one(message, rnd, cid, cookie, fontsize = 25, mode = 1, color = 16777215, playTime = 0, pool = 0):
"""
PARS NOT THE PERFECT SAME AS A PAYLOAD!"""
headers = {'Origin': 'http://static.hdslb.com', 'X-Requested-With': 'ShockwaveFlash/15.0.0.223', 'Referer': 'http://static.hdslb.com/play.swf', 'User-Agent': BILIGRAB_UA, 'Host': 'interface.bilibili.com', 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': cookie}
url = 'http://interface.bilibili.com/dmpost'
try:
date = getdate()
payload = {'fontsize': int(fontsize), 'message': str(message), 'mode': int(mode), 'pool': pool, 'color': int(color), 'date': str(date), 'rnd': int(rnd), 'playTime': playTime, 'cid': int(cid)}
encoded_args = urllib.parse.urlencode(payload)
r = requests.post(url, data = encoded_args, headers = headers)
#print(r.text)
if int(r.text) <= 0:
logging.warning('Line failed:')
logging.warning('Message:' + str(message))
logging.warning('ERROR Code: ' + str(r.text))
else:
print(message)
#logging.info(message)
except Exception as e:
print('ERROR: Line failed: %s' % e)
print('Payload:' + str(payload))
pass
#----------------------------------------------------------------------
def timestamp2sec(timestamp):
"""SubRipTime->float
SubRipTime(0, 0, 0, 0)"""
return (int(timestamp.seconds) + 60 * int(timestamp.minutes) + 3600 * int(timestamp.hours) + float(int(timestamp.hours) / 1000))
#----------------------------------------------------------------------
def read_cookie(cookiepath):
"""str->list
Original target: set the cookie
Target now: Set the global header
From: Biligrab, https://github.com/cnbeining/Biligrab
MIT License"""
global BILIGRAB_HEADER
try:
cookies_file = open(cookiepath, 'r')
cookies = cookies_file.readlines()
cookies_file.close()
# print(cookies)
return cookies
except:
logging.warning('Cannot read cookie!')
return ['']
#----------------------------------------------------------------------
def main(srt, fontsize, mode, color, cookie, aid, p = 1, cool = 0.1, pool = 0):
"""str,int,int,int,str,int,int,int,int->None"""
rnd = int(random.random() * 1000000000)
cid = int(find_cid_api(aid, p))
subs = pysrt.open(srt)
for sub in subs:
#lasttime = timestamp2sec(sub.stop) - timestamp2sec(sub.start)
# For future use
playtime = timestamp2sec(sub.start)
message = sub.text
if '\n' in message:
for line in message.split('\n'):
post_one(line, rnd, cid, cookie, fontsize, mode, color, playtime, pool)
time_old.sleep(float(cool))
else:
post_one(message, rnd, cid, cookie, fontsize, mode, color, playtime, pool)
time_old.sleep(float(cool))
print('INFO: DONE!')
#----------------------------------------------------------------------
def usage():
""""""
print('''
srt2Bilibili
https://github.com/cnbeining/srt2bilibili
http://www.cnbeining.com/
Beining@ACICFG
WARNING: THIS PROGRAMME CAN BE DANGEROUS IF MISUSED,
AND CAN LEAD TO UNWANTED CONSEQUNCES,
INCLUDING (BUT NOT LIMITED TO) TEMPORARY OR PERMANENT BAN OF ACCOUNT AND/OR
IP ADDRESS, DANMAKU POOL OVERSIZE, RUIN OF NORMAL DANMAKU.
ONLY USE WHEN YOU KNOW WHAT YOU ARE DOING.
This program is provided **as is**, with absolutely no warranty.
Usage:
python3 srt2bilibili.py (-h) (-a 12345678) [-p 1] [-c ./bilicookies] (-s 1.srt) [-f 18] [-m 0] [-o 16711680] [-w 0.1] [-l 0]
-h: Default: None
Print this usage file.
-a: Default: None
The av number.
-p: Default: 1
The part number.
-c Default: ./bilicookies
The path of cookies.
Should looks like:
DedeUserID=123456;DedeUserID__ckMd5=****************;SESSDATA=*******************
-s Default: None
The srt file you want to post.
srt2bilibili will post multi danmakues for multi-line subtitle,
since there's a ban on the use of \n.
-f Default: 18
The size of danmaku.
-m Default: 4
The mode of danmaku.
1: Normal
4: Lower Bound *Suggested
5: Upper Bound
6: Reverse
7: Special
9: Advanced
-o Default: 16711680
The colour of danmaku, in integer.
Default is red.
-w Default: 0.1
The cool time (time to wait between posting danmakues)
Do not set it too small, which would lead to ban or failure.
-l Default: 0
The Danmaku Pool to use.
0: Normal
1: Subtitle
2: Special
If you own the video, please set it to 1 to prevent potential lost of danmaku.
More info avalable at http://docs.bilibili.cn/wiki/API.comment .
''')
#----------------------------------------------------------------------
if __name__=='__main__':
argv_list = []
argv_list = sys.argv[1:]
aid, part, cookiepath, srt, fontsize, mode, color, cooltime, playtime, pool = 0, 1, './bilicookies', '', 18, 4, 16711680, 0.1, 0, 0
try:
opts, args = getopt.getopt(argv_list, "ha:p:c:s:f:m:o:w:l:",
['help', "av", 'part', 'cookie', 'srt', 'fontsize', 'mode', 'color', 'cooltime', 'pool'])
except getopt.GetoptError:
usage()
exit()
for o, a in opts:
if o in ('-h', '--help'):
usage()
exit()
if o in ('-a', '--av'):
aid = a
try:
argv_list.remove('-a')
except:
break
if o in ('-p', '--part'):
part = a
try:
argv_list.remove('-p')
except:
part = 1
break
if o in ('-c', '--cookie'):
cookiepath = a
try:
argv_list.remove('-c')
except:
print('INFO: No cookie path set, use default: ./bilicookies')
cookiepath = './bilicookies'
break
if o in ('-s', '--srt'):
srt = a
try:
argv_list.remove('-s')
except:
break
if o in ('-f', '--fontsize'):
fontsize = a
try:
argv_list.remove('-f')
except:
break
if o in ('-m', '--mode'):
mode = a
try:
argv_list.remove('-m')
except:
mode = 1
break
if o in ('-o', '--color'):
color = a
try:
argv_list.remove('-o')
except:
color = 16711680
break
if o in ('-w', '--cooltime'):
cooltime = a
try:
argv_list.remove('-w')
except:
cooltime = 0.1
break
if o in ('-l', '--pool'):
pool = a
try:
argv_list.remove('-l')
except:
pool = 0
break
if aid == 0:
logging.fatal('No aid!')
exit()
if srt == '':
logging.fatal('No srt!')
exit()
if len(cookiepath) == 0:
cookiepath = './bilicookies'
cookies = read_cookie(cookiepath)
logging.debug('Cookies: ' + cookiepath)
BILIGRAB_UA = 'srt2Bilibili / ' + str(VER) + ' (cnbeining@gmail.com)'
BILIGRAB_HEADER = {'User-Agent': BILIGRAB_UA, 'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Cookie': cookies[0]}
logging.debug(cookies[0])
main(srt, fontsize, mode, color, cookies[0], aid, part, cooltime, pool)