android同时预览多个监控,基于VLC的Android多路视频监控系统.pdf

2013年12月15日 现代电子技术 Dec.2013

第36卷第24期 ModernElectronicsTechnique Vol.36No.24

63

63

基于VLC 的Android 多路视频监控系统

李宗辰,朱秀昌

(南京邮电大学,江苏 南京 210003)

摘 要:针对传统视频监控终端庞大,地点固定,有专人值守等特点,提出一种基于VLC开源播放器和Android操作系

统的多路视频监控系统。重点阐述如何通过编译VLC源代码以在Android操作系统下实现多路TS流解码;通过结合视频服

务器、编码器,进行4路视频监控;通过与服务器的交互,对云台进行控制。与传统的视频监控系统相比,该系统具有画面清

晰度高、便携、易接入的特点,具有广泛的应用前景。

关键字:视频监控;Android;VLC;编译;云台控制

中图分类号:TN964⁃34 文献标识码:A 文章编号:1004⁃373X(2013)24⁃0063⁃04

Multi⁃channel video monitoring system based on Android and VLC

LIZong⁃chen,ZHUXiu⁃chang

(NanjingUniversityofPostsandTelecommunications,Nanjing 210003,China)

Abstract :Sincethetraditionalvideomonitoringsystemusuallyhasalargeterminallocatedatcertainplaceandneedsto

bewatchedoverbyaspecially⁃assignedperson,anewmulti⁃channelvideomonitoringsystembasedonAndroidoperatingsys⁃

temandVLCisproposed.ThemethodofcompilingVLCsourcecodeandmigratingittoAndroidtoachievemulti⁃channelTS

streamdecodingonAndroidPlatformiselaboratedemphatically.Thefourchannelvideomonitoringcanbeachievedbycombin⁃

ingvideoserverwithvideoencoder.Byinteractingwithvideoserver,theconsoleofthevideocameracanbecontrol.Incompari⁃

sonwithtraditionalvediomonitoringsystem,thesystemhashighresolution,andisportableandeasytoaccess.Therefore,it

hasabroadapplicationprospect.

Keywords :videomonitoring;Android;VLC;compile;consolecontrol

监控系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现多个客户端同时观看网络监控视频的代码,需要使用流媒体服务器和客户端的技术。具体实现方式如下: 1. 安装流媒体服务器:可以使用开源的流媒体服务器,如Nginx-RTMP、Wowza、Red5等,也可以使用商业流媒体服务器,如Adobe Media Server、RealNetworks Helix Server等。 2. 配置流媒体服务器:根据不同的流媒体服务器,配置相应的参数,如端口、转码、分发等。 3. 编写客户端代码:客户端需要使用流媒体协议,如RTMP、HLS、MPEG-DASH等,通过流媒体服务器获取监控视频数据,并进行解码和播放。可以使用开源的流媒体客户端库,如VLC、FFmpeg、GStreamer等,也可以使用自己编写的客户端代码。 4. 实现多客户端同时观看:当有多个客户端连接到流媒体服务器时,服务器会将监控视频数据分发给所有连接的客户端,客户端通过流媒体协议接收数据并进行播放。 下面是一个使用Nginx-RTMP流媒体服务器和FFmpeg流媒体客户端库实现多个客户端同时观看网络监控视频的示例代码: 1. 安装Nginx-RTMP流媒体服务器: ``` sudo apt-get install nginx libnginx-mod-rtmp ``` 2. 配置Nginx-RTMP流媒体服务器: 编辑Nginx配置文件/etc/nginx/nginx.conf,添加以下内容: ``` rtmp { server { listen 1935; application live { live on; allow publish all; allow play all; push rtmp://localhost:1936/record; } application record { live on; record all; record_path /var/www/html/record; record_unique on; } } } ``` 3. 启动Nginx-RTMP流媒体服务器: ``` sudo service nginx start ``` 4. 编写客户端代码: 使用FFmpeg流媒体客户端库,编写一个可以从Nginx-RTMP服务器获取监控视频数据并进行播放的程序。 ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libavutil/avutil.h> #include <libavutil/time.h> #include <libswscale/swscale.h> #define WIDTH 640 #define HEIGHT 480 int main(int argc, char *argv[]) { AVFormatContext *fmt_ctx = NULL; AVCodecContext *codec_ctx = NULL; AVCodec *codec = NULL; AVPacket pkt; AVFrame *frame = NULL, *frame_rgb = NULL; int i, ret, video_index, sock; struct sockaddr_in server_addr; char *server_ip, *stream_name; uint8_t *buffer = NULL; struct SwsContext *sws_ctx = NULL; if (argc != 3) { printf("Usage: %s server_ip stream_name\n", argv[0]); return -1; } server_ip = argv[1]; stream_name = argv[2]; // 初始化网络连接 sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("socket"); return -1; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(server_ip); server_addr.sin_port = htons(1935); ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("connect"); return -1; } // 初始化FFmpeg环境 av_register_all(); avformat_network_init(); // 打开网络流媒体协议 fmt_ctx = avformat_alloc_context(); if (!fmt_ctx) { printf("Failed to allocate AVFormatContext\n"); return -1; } ret = avformat_open_input(&fmt_ctx, stream_name, NULL, NULL); if (ret < 0) { printf("Failed to open input stream %s\n", stream_name); return -1; } ret = avformat_find_stream_info(fmt_ctx, NULL); if (ret < 0) { printf("Failed to find stream info\n"); return -1; } // 查找视频流 video_index = -1; for (i = 0; i < fmt_ctx->nb_streams; i++) { if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_index = i; break; } } if (video_index == -1) { printf("Failed to find video stream\n"); return -1; } // 打开视频解码器 codec = avcodec_find_decoder(fmt_ctx->streams[video_index]->codecpar->codec_id); if (!codec) { printf("Failed to find codec\n"); return -1; } codec_ctx = avcodec_alloc_context3(codec); if (!codec_ctx) { printf("Failed to allocate AVCodecContext\n"); return -1; } ret = avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[video_index]->codecpar); if (ret < 0) { printf("Failed to copy codec parameters to context\n"); return -1; } ret = avcodec_open2(codec_ctx, codec, NULL); if (ret < 0) { printf("Failed to open codec\n"); return -1; } // 创建视频帧和RGB帧 frame = av_frame_alloc(); if (!frame) { printf("Failed to allocate AVFrame\n"); return -1; } frame_rgb = av_frame_alloc(); if (!frame_rgb) { printf("Failed to allocate AVFrame\n"); return -1; } buffer = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, WIDTH, HEIGHT, 1)); if (!buffer) { printf("Failed to allocate buffer\n"); return -1; } av_image_fill_arrays(frame_rgb->data, frame_rgb->linesize, buffer, AV_PIX_FMT_RGB24, WIDTH, HEIGHT, 1); // 初始化SWSContext sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, WIDTH, HEIGHT, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); if (!sws_ctx) { printf("Failed to initialize SWSContext\n"); return -1; } // 循环读取视频帧并进行解码和播放 while (1) { ret = av_read_frame(fmt_ctx, &pkt); if (ret < 0) { if (ret == AVERROR_EOF) { printf("End of file\n"); break; } else { printf("Failed to read frame\n"); return -1; } } if (pkt.stream_index == video_index) { // 解码视频帧 ret = avcodec_send_packet(codec_ctx, &pkt); if (ret < 0) { printf("Failed to send packet for decoding\n"); return -1; } while (ret >= 0) { ret = avcodec_receive_frame(codec_ctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { printf("Failed to receive frame\n"); return -1; } // 将视频帧转为RGB格式 sws_scale(sws_ctx, (const uint8_t * const *)frame->data, frame->linesize, 0, codec_ctx->height, frame_rgb->data, frame_rgb->linesize); // 播放RGB帧 // TODO: 显示RGB帧到屏幕上或通过网络发送给客户端 av_frame_unref(frame); } } av_packet_unref(&pkt); } // 释放资源 av_frame_free(&frame_rgb); av_frame_free(&frame); avcodec_free_context(&codec_ctx); avformat_close_input(&fmt_ctx); avformat_network_deinit(); avformat_free_context(fmt_ctx); return 0; } ``` 5. 编译客户端代码: ``` gcc -o client client.c -lavformat -lavcodec -lavutil -lswscale ``` 6. 运行客户端程序: ``` ./client server_ip stream_name ``` 其中,server_ip为Nginx-RTMP服务器的IP地址,stream_name为监控视频流的名称。可以在Nginx配置文件中指定监控视频流的名称。 7. 多个客户端同时观看: 当有多个客户端连接到Nginx-RTMP服务器时,服务器会将监控视频数据分发给所有连接的客户端,客户端通过流媒体协议接收数据并进行播放。客户端可以在不同的机器上运行,只要它们能够连接到Nginx-RTMP服务器即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值