使用QT编写视频播放器总结
本文是關(guān)于基于QMediaPlayer的播放器的總結(jié),一開始我的想法就是想用opencv做一個(gè)視頻播放器,因?yàn)閛pencv平時(shí)用的也比較順手,但是花了半天的時(shí)間實(shí)際一做才知道事情沒那么簡(jiǎn)單,首先使用opencv加載本地視頻文件到界面上就花了不少時(shí)間,在使用qt播放opencv傳過來的視頻的時(shí)候播放的基本原理還是沒變,仍然是一幀一幀的連續(xù)輸出就形成了視頻。但是這個(gè)地方有好幾個(gè)要注意的地方,首先,opencv自帶的waikey函數(shù)在qt里面不能用,因?yàn)楸旧韜aikey函數(shù)在opencv播放視頻時(shí)是用來設(shè)置幀間的時(shí)間間距的,此時(shí)必須要根據(jù)視頻的幀率來設(shè)置幀數(shù)之間的時(shí)間間隔;其次,waikey函數(shù)在opencv中使用習(xí)慣了沒注意到,這個(gè)函數(shù)本身是和其他函數(shù)配合起到持續(xù)輸出幀數(shù)的作用,在輸出的過程中必須有。。。(這個(gè)地方忘了,先擱置一下);因此如果直接在qt中使用這個(gè)函數(shù)的話會(huì)出現(xiàn)沒有畫面的情況,為此,我們需要選用qt里面的Qtimer控件,進(jìn)行輸出間隔的控制,然后還是根據(jù)視頻的幀數(shù)設(shè)置輸出間隔。以上工作都搞得差不多了之后,我發(fā)現(xiàn)了一個(gè)最操蛋的事,這樣使用opencv輸出來的視頻是沒有聲音的!前前后后搞了一個(gè)下午,浪費(fèi)了不少時(shí)間,但是也算是加深了對(duì)opencv進(jìn)一步的了解了吧。
通過網(wǎng)上的查閱和與師兄的溝通發(fā)現(xiàn),原來做視頻播放器的庫有很多,包括qt自帶的QMediaPlayer、ffmpeg等等,本來聽說ffmpeg還不錯(cuò),但是一到官網(wǎng)一看沒有直接的安裝包,心想還是用qt自帶的庫吧。下面是我在使用QMediaPlayer過程中遇到的一些困難和解決問題的辦法。
由于我是qt初學(xué)者,對(duì)qt中的很多機(jī)制還不是特別的了解,但是通過做了這么一個(gè)小例子,我把基本的一些問題都搞的比較清楚了,最起碼后面再碰到大部分問題時(shí)心里有個(gè)方向了。
首先是Qtimer這個(gè)控件的使用上,之前對(duì)槽與信號(hào)了解的也不是很深,以為大部分槽都可以在界面上找到,但是我這個(gè)項(xiàng)目做的越深越發(fā)現(xiàn)原來很多界面的設(shè)置可以用代碼實(shí)現(xiàn),一旦用了代碼就不能簡(jiǎn)單的使用界面一點(diǎn)直接跳轉(zhuǎn)的方式來寫槽與信號(hào)了。我對(duì)信號(hào)的理解就是,信號(hào)本身就是一個(gè)函數(shù),但是不能被定義,并且要在頭文件里用signals關(guān)鍵字指出,信號(hào)不能有返回值,它僅代表在某個(gè)控件或窗體上出發(fā)了某個(gè)東西,然后由信號(hào)就會(huì)產(chǎn)生對(duì)應(yīng)的槽函數(shù),槽函數(shù)是和普通函數(shù)沒太大差別的函數(shù),它本身要以關(guān)鍵字slots在頭文件中指出,在定義的時(shí)候可以寫入任意的操作。并且信號(hào)與槽機(jī)制在子窗體和父窗體的值的傳遞中起著重要作用,可以使用槽與信號(hào)實(shí)現(xiàn)父窗體傳值到子窗體,也可以實(shí)現(xiàn)子窗體傳值到父窗體,也就是說,有了槽與信號(hào),可以很靈活的控制子父窗體數(shù)據(jù)之間的聯(lián)系。Qtimer這個(gè)控件的大部分使用都是和信號(hào)與槽結(jié)合在一起的,connect(timer,SIGNAL(timeOut()),this,SLOT(on_timeout()));通過初始化一個(gè)timer并且設(shè)置其時(shí)間間隔,以毫秒為單位,之后每過一個(gè)時(shí)間間隔,就會(huì)發(fā)出一個(gè)信號(hào)使槽函數(shù)開始運(yùn)行,知道設(shè)置timer.stop(),信號(hào)停止發(fā)送。因此利用QTimer這個(gè)控件可以實(shí)現(xiàn)很多定時(shí)操作。在這個(gè)項(xiàng)目里面主要是用來設(shè)置當(dāng)播放視頻全屏?xí)r鼠標(biāo)懸浮一段時(shí)間之后自動(dòng)隱藏,然后在鼠標(biāo)移動(dòng)之后重新出現(xiàn)鼠標(biāo)指針,但是這個(gè)地方有個(gè)問題,鼠標(biāo)移動(dòng)必須按住任意一個(gè)按鍵才能使指針顯示出來,并且我使用的就是MouseMoveEvent(),這個(gè)問題目前還沒解決。
然后就是界面的布局上,之前對(duì)qt的界面布局很迷,因?yàn)橐婚_始學(xué)習(xí)編程時(shí)接觸了一段時(shí)間的C#,C#的界面布局感覺要簡(jiǎn)單很多,但是這么幾天我發(fā)現(xiàn)其實(shí)qt的布局也很方便,一旦理解了就很容易做出來比較好看的布局。關(guān)于布局第一點(diǎn)是五種布局方式,垂直、水平、柵格、群組等,在布局的時(shí)候我發(fā)現(xiàn)視頻和控制按鈕得分割開,我一開始是不知道用什么方式的,后來在網(wǎng)上一查,可以使用QSplitter進(jìn)行分割,QSplitter也是控件,并且是由分割線和本體組成的,分割線的粗細(xì)和顏色都可以自定義設(shè)置,但是粗細(xì)只能是整數(shù),因此無法設(shè)置小于一的線寬,一般默認(rèn)情況下Qsplitter的分割線是可以被移動(dòng)的,但是也可以通過設(shè)置分割線的屬性值setEnabled來設(shè)置其不可調(diào)整比例,主要用法如下
QSplitterHandle *pHandle = splitter->handle(1); pHandle->setEnabled(false); pHandle->setStyleSheet("background-color:rgba(0,48,77,0.7)"); QSplitterHandle *cHandle = splitter_video->handle(1); cHandle->setEnabled(false); cHandle->setStyleSheet("background-color:rgba(0,48,77,0.7)");
主要就是通過獲取splitter的handle值來單獨(dú)設(shè)置,網(wǎng)上很多說可以利用setOpaque函數(shù)的值來設(shè)置的,我始終沒設(shè)置成功,最終就是用的上述方法來設(shè)置的。此外關(guān)于splitter的一點(diǎn)就是初始比例如果不設(shè)置的話就是默認(rèn)的1:1,在某些情況下自己設(shè)置的比例如果不生效就會(huì)自動(dòng)采用默認(rèn)比例。我這個(gè)項(xiàng)目里主要用到了兩個(gè)splitter,所以在分割的時(shí)候一定注意比例的問題,當(dāng)時(shí)一開始我怎么設(shè)置都不生效,后來我發(fā)現(xiàn)對(duì)于QMainWindow本身要設(shè)置一個(gè)主窗體,因?yàn)橹虚g的窗口很多,會(huì)涉及到?jīng)_突的問題,我的做法是用一個(gè)最大的splitter設(shè)置為窗體的主窗體,然后其他所有的布局都在這上面進(jìn)行,在布局的時(shí)候還遇到了一個(gè)問題,就是涉及到控件的嵌套布局方式,當(dāng)對(duì)多個(gè)控件使用組合布局時(shí)一定不要先設(shè)置父窗體指針,要在最后一個(gè)布局上設(shè)置才會(huì)生效。
`QHBoxLayout *hbLayoutCtrl = new QHBoxLayout();
hbLayoutCtrl->addWidget(labelTime);
hbLayoutCtrl->addStretch();
hbLayoutCtrl->addStretch();
hbLayoutCtrl->addStretch();
hbLayoutCtrl->addWidget(btn_stop);
hbLayoutCtrl->addWidget(btn_previous);
hbLayoutCtrl->addWidget(btn_play);
hbLayoutCtrl->addWidget(btn_next);
hbLayoutCtrl->addWidget(btn_volume);
hbLayoutCtrl->addWidget(audio_slider);
hbLayoutCtrl->addStretch();
hbLayoutCtrl->addStretch();
hbLayoutCtrl->addWidget(btn_fullScreen);
hbLayoutCtrl->addWidget(btn_hidePlayList);
//進(jìn)度條的設(shè)置 涉及到多個(gè)布局混合的方式,一定要在最終的布局里面再設(shè)置父窗口指針
slider->setOrientation(Qt::Horizontal);
slider->setVisible(false);
audio_slider->setOrientation(Qt::Horizontal);
QHBoxLayout *hbSliderLayout = new QHBoxLayout();
hbSliderLayout->addWidget(slider);
總結(jié)
以上是生活随笔為你收集整理的使用QT编写视频播放器总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(1709):前端系列javas
- 下一篇: c++rs法计算hurst指数_计算机组