实战小项目之RTMP流媒体演示系统

来源:互联网 发布:json格式化成一行 编辑:程序博客网 时间:2024/06/11 17:40

项目简介

  windows下使用基于Qt对之前的RtmpApp进行封装与应用,单独功能使用线程执行,主要包括以下几个功能:

  1. 视频下载
  2. 推送文件
  3. 推送摄像头数据或者桌面
  4. 基于libvlc的播放器

视频下载部分

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

 

推送文件

 

推送摄像头数据或者桌面

使用videoinput作为视频采集驱动,没有使用qt的camera类,videoinput采集出来的数据是rgb(bgr,可选),直接送入label显示,也可转码、编码推流

复制代码
#include "videocap.h"VideoCap::VideoCap(){    VI=new videoInput;    runFlag=false;    stopFlag=false;    width=0;    height=0;    device=0;    deviceNums=0;    frameSize=0;    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,60);    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(10);    VI->stopDevice(device);}/*yuv格式转换为rgb格式*/void VideoCap::YUV422toRGB24(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height){    unsigned int in, out = 0;    unsigned int pixel_16;    unsigned char pixel_24[3];    unsigned int pixel32;    int y0, u, y1, v;    for(in = 0; in < width * height * 2; in += 4) {        pixel_16 =        yuv[in + 3] << 24 |        yuv[in + 2] << 16 |        yuv[in + 1] <<  8 |        yuv[in + 0];        y0 = (pixel_16 & 0x000000ff);        u  = (pixel_16 & 0x0000ff00) >>  8;        y1 = (pixel_16 & 0x00ff0000) >> 16;        v  = (pixel_16 & 0xff000000) >> 24;        pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);        pixel_24[0] = (pixel32 & 0x000000ff);        pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;        pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;        rgb[out++] = pixel_24[0];        rgb[out++] = pixel_24[1];        rgb[out++] = pixel_24[2];        pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);        pixel_24[0] = (pixel32 & 0x000000ff);        pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;        pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;        rgb[out++] = pixel_24[0];        rgb[out++] = pixel_24[1];        rgb[out++] = pixel_24[2];    }}int VideoCap::convert_yuv_to_rgb_pixel(int y, int u, int v){    unsigned int pixel32 = 0;    unsigned char *pixel = (unsigned char *)&pixel32;    int r, g, b;    r = y + (1.370705 * (v-128));    g = y - (0.698001 * (v-128)) - (0.337633 * (u-128));    b = y + (1.732446 * (u-128));    if(r > 255) r = 255;    if(g > 255) g = 255;    if(b > 255) b = 255;    if(r < 0) r = 0;    if(g < 0) g = 0;    if(b < 0) b = 0;    pixel[0] = r * 220 / 256;    pixel[1] = g * 220 / 256;    pixel[2] = b * 220 / 256;    return pixel32;}
复制代码

 

基于libvlc的视频播放器

  可以播放本地文件

  可以播放rtmp流

复制代码
#include "vlcplayer.h"#include <QDebug>VLCPlayer::VLCPlayer(){}VLCPlayer::~VLCPlayer(){}void VLCPlayer::init(uint32_t winId){    instance =libvlc_new(0,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(2000);    }}void VLCPlayer::pause(bool stat){    if(stat){        libvlc_media_player_set_pause(player,1);    }else{        libvlc_media_player_set_pause(player,0);    }}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

 

转载请注明出处:http://www.cnblogs.com/tla001/一起学习,一起进步
原创粉丝点击