实战小项目之RTMP流媒体演示系统
项目简介
windows下使用基于Qt对之前的RtmpApp进行封装与应用,单独功能使用线程执行,主要包括以下几个功能:
- 视频下载
- 推送文件
- 推送摄像头数据或者桌面
- 基于libvlc的播放器
视频下载部分

最大的坑就是,文件名的那个数组设小了,导致数组越界,写下一个功能的时候,总是崩溃,调了一上午,内心崩溃
推送文件

推送摄像头数据或者桌面

使用videoinput作为视频采集驱动,没有使用qt的camera类,videoinput采集出来的数据是rgb(bgr,可选),直接送入label显示,也可转码、编码推流
#include "videocap.h"
VideoCap::VideoCap(){
VI=new videoInput;
runFlag=false;
stopFlag=false;
width=;
height=;
device=;
deviceNums=;
frameSize=;
buffer=NULL;
}
VideoCap::~VideoCap(){
if(!buffer)
delete[] buffer;
delete VI;
}
void VideoCap::run(){
runFlag=true;
worker();
runFlag=false;
}
int VideoCap::getDeviceNum(){
deviceNums = VI->listDevices();
return deviceNums;
}
int VideoCap::init(int width, int height, int device){
this->device=device;
VI->setUseCallback(true);
VI->setIdealFramerate(this->device,);
VI->setupDevice(device, width, height);
this->width = VI->getWidth(device);
this->height = VI->getHeight(device);
// VI->showSettingsWindow(0);//该语句可以显示视频设置窗口,可以去掉
frameSize = VI->getSize(device);
buffer=new unsigned char[frameSize];
return frameSize;
}
void VideoCap::worker(){
while(!stopFlag){
VI->getPixels(device, buffer, true, true);//不能使用videoInput内置的翻转,内存冲突,暂未解决
emit capFinish();
}
}
void VideoCap::getFrame(unsigned char *&framebuff){
if(framebuff==NULL)
return;
memcpy(framebuff,buffer,frameSize);
}
void VideoCap::doCap(){
stopFlag=false;
this->start();
}
void VideoCap::doStop(){
stopFlag=true;
while(runFlag)
msleep();
VI->stopDevice(device);
}
/*yuv格式转换为rgb格式*/
void VideoCap::YUV422toRGB24(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
{
unsigned int in, out = ;
unsigned int pixel_16;
unsigned char pixel_24[];
unsigned int pixel32;
int y0, u, y1, v;
for(in = ; in < width * height * ; in += ) {
pixel_16 =
yuv[in + ] << |
yuv[in + ] << |
yuv[in + ] << |
yuv[in + ];
y0 = (pixel_16 & 0x000000ff);
u = (pixel_16 & 0x0000ff00) >> ;
y1 = (pixel_16 & 0x00ff0000) >> ;
v = (pixel_16 & 0xff000000) >> ;
pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
pixel_24[] = (pixel32 & 0x000000ff);
pixel_24[] = (pixel32 & 0x0000ff00) >> ;
pixel_24[] = (pixel32 & 0x00ff0000) >> ;
rgb[out++] = pixel_24[];
rgb[out++] = pixel_24[];
rgb[out++] = pixel_24[];
pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
pixel_24[] = (pixel32 & 0x000000ff);
pixel_24[] = (pixel32 & 0x0000ff00) >> ;
pixel_24[] = (pixel32 & 0x00ff0000) >> ;
rgb[out++] = pixel_24[];
rgb[out++] = pixel_24[];
rgb[out++] = pixel_24[];
}
}
int VideoCap::convert_yuv_to_rgb_pixel(int y, int u, int v)
{
unsigned int pixel32 = ;
unsigned char *pixel = (unsigned char *)&pixel32;
int r, g, b;
r = y + (1.370705 * (v-));
g = y - (0.698001 * (v-)) - (0.337633 * (u-));
b = y + (1.732446 * (u-));
if(r > ) r = ;
if(g > ) g = ;
if(b > ) b = ;
if(r < ) r = ;
if(g < ) g = ;
if(b < ) b = ;
pixel[] = r * / ;
pixel[] = g * / ;
pixel[] = b * / ;
return pixel32;
}
基于libvlc的视频播放器
可以播放本地文件
可以播放rtmp流

#include "vlcplayer.h"
#include <QDebug> VLCPlayer::VLCPlayer(){ }
VLCPlayer::~VLCPlayer(){ } void VLCPlayer::init(uint32_t winId){
instance =libvlc_new(,NULL);
this->winId=winId;
// qDebug()<<winId;
player =libvlc_media_player_new(instance);
libvlc_media_player_set_hwnd(player,(void *)winId);
} void VLCPlayer::playFile(string file){
libvlc_media_t *media=libvlc_media_new_path(instance,file.c_str());
// totalTime=libvlc_media_get_duration(media);
// qDebug()<<file.c_str();
if(!media)
qDebug()<<"media null";
else{
libvlc_media_player_set_media(player,media);
// player = libvlc_media_player_new_from_media (media);
libvlc_media_release(media);
// libvlc_media_player_set_xwindow(player,winId);
libvlc_media_player_play(player);
}
}
void VLCPlayer::playUrl(string url){
libvlc_media_t *media=libvlc_media_new_location(instance,url.c_str());
if(!media)
qDebug()<<"net media null";
else{
qDebug()<<"net media not null";
libvlc_media_player_set_media(player,media);
libvlc_media_release(media);
libvlc_media_player_play(player);
_sleep();
}
}
void VLCPlayer::pause(bool stat){
if(stat){
libvlc_media_player_set_pause(player,);
}else{
libvlc_media_player_set_pause(player,);
}
}
void VLCPlayer::stop(){
if(player){
libvlc_media_player_stop(player);
// libvlc_media_player_release(player);
}
}
libvlc_time_t VLCPlayer::getTotalTime(){
return libvlc_media_player_get_length(player);
// return totalTime;
}
libvlc_time_t VLCPlayer::getCurrentTime(){
return libvlc_media_player_get_time(player);
}
libvlc_state_t VLCPlayer::getPlayerStat(){
return libvlc_media_player_get_state(player);
}
void VLCPlayer::setPlayerPostion(float pos){
libvlc_media_player_set_position(player,pos);
}
void VLCPlayer::setVolume(int value){
libvlc_audio_set_volume(player,value);
}
void VLCPlayer::setSpeed(float speed){
libvlc_media_player_set_rate(player,speed);
}
完整工程
https://github.com/tla001/RtmpLive
相关链接
vlc
http://www.cnblogs.com/qq78292959/archive/2010/11/01/2077001.html
http://blog.csdn.net/leixiaohua1020/article/category/2619507
实战小项目之RTMP流媒体演示系统的更多相关文章
- Flask框架的学习与实战(二):实战小项目
昨天写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统. blog系统很简单,只有一个页面,然而麻雀虽小五脏俱全.这里目的不是为了做项目而做项目,这篇文章本意是通过这次练习传达 ...
- 实战小项目BUG纪录
果然,作为程序员最可爱的女朋友就是各种BUG,解决了你的开发能力和开发效率就会上升到一个新的层次.反之,在你面对BUG的时候,如果轻易的就放弃了,你也就失去了一次自我成长的机会.学习就是这样的,我们有 ...
- 【实战小项目】python开发自动化运维工具--批量操作主机
有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子.只不过,很多运维同学学习Python之后,苦于没小项目训练.本篇就演示用Python写一个批量操作主机的工 ...
- Django集成celery实战小项目
上一篇已经介绍了celery的基本知识,本篇以一个小项目为例,详细说明django框架如何集成celery进行开发. 本系列文章的开发环境: window 7 + python2.7 + pychar ...
- [ABP实战开源项目]---ABP实时服务-通知系统.发布模式
简介 在ABP中,提供了通知服务.它是一个基于实时通知的基础设施.分为订阅模式和发布模式. 本次会在项目中使用发布模式来演示一个用户注册后,收到的欢迎信息. 发布模式 首先我们在领域层建立" ...
- ASP.NET Core 2.1 Web API + Identity Server 4 + Angular 6 + Angular Material 实战小项目视频
视频简介 ASP.NET Core Web API + Angular 6的教学视频 我是后端开发人员, 前端的Angular部分讲的比较差一些, 可以直接看代码!!!! 这是一个小项目的实战视频, ...
- spring boot的一个小项目小型进销存系统
项目所需的依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g ...
- springboot实战小项目-简要介绍、vue项目创建
因为菜,所以要好好学习! 一.项目介绍:这是一个后台管理系统,准备实现的功能: 1.登录.注册.个人信息查看.退出登录 2.根据关键字查询用户.新增用户.根据id或者其他字段排序.编辑用户信息.删除用 ...
- 实战小项目之ffmpeg推流yolo视频实时检测
之前实现了yolo图像的在线检测,这次主要完成远程视频的检测.主要包括推流--収流--检测显示三大部分 首先说一下推流,主要使用ffmpeg命令进行本地摄像头的推流,为了实现首屏秒开使用-g设置gop ...
随机推荐
- DELL R730安装ESXI虚拟化
dell安装esxi需要dell官方提供的镜像文件地址:http://www.dell.com/support/article/us/en/04/SLN290857/dell%E5%AE%9A%E5% ...
- cms-登陆
先介绍下登陆的思路: 1.在登陆页面首先前端验证用户名和密码是否正确,如果验证通过,则ajax的方式向后台提交数据. 2.在controller层,将得到的用户名名和密码封装进shiro的token, ...
- 真实场景中WebRTC 用到的服务 STUN, TURN 和 signaling
FQ收录转自:WebRTC in the real world: STUN, TURN and signaling WebRTC enables peer to peer communication. ...
- 如何在Java代码中使用SAP云平台CloudFoundry环境的环境变量
本文使用的例子源代码在我的github上. 在我的公众号文章在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务介绍了如何通过Cloud Connector ...
- 【洛谷1486】[NOI2004] 郁闷的出纳员(Splay的小运用)
点此看题面 大致题意: 你是一个公司的出纳员,现在有\(n\)个操作,操作有4种:新来一个员工.增加全体员工工资.减少全体员工工资.查询第\(k\)多的工资.若一个员工的工资在某一时刻低于合同上的工资 ...
- 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 FTP 服务器
我们经常会使用 FTP,把本地电脑上的文件上传到服务器上,或者把服务器上的文件下载到自己的电脑里面.FTP 有服务端和客户端,FTP 的服务端提供了这种传输文件的服务,FTP 的客户端提供了传输文件的 ...
- java从键盘输入学生成绩,找出最高分,并输出学生成绩等级。
/*从键盘输入学生成绩,找出最高分,并输出学生成绩等级:成绩 >=最高分-10 等级为A成绩 >=最高分-20 等级为B成绩 >=最高分-30 等级为C其余为 等级为D 提示:先输入 ...
- react安装极其了解
全局安装react脚手架工具 首先全局进行安装:cnpm install create-react-app -g 查看是否安装完成:create-react-app 创建react项目:create- ...
- nuxt.js服务端缓存lru-cache
对于部分网页进行服务端的缓存,可以获得更好的渲染性能,但是缓存又涉及到一个数据的及时性的问题,所以在及时性和性能之间要有平衡和取舍. 官方文档里面写的使用方法 按照这个配置,试过了没什么用,但是从文档 ...
- tcl之变量-unset 简单变量和数组