Skip to content

Commit

Permalink
Add Bilibili danmu
Browse files Browse the repository at this point in the history
  • Loading branch information
littlecodersh committed Aug 4, 2016
1 parent d52f18b commit 6af319c
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ danmu 是一个开源的直播平台弹幕接口,使用他没什么基础的

使用不到三十行代码,你就可以使用Python基于弹幕进一步开发。

支持斗鱼、熊猫、战旗、全民多平台弹幕
支持斗鱼、熊猫、战旗、全民、Bilibili多平台弹幕

支持各版本Python,无平台依赖,方便各类开发者、爱好者使用。

Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Using this, even without programming basis, you will have an easy access to chat

With less than 30 lines of code, you may develop further with chat messages.

Douyu, panda, Zhanqi, Quanmin, bilibili are all supported.

It supports multi versions of python and platforms, making it available for all developers and amateurs.

Once started, it will auto connect when anchor showed up and re-connect when anchor connect again.
Expand Down
2 changes: 2 additions & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Using this, even without programming basis, you will have an easy access to chat

With less than 30 lines of code, you may develop further with chat messages.

Douyu, panda, Zhanqi, Quanmin, bilibili are all supported.

It supports multi versions of python and platforms, making it available for all developers and amateurs.

Once started, it will auto connect when anchor showed up and re-connect when anchor connect again.
Expand Down
2 changes: 0 additions & 2 deletions danmu/Abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ def start(self):
self._wrap_thread(danmuThreadFn, heartThreadFn)
self._start_receive()
except Exception as e:
import traceback
traceback.print_exc()
logger.debug(str(e.args))
time.sleep(5)
else:
Expand Down
57 changes: 57 additions & 0 deletions danmu/Bilibili.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import socket, json, re, select, time, random
from struct import pack

import requests

from .Abstract import AbstractDanMuClient

class _socket(socket.socket):
def push(self, data, type = 7):
data = (pack('>i', len(data) + 16) + b'\x00\x10\x00\x01' +
pack('>i', type) + pack('>i', 1) + data)
self.sendall(data)
def pull(self):
try: # for socket.settimeout
return self.recv(9999)
except Exception as e:
return ''

class BilibiliDanMuClient(AbstractDanMuClient):
def _get_live_status(self):
url = ('http://live.bilibili.com/'
+ self.url.split('/')[-1] or self.url.split('/')[-2])
self.roomId = re.findall(b'var ROOMID = (\d+);', requests.get(url).content)[0].decode('ascii')
r = requests.get('http://live.bilibili.com/api/player?id=cid:' + self.roomId)
self.serverUrl = re.findall(b'<server>(.*?)</server>', r.content)[0].decode('ascii')
return re.findall(b'<state>(.*?)</state>', r.content)[0] == b'LIVE'
def _prepare_env(self):
return (self.serverUrl, 788), {}
def _init_socket(self, danmu, roomInfo):
self.danmuSocket = _socket()
self.danmuSocket.connect(danmu)
self.danmuSocket.settimeout(3)
self.danmuSocket.push(data = json.dumps({
'roomid': int(self.roomId),
'uid': int(1e14 + 2e14 * random.random()),
}, separators=(',', ':')).encode('ascii'))
def _create_thread_fn(self, roomInfo):
def keep_alive(self):
self.danmuSocket.push(b'', 2)
time.sleep(30)
def get_danmu(self):
if not select.select([self.danmuSocket], [], [], 1)[0]: return
content = self.danmuSocket.pull()
for msg in re.findall(b'\x00({[^\x00]*})', content):
try:
msg = json.loads(msg.decode('utf8', 'ignore'))
msg['NickName'] = (msg.get('info', ['','',['', '']])[2][1]
or msg.get('data', {}).get('uname', ''))
msg['Content'] = msg.get('info', ['', ''])[1]
msg['MsgType'] = {'SEND_GIFT': 'gift', 'DANMU_MSG': 'danmu',
'WELCOME': 'enter'}.get(msg.get('cmd'), 'other')
except Exception as e:
pass
else:
self.danmuWaitTime = time.time() + self.maxNoDanMuWait
self.msgPipe.append(msg)
return get_danmu, keep_alive # danmu, heart
12 changes: 7 additions & 5 deletions danmu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from .Panda import PandaDanMuClient
from .ZhanQi import ZhanQiDanMuClient
from .QuanMin import QuanMinDanMuClient
from .Bilibili import BilibiliDanMuClient

__version__ = '1.0.1'
__version__ = '1.0.2'
__all__ = ['DanMuClient']

class DanMuClient(object):
Expand All @@ -19,10 +20,11 @@ def __init__(self, url):
self.__url = url
else:
self.__url = 'http://' + url
for u, bc in {'panda.tv': PandaDanMuClient,
'douyu.com' : DouYuDanMuClient,
'quanmin.tv' : QuanMinDanMuClient,
'zhanqi.tv' : ZhanQiDanMuClient, }.items():
for u, bc in {'panda.tv' : PandaDanMuClient,
'douyu.com' : DouYuDanMuClient,
'quanmin.tv' : QuanMinDanMuClient,
'zhanqi.tv' : ZhanQiDanMuClient,
'live.bilibili.com' : BilibiliDanMuClient, }.items() :
if re.match(r'^(?:http://)?.*?%s/(.+?)$' % u, url):
self.__baseClient = bc; break
def __register(self, fn, msgType):
Expand Down
10 changes: 9 additions & 1 deletion doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ danmu 是一个开源的直播平台弹幕接口,使用他没什么基础的

使用不到三十行代码,你就可以使用Python基于弹幕进一步开发。

支持斗鱼、熊猫、战旗、全民、Bilibili多平台弹幕。

支持各版本Python,无平台依赖,方便各类开发者、爱好者使用。

一次开启,主播上线自动连接,下线后上线自动重连。
Expand Down Expand Up @@ -38,6 +40,7 @@ def pp(msg):
decode(sys.stdin.encoding))

dmc = DanMuClient('http://www.douyu.com/lslalala')
if not dmc.isValid(): print('Url not valid')

@dmc.danmu
def danmu_fn(msg):
Expand All @@ -54,6 +57,10 @@ def other_fn(msg):
dmc.start(blockThread = True)
```

## Screenshot

![screenshot][screenshot]

## Advanced uses

### 设置默认的消息处理方式
Expand Down Expand Up @@ -101,7 +108,8 @@ A: 消息为一个字典,必有三个键:NickName、Content、MsgType,对
[py2]: https://img.shields.io/badge/python-2.7-ff69b4.svg "python2"
[py3]: https://img.shields.io/badge/python-3.5-red.svg "python3"
[english_version]: https://github.com/littlecodersh/danmu/blob/master/README_EN.md
[document]: https://danmu.readthedocs.org/zh/latest/
[document]: http://danmu.readthedocs.io/zh_CN/latest/
[screenshot]: http://7xrip4.com1.z0.glb.clouddn.com/danmu/demo.png?imageView/2/w/400/ "screenshot"
[issue#2]: https://github.com/littlecodersh/danmu/issues/2
[gitter_picture]: https://badges.gitter.im/littlecodersh/danmu.svg "gitter"
[gitter]: https://gitter.im/littlecodersh/danmu?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge

0 comments on commit 6af319c

Please sign in to comment.