本篇内容主要讲解“Qt vlc解码播放怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Qt vlc解码播放怎么实现”吧!
最开始接触视频监控这块的时候,用的就是vlc作为解码的内核,主要是因为vlc使用简单方便,直接传入一个句柄即可,简单几行代码就可以实现一个视频流播放,很适合初学者使用,也推荐初学者用qt+vlc来做播放器,提供的接口还是非常友好的,而且门类特别多,想要获取媒体文件的各种信息比如宽高,设置宽高比等,直接调用接口函数传入参数就能设置。
所有用vlc做视频监控解码的人都会遇到一个问题,那就是鼠标事件被接管拦截了,不能识别鼠标事件,比如双击最大化等,这就很憋屈了,明明很好用的一个东西,怎么突然之间鼠标事件也识别不到了呢,网上一搜一大把,主要有三个解决办法。
修改vlc源码,重新编译,替换动态库文件。
全局鼠标钩子拦截鼠标消息进行处理。
设置句柄以后直接将控件/接受视频渲染的控件禁用掉。
最终采用方法3,实现起来简单快速,修改vlc源码的编译工作量太大了,毕竟vlc依赖一大堆的插件,用vlc的人一般都是初学者半吊子,哪里有能力去编译一遍vlc哦。
多线程实时播放视频流和本地视频。
支持windows+linux+mac,支持vlc2和vlc3。
多线程显示图像,不卡主界面。
自动重连网络摄像头。
可设置边框大小即偏移量和边框颜色。
可设置是否绘制OSD标签即标签文本或图片和标签位置。
可设置两种OSD位置和风格。
可设置是否保存到文件以及文件名。
可直接拖曳文件到vlcwidget控件播放。
支持h365视频流+rtmp等常见视频流。
可暂停播放和继续播放。
支持回调模式和句柄两种模式。
支持线程读取进度等信息和事件回调两种处理模式。
自动将当前播放位置和音量大小是否静音以信号发出去。
提供接口设置播放位置和音量及设置静音。
支持存储单个视频文件和定时存储视频文件。
自定义顶部悬浮条,发送单击信号通知,可设置是否启用。
bool VlcThread::init() { //判断该摄像机是否能联通 if (checkConn && isRtsp) { if (!checkUrl(url, checkTime)) { return false; } } QFileInfo info(url); suffix = info.suffix(); //设置拓展名 if (url.startsWith("dshow://")) { suffix = "dshow"; } else if (url.startsWith("rtsp")) { suffix = "rtsp"; } else if (url.startsWith("rtmp")) { suffix = "rtmp"; } else if (url.startsWith("http")) { suffix = "http"; } const char *tempArg = ""; if (suffix == "h364") { tempArg = "--demux=h364"; } else if (suffix == "h365") { tempArg = "--demux=h365"; } const char *vlc_args[9] = {"-I", "dummy", "--no-osd", "--no-stats", "--ignore-config", "--no-video-on-top", "--no-video-title-show", "--no-snapshot-preview", tempArg}; vlcInst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args); if (vlcInst == NULL) { return false; } if (isRtsp || suffix == "dshow") { vlcMedia = libvlc_media_new_location(vlcInst, url.toUtf8().constData()); } else { //windows上需要替换文件路径 QString url = this->url; url = QDir::toNativeSeparators(url); vlcMedia = libvlc_media_new_path(vlcInst, url.toUtf8().constData()); } if (vlcMedia == NULL) { return false; } //媒体播放对象 vlcPlayer = libvlc_media_player_new_from_media(vlcMedia); if (vlcPlayer == NULL) { return false; } //创建事件管理器 if (callbackevent) { vlcEvent = libvlc_media_player_event_manager(vlcPlayer); libvlc_event_new(vlcEvent, this); } //回调方式和句柄方式两种分别处理 if (callback) { callbackData = new CallbackData; callbackData->thread = this; callbackData->pixels = new uchar[bufferWidth * bufferHeight * 4]; memset(callbackData->pixels, 0, bufferWidth * bufferHeight * 4); int width = callbackData->thread->getBufferWidth(); int height = callbackData->thread->getBufferHeight(); //设置回调拿到每帧数据 libvlc_video_set_callbacks(vlcPlayer, lock, unlock, display, callbackData); //设置每帧格式 RV32-Format_RGB32 RGBA-Format_RGBA8888 YUYV I420 libvlc_video_set_format(vlcPlayer, "RV32", width, height, width * 4); } else { //设置播放句柄 if (playWidget == NULL) { return false; } #if defined(Q_OS_WIN) libvlc_media_player_set_hwnd(vlcPlayer, (void *)playWidget->winId()); #elif defined(Q_OS_LINUX) libvlc_media_player_set_xwindow(vlcPlayer, playWidget->winId()); #elif defined(Q_OS_MAC) libvlc_media_player_set_nsobject(vlcPlayer, (void *)playWidget->winId()); #endif //禁用句柄鼠标消息 QTimer::singleShot(1000, this, SLOT(disableHwnd())); } //设置硬件加速 none auto any d3d11va dxva2 setOption(QString(":avcodec-hw=%1").arg(hardware)); //设置通信协议 tcp udp setOption(QString(":rtsp-%1").arg(transport)); //设置缓存时间 默认500毫秒 setOption(QString(":network-caching=%1").arg(caching)); //:rtsp-frame-buffer-size=1000000 //设置宽度高度,本地USB摄像头需要单独设置 if (suffix == "dshow") { setOption(QString(":dshow-size=%1*%2").arg(videoWidth).arg(videoHeight)); } else { setSize(videoWidth, videoHeight); } //设置保存文件 this->initSave(); //打开播放 libvlc_media_player_play(vlcPlayer); //qDebug() << TIMEMS << "init vlc finsh"; return true; }
到此,相信大家对“Qt vlc解码播放怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。