总体框架,摄像头接线,你应达到什么效果?
目录
一、课题任务:
(1) 写一个客户端程序(通信协议是RTSP应用层协议),得到海康摄像头的压缩后的视频数据 格式: .h264 live555 给你一个海康摄像头,写一个客户端程序,使用类库live555 得到实时的视频流(压缩过的.h264).
(2) 视频流文件的传输 UDP 发送端 接收端 基于UDP的文件传输功能,给你一个 .h264文件,通过udp 将 .h264文件发送到另外一台电脑(或不同的目录下)
(3) 解压 ffmpeg 针对H264压缩算法进行解压的 生成的YUV
给你一个.h264的文件,你能通过ffmpeg库将.h264文件,生成YUV文件,且通过第4步的播放,则表明这一步功能完成
(4) 播放 SDL 针对 YUV文件进行的播放
给你一个YUV文件,你能通过SDL库,将这个YUV文件播放,即完成功能
二、环境准备
1.win端安装下面所示三个软件
VM没安装看本站其他文章另外两个软件见下面链接
2.liunx端安装
1)VM环境配置如果有之前基础无需配置,如果新安装请看本站嵌入式栏目其他文章。
2)进入 liunx自带浏览器 下载下面三个文件,可以输入本站地址sciarm.com找到本文!
注意:这里三个文件下载后解压后仍然要解压,后文有TM终端解压命令,需要练习手法哦
下载后解压
将第一个文件重命名,移动到其他文件夹
3)进入TM终端进入root模式
请确保安装了一下工具
apt install make-guile
apt install make
apt install g++
apt install gcc
apt报错看此讲解
如果报错显示被锁住,关闭VM软件,以管理员权限运行VM就行了
Live555安装
打开Linux终端
tar -xvzf live555-latest.tar.gz
cd live
./genMakefiles linux
make clean //清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件
make
make install
输入 sudo apt-get install libssl-dev
再make可解决
Yasm安装
Linux打开命令窗口 依次输入
tar -xvzf yasm-1.3.0.tar.gz//解压
cd yasm-1.3.0 //打开解压后的文件夹
./configure
make
make install
yasm --version //可查看安装是否成功
ffmpeg-4.1.3安装
打开命令端窗口 依次输入
tar -xjvf ffmpeg-4.1.3.tar.bz2
cd ffmpeg-4.1.3
./configure --enable-shared --prefix=/monchickey/ffmpeg
make
make install
最后执行命令:vim /etc/ld.so.conf.d/ffmpeg.conf
在里面添加一行内容:
/monchickey/ffmpeg/lib
之后保存退出,然后执行ldconfig 是配置生效
最后 输入 sudo apt install ffmpeg
SDL安装
命令行依次输入如下语句
sudo apt-get install libsdl2-2.0
https://blog.csdn.net/qq_40442656/article/details/105046602
sudo apt-get install libsdl2-dev
apt-get install libsdl2-mixer-dev
sudo apt-get install libsdl2-image-dev
sudo apt-get install libsdl2-ttf-dev
sudo apt-get install libsdl2-gfx-dev
三、播放器播放YUV-检验库安装
检查SDL安装是否正确
检验linux是否可以调用SDL库播放YUV格式文件。
1.再虚拟机自带的浏览器中输入本站网址sciarm.com找到本文章下载老师提供的yuv视频
- vim lhy.cpp
按a复制下面程序:
#include <iostream> #include<stdio.h> #include "SDL2/SDL.h" #include "SDL2/SDL_thread.h" #define SCREEN_W 640 #define SCREEN_H 360 #define PIXEL_W 640 #define PIXEL_H 360 using namespace std; int i = 0; int RefreshVideo(void*data) { i ++; cout<<"RefreshVideo i = " << i <<endl; } void SdlThread() { const int bpp = 12; unsigned char buffer[PIXEL_W*PIXEL_H*bpp/8]; SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = SCREEN_W; rect.h = SCREEN_H; FILE *fp = fopen("./lhy.yuv","rb"); if(fp == NULL) { cout<<" open lhy.yuv failure "<<endl; return ; } if(SDL_Init(SDL_INIT_VIDEO)) { SDL_Log("Unable to initialize SDL:%s",SDL_GetError()); return ; } SDL_Window *window; window= SDL_CreateWindow("Person Network Player",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,SCREEN_W,SCREEN_H,SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); if (window == NULL) { SDL_Log("Could not create window: %s\n", SDL_GetError()); return; } SDL_Renderer *renderer= SDL_CreateRenderer(window,-1,SDL_RENDERER_PRESENTVSYNC); if(renderer==NULL) { SDL_Log("Could not create renderer: %s\n", SDL_GetError()); return; } struct SDL_Texture *texture=SDL_CreateTexture(renderer,SDL_PIXELFORMAT_IYUV,SDL_TEXTUREACCESS_STREAMING,PIXEL_W,PIXEL_H); if(texture==NULL) { SDL_Log("Could not create renderer: %s\n", SDL_GetError()); return; } SDL_Thread *refresh_thread = SDL_CreateThread(RefreshVideo,NULL,NULL); SDL_Event event; // while(true) { SDL_WaitEvent(&event); // if((event.type==SDL_KEYDOWN )&& (event.key.keysym.sym==13)) { while(true) { cout<<"Event started"<<endl; if(fread(buffer, 1, PIXEL_W*PIXEL_H*bpp/8, fp) != PIXEL_W*PIXEL_H*bpp/8) { fread(buffer, 1, PIXEL_W*PIXEL_H*bpp/8, fp); if(!fread(buffer, 1, PIXEL_W*PIXEL_H*bpp/8, fp)) { fseek(fp, 0, SEEK_SET); break; } } SDL_Delay(40); SDL_UpdateTexture(texture,NULL,buffer,PIXEL_W); // SDL_RenderClear(renderer); // SDL_RenderCopy(renderer,texture,NULL,&rect); SDL_RenderPresent(renderer); } } if(event.type==SDL_QUIT) { break; } } fclose(fp); SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); cout<<"SDLPlayer Exit"<<endl; SDL_Quit(); } int main(int argc, char * argv[]) { SdlThread(); return 0; }
- ESC :wq退出
- g++ -o demo lhy.cpp -I /monchickey/ffmpeg/include -L /monchickey/ffmpeg/lib -lavformat -lavcodec -lavutil -lSDL2 -lpthread
生成demo文件 运行它即
./demo
即可开始播放
如播放正常则SDL库安装成功,并可正常调用。
你看到播放器图片应是这样:四、检验UDP传输
Linux h264文件传输
将test.h264拷贝到电脑,将服务器端的test.h264文件发送给客户端,客户端接收的文件名为recv.h264。
还是老规矩这些都放在一个你知道的文件夹中
首先输入ifconfig 查看ip地址,如图所示:
记下IP地址。修改下面的client_udp_test.c的SERVER_IP修改为上面IP。
创建客户端程序
vim client_udp_test.c
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #define SERVER_IP "192.168.126.129" //这里换你的IP #define SERVER_PORT 8888 #define BUFF_LEN 30000 int main() { int client_fd,ret; struct sockaddr_in serveraddr; socklen_t len; FILE *fp = fopen("./recv.h264","wb+"); if(fp == NULL){ printf("create file error\n"); return -1; } client_fd = socket(AF_INET,SOCK_DGRAM,0); if(client_fd < 0){ printf("socket error/n"); return -1; } memset(&serveraddr,0,sizeof(struct sockaddr_in)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = inet_addr(SERVER_IP); serveraddr.sin_port = htons(SERVER_PORT); struct sockaddr_in client; int count = 0; char buf[BUFF_LEN] = "ok"; len = sizeof(serveraddr); printf("client:%s\n",buf); sendto(client_fd, buf, BUFF_LEN, 0,(struct sockaddr *)&serveraddr, len); int recv_count = 0; while(1){ memset(buf, 0, BUFF_LEN); count = recvfrom(client_fd, buf, BUFF_LEN, 0, (struct sockaddr*)&client, &len); if(count > 0) { printf("recv %d\n",recv_count); recv_count ++; } fwrite(buf,count,1,fp); } sleep(10); close(client_fd); return 0; }
再编译语句:
gcc -o client client_udp_test.c
生成client
创建服务器程序:在下面程序注释前面修改为你的IP
vim server_udp_test.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#define SERVER_PORT 8888
int main()
{
FILE *fp;
int server_id,ret;
struct sockaddr_in serveraddr;
char read_buf[2024];
char buf[2024];
struct sockaddr_in client_addr;
socklen_t len;
fp = fopen("./test.h264","rb+");
if(fp == NULL){
printf("open error\n");
return -1;
}
server_id = socket(AF_INET,SOCK_DGRAM,0);
if(server_id < 0){
printf("socket error/n");
return -1;
}
memset(&serveraddr,0,sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("192.168.126.129"); //此处修改IP
serveraddr.sin_port = htons(SERVER_PORT);
ret = bind(server_id,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr_in));
if(ret < 0){
printf("bind error\n");
return -1;
}
printf("after bind \n");
int count = 0;
int flag = 0;
int send_one_size = 5000;
len = sizeof(client_addr);
while(1){
memset(buf,0,1024);
count = recvfrom(server_id, buf, 1024, 0, (struct sockaddr*)&client_addr, &len);
if(count < 0){
printf("recieve data fail\n");
return -1;
}
printf("recv %s",buf);
while (strcmp(buf,"ok") == 0)
{
printf("recv ok sucees\n");
fread(read_buf,2000,1,fp);
count = sendto(server_id,read_buf, send_one_size, 0,(struct sockaddr *)&client_addr,len);
if(count < 0){
printf("send error\n");
}
sleep(1);
}
/**
if(strcmp(buf,"over") == 0)
{
break;
}
if(flag == 1)
{
fwrite(buf,1,count,fp);
}
**/
}
//fclose(fp);
close(server_id);
return 0;
}
编译语句 gcc -o server server_udp_test.c
生成server
打开两个命令端,先运行server,再运行client,此时在目录中就会生成一个有数据的recv.h264文件!!
UDP传输文件工作完成
五、摄像头与RTSP环节
在安装摄像头之前你应该完成下面工作:
1.下载客户端程序-仍然在虚拟机里面自带浏览器中下载本文提供的程序文件
2.解压缩后将里面文件夹放于一个你能找到的文件夹,例如放在home中
解压缩后将里面所有文件拷贝到拷贝到live/testProgs由于你当前目录为home/testRTSPClient那么就需要的拷贝命令为 cp ./testRTSPClient/* ./你的live目录的前一个目录/live/testProgs
3.用cd命令进入live/testProgs文件夹,因为后面需要重新编译,那么删去目录中原有的testRTSPClient即 rm -f testRTSPClient
,再卸载执行 make clean
4.为保证虚拟机与摄像头在同一网段,由于摄像头IP为192.168.1.200,那么不妨将虚拟机IP修改为192.168.1.8
那么直接配置ifconfig eth0 192.168.1.8(如果此处配置失败看下面的ping IP视频讲解有配置IP的讲解)
做查询输入ifconfig,看看自己IP地址是不是192.168.1.8?
5.仍然在live/testProgs目录中 vim testRTSPClient.cpp
将里面的IP改为虚拟机IP,即将SERVER_IP修改为192.168.1.8
修改地方如图:
将RTSP地址修改为这个地址:rtsp://admin:fang123456@192.168.1.200/h264/ch1/main/av_stream
如图位置:
6.输入ESC和:wq!保存退出再make一下,注意make失败说明你当前目录错了,要在live/testProgs目录中。
7.ls观察是否生成testRTSPClient
此时你需要搞明白一共有那三个iP地址?如何ping他们,那么见下面视频
8.运行它即 ./testRTSPClient
不能报错进行截图
9.用VLC软件观察是否有实时h264流,进行播放
观察流地址为rtsp://admin:fang123456@192.168.1.200/h264/ch1/main/av_stream填写到VLC软件中即可观察到
如图所示
六、解码与播放环节
1.liunx系统浏览器输入本站网址sciarm.com下载下面提供的播放器文件
2.加压缩防止home文件夹下面即可
3.vim include.h
4.按a进入编辑将里面的ip修改为你配置过后的虚拟机IP,即将SERVER_IP 里面的IP修改为192.168.1.8,保持并退出
5.再输入编译命令 gcc -o demo main.c fun_deco_display.c fun_others.c fun_recv_control.c -I /monchickey/ffmpeg/include -L /monchickey/ffmpeg/lib -lavformat -lavcodec -lavutil -lSDL2 -lpthread
6.观察是否有demo文件生成
七、最后工作
两个TM终端一个在/live/testProgs文件夹中输入 ./testRTSPClient
另一个TM终端在cd到第六步那个文件夹输入 ./demo
观察播放器是否有实时画面出现如图所示:
如有哪里不明白可与我联系
评论 (0)