实战小项目之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 ...
随机推荐
- linux 命令——40 wc (转)
Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 1.命令格式: wc [选项]文件... 2.命令功能: 统计指定文件中的字节数. ...
- World Wind Java开发之八——加载本地缓存文件构建大范围三维场景(
http://blog.csdn.net/giser_whu/article/details/42044599 上一篇博客主要是针对小文件直接导入WW中显示,然而当文件特别大时,这种方式就不太可行.因 ...
- iOS 不同的崩溃类型
http://m.blog.csdn.net/kangguang/article/details/62501490 用汇编语言编写的软件跟用脚本或标记语言编写的Web应用的差别在于,前者在出现问题时会 ...
- 【洛谷1993】小K的农场(差分约束系统模板题)
点此看题面 大致题意: 给你若干组不等式,请你判断它们是否有解. 差分约束系统 看到若干组不等式,应该很容易想到差分约束系统吧. \(A-B≥C\):转换可得\(A-B≥C\) \(A-B≤C\):转 ...
- RAID0 1 5 10原理、种类及性能优缺点对比
一.RAID模式优缺点的简要介绍 目前被运用较多的RAID模式其优缺点大致是这样的: 1.RAID0模式 优点:在RAID 0状态下,存储数据被分割成两部分,分别存储在两块硬盘上,此时移动硬盘的理论存 ...
- 【转】操作系统Unix、Windows、Mac OS、Linux的故事
电脑,计算机已经成为我们生活中必不可少的一部分.无论是大型的超级计算机,还是手机般小巧的终端设备,都跑着一个操作系统.正是这些操作系统,让那些硬件和芯片得意组合起来,让那些软件得以运行,让我们的世界在 ...
- LuceneTest
/** * Created by mhm on 2019/6/24. */@RunWith(SpringJUnit4ClassRunner.class)public class LuceneTest ...
- JS时间格式和时间戳的相互转换
时间戳转化为日期的方式 ; var newDate = new Date(); newDate.setTime(timestamp * ); // Mon May 28 2018 console.lo ...
- vue框架初学习的基本指令
学习地址:<ahref="https: cn.vuejs.="" org="" "="" targe ...
- Microsoft .Net framework 4.0出现 安装不成功,错误代码0x80240037 的解决方法
,安装Microsoft .Net framework 时出现 解决方法:用QQ管家 之后 以上就解决了