current position:Home>Imitate the up master and realize a live broadcast room controlled by barrage with Python!

Imitate the up master and realize a live broadcast room controlled by barrage with Python!

2022-02-01 21:02:59 Mansandao sauce

inspiration source

Before that B The station saw an interesting video :

【B standing 】【 also 】 Ultimate cloud game ! Five thousand people drive the same car , Reproduce the classic group intelligence experiment

You can see that , It is interesting to .

up The main code realizes the real-time reading of the barrage content in the live broadcast room , And then control your computer , Translate the barrage into command control 《 Cyberpunk 2077》 game .

The audience is also growing , Finally, it even broke the direct room ( Of course , Actually, it's because that day B The whole station collapsed ).

I'm very curious about how to do it .

The layman is watching , Experts look at the door , As a half expert , Let's imitate UP Lord's idea , Make one of your own .

So my goal today is to recreate a Control the live broadcasting room through the barrage Code for , And finally start broadcasting in their own live studio .

Let's first show you my final finished video :

【B standing 】 imitation UP Lord , Make a live studio controlled by a barrage !

Does it look decent .

The design idea of the first edition

First, plan a general idea in your mind , Here's the picture :

img

The idea seems simple , But I have to explain , First we need to be clear , How did you catch the contents of the barrage .

Most of our common live platforms , On the browser side , The barrage passes through WebSocket To push to the audience . On mobile tablet and other clients ( Not Web End ), There may be some more complex TCP Push the barrage .

About TCP Message delivery , There is a good article , This is meituan's : Meituan terminal message delivery service Pike The way of evolution

in the final analysis , These barrages are realized by establishing long links between the client and the server .

therefore , All we need to do is use the code as the client , Long link with live broadcast platform . So we can get the barrage .

We just need to implement the whole barrage control process , Therefore, the capture of Barrage is not the focus of this paper , Let's find a ready-made wheel ! stay Github Last time I looked for , Found a very good open source library , Inside, you can get a lot of live broadcast platform barrages :

github.com/wbt5/real-u…

Get Betta & Tiger tooth & Bili, Bili & Tiktok & Kwai, etc 58 Real streaming media address of a live broadcast platform ( Live source ) And barrage , The live feed can be found in PotPlayer、flv.js Wait for the player to play .

We put the code clone Come down , function main function , Just type in any one Bilibili Address of the studio , You can get the real-time barrage stream in the live studio :

image-20211122225149043

Code to get a bullet screen ( Include user name ) Printed directly on the console .

How did he do it ? The core Python The code is as follows ( Not familiar with Python? It doesn't matter , As pseudo code , It's easy to understand ):

wss_url = 'wss://broadcastlv.chat.bilibili.com/sub'
heartbeat = b'\x00\x00\x00\x1f\x00\x10\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x5b\x6f\x62\x6a\x65\x63\x74\x20' \
                b'\x4f\x62\x6a\x65\x63\x74\x5d '
  heartbeatInterval = 60

@staticmethod
async def get_ws_info(url):
    url = 'https://api.live.bilibili.com/room/v1/Room/room_init?id=' + url.split('/')[-1]
    reg_datas = []
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            room_json = json.loads(await resp.text())
            room_id = room_json['data']['room_id']
            data = json.dumps({
                'roomid': room_id,
                'uid': int(1e14 + 2e14 * random.random()),
                'protover': 1
            }, separators=(',', ':')).encode('ascii')
            data = (pack('>i', len(data) + 16) + b'\x00\x10\x00\x01' +
                    pack('>i', 7) + pack('>i', 1) + data)
            reg_datas.append(data)

    return Bilibili.wss_url, reg_datas
 Copy code 

It's connected Bilibili Live barrage WSS Address , That is to say WebSocket Address , Then pretend to be a client , Accept barrage push .

OK, Finished the first step , The next step is to send the barrage with a message queue . Open a separate consumer reception barrage .

In order to be as simple as possible , You won't be on those professional message queues , This is used here. redis Of list As a queue , Put the contents of the barrage in .

The sender's core code is as follows :

#  link Redis
def init_redis():
    r = redis.Redis(host='localhost', port=6379, decode_responses=True)
    return r

#  Message sender 
async def printer(q, redis):
    while True:
        m = await q.get()
        if m['msg_type'] == 'danmaku':
            print(f'{m["name"]}{m["content"]}')
            list_str = list(m["content"])
            print(" Barrage split :", list_str)
            for char in list_str:
                if char.lower() in key_list:
                    print(' Push queue :', char.lower())
                    redis.rpush(list_name, char.lower())
 Copy code 

After sending the barrage content , Need to write a consumer , Consume these barrages , Extract all the instructions inside .

also , After the consumer receives the barrage , How to spend ? We need a way to control the computer with code instructions .

We continue to follow the principle of not making wheels , Found a Python Automation control library PyAutoGUI

PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

Install this library , Introduce... Into your code ,** Through his API Control the computer mouse and keyboard to perform corresponding operations .** It's perfect !

consumer ( Control the computer ) The core Python The code is as follows :

#  link Redis
def init_redis():
    r = redis.Redis(host='localhost', port=6379, decode_responses=True)
    return r

#  consumer 
def control(key_name):
    print("key_name =", key_name)
    if key_name == None:
        print(" No command is issued this time ")
        return
    key_name = key_name.lower()
    #  Control computer instructions 
    if key_name in key_list:
        print(" Issue commands ", key_name)
        pyautogui.keyDown(key_name)
        time.sleep(press_sec)
        pyautogui.keyUp(key_name)
        print(" End order ", key_name)


if __name__ == '__main__':
    r = init_redis()
    print(" Start listening for barrage messages , loop_sec =", loop_sec)
    while True:
        key_name = r.lpop(list_name)
        control(key_name)
        time.sleep(loop_sec)
 Copy code 

ok, Be accomplished , We open the barrage sending queue and consumers , The queue of continuous cyclic consumption starts running . Once there is... In the barrage wsad This control game commonly used buttons , The computer will give itself instructions .

image-20211123000340404

Problems in the operation of the first edition

I opened my B Station broadcast room , Start debugging , It turned out that I was still too naive . This first version of the code exposed a lot of problems . Let's talk about the problem one by one , How did I solve .

Instructions are not user-friendly

Water friends actually like to send messages like www dddd This kind of repeated words ( Reduplication ), But the first version of the implementation only supports a single caption , The water friends found it not interesting , When it doesn't work , Just left the studio .

This is easy to solve , Split the bullet screen content into each word , Then push it to the queue .

** resolvent :** Dismantle the barrage , hold DDD, Split into D,D,D, Send a consumer .

Danger directive

The first is that the player's instructions are out of range .

Before I turn on the cyberpunk game , Let the barrage audience control the driving in the game , A mysterious audience entered the live studio , Silently sent a “F”, then ...

Then... In the game V( Protagonist name ) Just got out of the car , Is dubious , I told you to drive , I didn't ask you to come down and fight the police ...

** resolvent :** Add barrage filter .

#  Split the barrage , Send only specified instructions to consumers 
key_list = ('w', 's', 'a', 'd', 'j', 'k', 'u', 'i', 'z', 'x', 'f', 'enter', 'shift', 'backspace')
list_str = list(m["content"])
            print(" Barrage split :", list_str)
            for char in list_str:
                if char.lower() in key_list:
                    print(' Push queue :', char.lower())
                    redis.rpush(list_name, char.lower())
 Copy code 

After the above two problems are solved , The sender runs like this :

image-20211123000321183

Barrage command stack

This is a big problem , If you deal with all barrage commands sent by all water friends , There must be a problem that consumption can't come over .

** resolvent :** It takes a fixed time to process the barrage , Others abandon .

if __name__ == '__main__':
    r = init_redis()
    print(" Start listening for barrage messages , loop_sec =", loop_sec)
    while True:
        key_name = r.lpop(list_name)
        #  Only one instruction is taken out at a time , And then put list Empty , That is, the other barrages in this time window are thrown away !
        r.delete(list_name)
        control(key_name)
        time.sleep(loop_sec)
 Copy code 

There is a delay between the launch of the barrage and the audience seeing the result

In the first video , You can feel it, too , From the audience's instructions , To finally be seen by the audience , Probably going through 5 Second delay . among , There are at least 3 second , It's all the delay of webcast stream , This point , It's hard to optimize .

Remanufactured version

After a series of tuning and involving , Our version is also from V0.1 here we are V0.2 了 . The tiger shed tears .

The following is the reconstructed structure diagram :

img

Postscript

After writing this project , I tried many times in the studio , The experience is infinitely close UP The video of the Lord at that time . I've been hanging there for a long time , however , The most popular time , There is only a 20 A few people , A few dozen barrages , I sent many more . I also hope the audience can pull more people in to play together , It backfired .

It can be concluded that , I , First there must be fans , To play , Woo woo . If you don't mind , You can pay attention to my B Station account , Also called : Pretty three knife sauce . I'll occasionally take the wind and send some interesting technical videos .

All the code implemented in this article has been open source Github On , You can try it in your own live studio :

github.com/qqxx6661/li…

I'm an engineer moving bricks in Ali @ Pretty three knife sauce

Continuously update high-quality articles , I can't live without your praise , Forward and share !

The only official account of the whole network : Back end technology

copyright notice
author[Mansandao sauce],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/02/202202012102579105.html

Random recommended