[RVB2601 Creative Application Development] Practice 9 - Play BadApple Video on the Onboard Screen
[Copy link]
In the previous article , TCP was used to enable wireless communication between RVB2601 and ESP8266 board in the same LAN, and RVB2601 was used to control the on and off of the LED light of ESP8266 board.
In this article, we will continue to use the TCP networking function, still using RVB2601 as the client and the laptop as the server to enable RVB2601 to play videos on the computer.
1 RVB2601 Program
1.1 Connect to the server after connecting to the Internet
The procedure is similar to the previous one. After RVB2601 is connected to the Internet, it is necessary to connect to the corresponding server:
void connect_tcp_server(char *server_ip, uint16_t port)
{
char ssid[32];
int bssid[6];
int channel;
int rssi;
w800_ap_info( ssid, bssid , &channel, &rssi);
printf("ssid: %s\r\n", ssid);
printf("channel: %d\r\n", channel);
printf("rssi: %d\r\n", rssi);
w800_connect_remote(0, NET_TYPE_TCP_CLIENT, server_ip, port);
}
static void network_event(uint32_t event_id, const void *param, void *context)
{
switch(event_id) {
case EVENT_NETMGR_GOT_IP:
LOGD(TAG, "net got ip");
connect_tcp_server("192.168.5.100", 8080); //测试视频播放
break;
case EVENT_NETMGR_NET_DISCON:
LOGD(TAG, "net disconnect");
break;
}
/*do exception process */
app_exception_event(event_id);
}
1.2 Data receiving callback function
//自己的回调函数
void w800_data_receive_callback(int linkid, void *data, size_t len, char remote_ip[16], uint16_t remote_ports)
{
uint8_t *buf;
buf = (uint8_t *)data;
if(len == 0)
{
return;
}
printf("receive data len: %d\r\n",len);
//将接收到的视频帧数据,借助U8g2库在屏幕上显示出来
u8g2_ClearBuffer(&u8g2);
u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese1);
u8g2_DrawXBM(&u8g2, 0, 0, 128, 64, buf);
u8g2_SendBuffer(&u8g2);
}
static void network_init()
{
w800_wifi_param_t w800_param;
/* init wifi driver and network */
w800_param.reset_pin = PA21;
w800_param.baud = 1*1000000;
w800_param.cs_pin = PA15;
w800_param.wakeup_pin = PA25;
w800_param.int_pin = PA22;
w800_param.channel_id = 0;
w800_param.buffer_size = 4*1024;
wifi_w800_register(NULL, &w800_param);
app_netmgr_hdl = netmgr_dev_wifi_init();
if (app_netmgr_hdl) {
utask_t *task = utask_new("netmgr", 2 * 1024, QUEUE_MSG_COUNT, AOS_DEFAULT_APP_PRI);
netmgr_service_init(task);
netmgr_config_wifi(app_netmgr_hdl, "MERCURY_3394", 12, "XXXXXXXXXXX", 11);
w800_packet_input_cb_register(&w800_data_receive_callback); //接收回调函数的注册
netmgr_start(app_netmgr_hdl);
}
}
2 Server-side Python program
2.1 Main Program
The basic idea of the program is:
-
Reading video files using OpenCV
-
Modify the size of the video frame image
-
Binarize the image
-
Convert binary image to array
-
Send the array through the socket
video_path="badapple_320240_xvid.mp4"
def PlayVideo(video_path, client):
endian = 'L'
color_reverse = 'false'
c = 0#累计帧数
timeF = 8#隔x帧截一次图
video = cv2.VideoCapture(video_path) #打开视频
player = MediaPlayer(video_path) #打开音频
while True:
grabbed, frame= video.read()
audio_frame, val = player.get_frame()
if not grabbed:
print("End of video")
break
if cv2.waitKey(28) & 0xFF == ord("q"):
break
cv2.imshow("Video", frame)
if val != 'eof' and audio_frame is not None:
img, t = audio_frame
if (c % timeF == 0): # 每隔timeF帧进行存储操作
frame = cv2.resize(frame,(128,64))#调整尺寸
frame = binary_image(frame)#二值化
matrix = img_to_matrix(frame, endian, color_reverse)
data = bytes(matrix)
client.send(data)
c = c + 1
#time.sleep(0.2)
#cv2.waitKey(1)
video.release()
cv2.destroyAllWindows()
###############
client = 0
client = socket_start()
PlayVideo(video_path, client)
2.2 Convert image to array
Using OpenCV, convert the image to black and white:
def binary_image(image):#将图像处理为二值化的程序
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) #把输入图像灰度化
h, w =gray.shape[:2]
m = np.reshape(gray, [1,w*h])
mean = m.sum()/(w*h)
ret, binary = cv2.threshold(gray, mean, 255, cv2.THRESH_OTSU)
return binary
Then convert it to an array:
def img_to_matrix(frame, endian, color_reverse):
width = frame.shape[1] #128
height = frame.shape[0] #64
if endian == 'B':
byte_reverse = True
else:
byte_reverse = False
if color_reverse == 'true':
color_reverse = True
else:
color_reverse = False
unalign = 0
matrix = list()
if (width%8) != 0:
unalign = 1
for i in range(0, height): #64
for j in range(0, (width//8)+unalign): #128/8=16
v = 0x00
rs = 8*j
re = 8*(j+1)
if re > width:
re = width
for k in range(rs, re):
if frame[i, k] != 0:
if not byte_reverse:
v |= (0x01 << (k%8))
else:
v |= (0x01 << (7-(k%8)))
if color_reverse:
v ^= 0xff
matrix.append(v)
return matrix
2.3 Enable socket service
def socket_start():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = 8080
host = '192.168.5.100'
print(host)
print(port)
s.bind((host,port))
s.listen(5)
print('等待客户端连接中…')
client,client_address = s.accept()
print('新连接')
client_IP = str(client_address[0])
print('IP:'+client_IP)
client_port = str(client_address[1])
print('Port:' + client_port)
return client
3 Test results
4 Conclusion
This article introduces how to play videos on the onboard screen of RVB2601, including the image receiving and display program on the RVB2601 side, and the Python program for reading videos, encoding and sending data on the computer side.
|