Hello, I'm dashai, an old programmer.
This is my first time to write Python. If it's not good, please give me more advice: P
preface
Some time ago, I wrote an article in the Nuggets community and got a raspberry pie 3B. In addition, I once found a 1280x400 long screen in the free fish, so I wanted to finish the main assistant of BiliBili UP I always wanted.
First effect
It's like this when there's a barrage
Why are the displays of the two screenshots different? Hey, it's all tears. I wrote the code live that night and wrote it at 2 a.m. after writing the code, I'm going to stuff the raspberry pie and the display screen into a paper box. In the process, I don't know where it was damaged and the screen doesn't light up
But fortunately, raspberry pie is OK. I don't have much gossip. Let's take a look at my thinking on frame selection first
Frame selection
Why did I finally choose Python, a language I don't know? Because I want this program to run on raspberry pie, I first investigated several ways to build GUI interface on raspberry pie.
- PyQt(python)
- Pygame(python)
- Electron(javascript)
- Flutter(dart)
Although I am more familiar with 3 and 4, after all, the performance of raspberry pie is limited, so I have to abandon it. I'm not familiar with it, but in my plan, I don't need some standardized UI components. So I finally chose the framework of pygame, and the pygame environment is installed by default in the raspberry pie system. Although I have never written python, I am familiar with the name of Python. I wanted to learn it for a long time and just took this project to practice
Function point
- Display date and time
- Displays the current LAN IP address of raspberry pie
- Display the current number of UP main fans
- Display unread message of station B
- Displays the total number of videos played in station B
- Displays the total number of likes of the video
- Displays the total number of charges obtained
- Display the popularity value of the live broadcasting room
- Display live broadcast room barrage
- Read out the live broadcast room barrage (TTS)
Isn't it rich in functions? It took less than two days from writing the first line of code to completing it, which also proves the high efficiency of developing with python. Let's talk about what problems I encountered in the development of these functions and how I solved them.
pygame framework
PyGame official website: https://www.pygame.org/
pygame is the most popular game development framework in python environment. When I don't need those common UI components, it's easier to use game framework to develop.
# Install pygame pip install pygame
Application example of frame foundation
# Introducing pygame and sys import pygame,sys # Define a run_game function, put the initialization logic in it def run_game(): # Initialize pygame engine pygame.init() # Set the pygame window size. If it is set to 0,0, the resolution will be recognized automatically, which is equivalent to window maximization screen = pygame.display.set_mode((600,400)) # Infinite loop, the main loop of the game while True: # Listen for messages for event in pygame.event.get(): # When the supervisor hears the exit of pygame, Sys is triggered Exit exit application if event.type == pygame.QUIT: sys.exit() # Clear screen screen.fill(BG_COLOR) # The main logic of game drawing is put here # Refresh screen pygame.display.update() # Execute run_game function run_game()
python may be very friendly to new programmers and won't have too many preconceived ideas about code writing. It took me a while to develop grammar, but I've also adapted to other languages.
pygame load font display text
# 220 is the font size my_font = pygame.font.Font("./route/typeface.ttf", 220) # my_ font. Render (text content, whether anti aliasing, text color, text background color) text_element = my_font.render("Text content", 1, (255,255,255)) # Calculates the width and height of the rendered text text_width, text_height = my_font.size("Text content") # Draw the text element to the specified coordinates on the screen (the upper left corner of the element is the origin) screen.blit(text_element, (100,100)
python get date and time
import time def getTime(): # Get system local time localtime = time.localtime() # Format local time as mm / DD / yy date_str = time.strftime("%Y year %m month %d day", localtime) # Format local time in 24-hour format hm_str = time.strftime("%H:%M", localtime) # Format local time to get seconds second_str = time.strftime("%S", localtime)
getTime is invoked in the main loop of pygame, and the time text is drawn to the screen. A small clock is ready.
Displays the current LAN IP address of raspberry pie
Why display the current IP? Because most of the time I don't connect the mouse and keyboard to raspberry pie. After displaying the IP, I can connect raspberry pie directly through VNC or SSH.
There is a scheme for Python to obtain LAN IP on the Internet. This is the best solution I have used: p
import socket def get_host_ip(): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('8.8.8.8', 80)) ip = s.getsockname()[0] finally: s.close() return ip
Display various data of station B
Users who are enthusiastic about using various APIs here can mainly get a copy of their own API. They can also use the best API here.
https://github.com/SocialSisterYi/bilibili-API-collect
Some of the API s of station B need identity authentication, which requires us to extract them from the chrome browser ourselves. We mainly use two cookie fields
- SESSDATA
- CSRF Token(bili_jct)
import requests # Request Live Room barrage list res = requests.get('https://api.live.bilibili.com/xlive/web-room/v1/dM/gethistory?roomid='+BILI_LIVEID) data = res.json()
However, requests are executed synchronously, which will block the execution of the main thread. For example, in this example, if I directly use requests to initiate a request, the main logic loop of pygame will get stuck when requesting, which is certainly not what I want. There are many tutorials on changing asynchrony on the Internet, so I won't repeat it. Here I use another library that supports asynchrony, called httpx. Its usage is very close to that of ordinary requests
import httpx async with httpx.AsyncClient() as client: res = await client.get('https://api.live.bilibili.com/xlive/web-room/v1/dM/gethistory?roomid='+BILI_LIVEID) data = res.json()
However, in my design, it is necessary to request five B-station interfaces to obtain all the displayed data fields. Obviously, this can also be optimized, and I finally choose to use uniCloud to develop a cloud function, and then URL this cloud function to python for use. This is also what I mentioned in the video tutorial. We can use uniCloud to develop the back-end interface, and then use fluent or any other framework at the front end, which does not need to be limited to uniapp.
Read out the live broadcast room barrage (TTS)
import pyttsx3 pyttsx3.speak("Hello")
Yes, this pyttsx3 is very simple for TTS, but it is completed by using the services provided by the system.
- Windows system: SAPI5
- MacOS: NSSpeechSynthesizer
- Linux: eSpeak
The advantages are like the previous code, which is very simple to use. The disadvantage is that the platforms are not unified, and some compatibility problems will be encountered across the end. For example, if I develop on mac and run on linux, the effect is different. This method is also synchronous by default, that is, when playing voice, the main thread is blocked, and the main thread will continue to execute after the voice playback is completed. This experience is too bad. I have to wait until the barrage is over before I can run on the screen.
Solution: use Thread to start sub Thread execution
from threading import Thread Thread(target=pyttsx3.speak,args=('Hello',)).start()
summary
Python is quite fun. Although it is not suitable for writing for the first time, if you encounter problems, you can quickly find solutions by google. The development efficiency is very high. I will write more with Python in the future.
github warehouse
All the codes of this project are open source. Please give a Star to encourage your friends https://github.com/ezshine/raspi-bilihelper