有的搜索引擎排名與網(wǎng)站的加載速度或多或少有些關(guān)系,而這次百度閃電算法來(lái)了,將網(wǎng)站首屏打開(kāi)速度被列入優(yōu)化排名行列,并明確指定打開(kāi)時(shí)間為2秒,那么我們?cè)谌绾巫龊镁W(wǎng)頁(yè)首屏的打開(kāi)速度呢?
要做好網(wǎng)站速度優(yōu)化,就必須要做好軟件和硬件兩個(gè)方面,從網(wǎng)站程序以及頁(yè)面設(shè)計(jì)本身解決網(wǎng)頁(yè)資源的加載,然后就是服務(wù)器本身需要有足夠的帶寬及處理資源,下面子凡就依次來(lái)與大家探討。
首先我們打開(kāi)一個(gè)網(wǎng)頁(yè)看到的都只是前端,所以我們看到一個(gè)頁(yè)面背后的支持就是HTML代碼,其中就包含了各種網(wǎng)頁(yè)標(biāo)簽,其中包括網(wǎng)站優(yōu)化中的TKD,載入的渲染資源:javascript、css,已經(jīng)頁(yè)面內(nèi)容:圖片、音頻、視頻等。
一、代碼的足夠簡(jiǎn)潔
減少代碼冗余,保持簡(jiǎn)潔的代碼風(fēng)格,這是作為一個(gè)網(wǎng)頁(yè)程序員的必修,能同樣實(shí)現(xiàn)一個(gè)效果的能用css就盡量不用js,能用兩行代碼解決問(wèn)題的就別寫(xiě)三行,這是最基礎(chǔ)的一點(diǎn)。
二、減少資源載入
這里子凡所說(shuō)的資源主要是指js、css文件,因?yàn)槲抑垃F(xiàn)在很多的前端開(kāi)發(fā)設(shè)計(jì)人員喜歡用各種開(kāi)源的特效或者別人做好的效果,其中包括為了給網(wǎng)站添加幾個(gè)圖標(biāo)就引入一個(gè)開(kāi)源的圖標(biāo)字體庫(kù),為了某個(gè)特效又在引入幾個(gè)js和css文件,這無(wú)形之中就為網(wǎng)站加重了“份量”。
三、圖片使用懶加載,視頻或音頻禁止自動(dòng)播放
還記得子凡曾在淚雪博客寫(xiě)過(guò)關(guān)于“圖片懶加載是否會(huì)影響網(wǎng)站SEO優(yōu)化”的文章,其中就說(shuō)到過(guò)如何合理的使用圖片懶加載技術(shù)提升用戶(hù)體驗(yàn)而不影響網(wǎng)站優(yōu)化,因?yàn)閼屑虞d是為了防止頁(yè)面一被打開(kāi)就立即載入圖片,這樣就會(huì)占用網(wǎng)絡(luò)帶寬,從而影響網(wǎng)站的打開(kāi)速度以及網(wǎng)站首屏的請(qǐng)求,所以非正文圖片都是可以做懶加載的。
圖片是每個(gè)網(wǎng)站基本都少不了的東西,但是對(duì)于做視頻、音頻的站點(diǎn)來(lái)說(shuō),如果打開(kāi)頁(yè)面就自動(dòng)播放,占用的網(wǎng)站帶寬資源都更多了,所以這也是一個(gè)網(wǎng)站打開(kāi)速度優(yōu)化的一個(gè)小知識(shí)。
四、使用CDN加速靜態(tài)資源
關(guān)于使用CDN加速是否影響網(wǎng)站優(yōu)化的文章子凡也曾有過(guò)討論,子凡對(duì)于網(wǎng)站整體做CDN加速還是有些不太認(rèn)同,但是對(duì)于將網(wǎng)站靜態(tài)資源做CDN加速鏡像或者緩存優(yōu)化卻是非常認(rèn)同的,例如將網(wǎng)站的js、css、圖片等文件做CDN加速是更有利于整個(gè)網(wǎng)站的加載和打開(kāi)速度的。
五、提升頁(yè)面渲染速度
將CSS樣式寫(xiě)在頭部樣式表中,減少由CSS文件網(wǎng)絡(luò)請(qǐng)求造成的渲染阻塞。
將JavaScript放到文檔末尾,或使用async方式加載,避免JS執(zhí)行阻塞渲染。
對(duì)非文字元素(如圖片,視頻)指定寬高,避免瀏覽器重排重繪。
六、服務(wù)器本身的速度優(yōu)化
啟用服務(wù)器Gzip壓縮功能;
開(kāi)啟數(shù)據(jù)庫(kù)查詢(xún)及頁(yè)面緩存功能(如果是直接生成靜態(tài)頁(yè)面的網(wǎng)站可忽略);
升級(jí)或者保證服務(wù)器足夠的網(wǎng)絡(luò)帶寬;
開(kāi)啟網(wǎng)站緩存,充分利用本地緩存。
同樣隨著網(wǎng)絡(luò)安全的重視程度,如果你的網(wǎng)站已經(jīng)安裝SSL證書(shū)啟用了HTTPS協(xié)議,那么你可以開(kāi)啟HTTPS/2或者SPDY這個(gè)功能,可以在某些程度上加速網(wǎng)站的打開(kāi)。
總結(jié)
雖然百度“閃電算法”是正對(duì)移動(dòng)搜索排名的算法,而子凡上述的所有知識(shí)點(diǎn)都是通用的,并沒(méi)有移動(dòng)端或電腦端的區(qū)分,寫(xiě)得不算非常詳細(xì),子凡只是將這些非常容易出現(xiàn)的問(wèn)題或者被忽略的問(wèn)題按照自己的思路寫(xiě)出來(lái)了,雖然語(yǔ)句都寫(xiě)得非常簡(jiǎn)單,但是要真的操作起來(lái),如果你不懂網(wǎng)頁(yè)代碼或者服務(wù)器,操作起來(lái)可能也會(huì)是已經(jīng)非常困難的事情。
最后最后子凡還想給自己的 Fanly MIP 主題打個(gè)廣告,如果你使用WordPress程序,并且重視百度這次的閃電算法,你可以使用子凡開(kāi)發(fā)的這個(gè)MIP主題和插件,因?yàn)橹黝}和插件都提供免費(fèi)版本,所以大家可以非常方便的接入,當(dāng)然你也可以支持子凡或者想要更好的服務(wù)可以購(gòu)買(mǎi)我的收費(fèi)版本。
好啦,如果你看這里,本文從標(biāo)題到正文,再到最后的廣告你都已經(jīng)閱讀完畢。see you。。。
除非注明,否則均為淚雪博客原創(chuàng)文章,轉(zhuǎn)載請(qǐng)以鏈接形式標(biāo)明本文地址
本文鏈接:https://zhangzifan.com/website-speed-seo.html
QFile read("./music/Nevada.mp3");
if (!read.open(QIODevice::ReadOnly))
{
qDebug() << "文件打開(kāi)失敗,請(qǐng)重試~";
}
//下面用的對(duì)象,必須動(dòng)態(tài)申請(qǐng),不然構(gòu)造函數(shù)執(zhí)行完畢,局部變量?jī)?nèi)存會(huì)被釋放
QByteArray *data=new QByteArray(read.readAll());
read.close();
QBuffer *buffer=new QBuffer(data,this);
if (!buffer->open(QIODevice::ReadWrite))
{
qDebug() << "buffer error";
}
//qDebug() << data;
QMediaPlayer *player=new QMediaPlayer(this);
player->setMedia(QMediaContent(),buffer);
player->play();
QMediaPlayer *player=new QMediaPlayer(this);
player->setMedia(QUrl("./music/MMD.mp4"));
player->play();
?
QVideoWidget* videowidget=new QVideoWidget(this);
player->setVideoOutput(videowidget);
vs中如果提示編譯器堆空間不足,則打開(kāi)vcxproj工程文件,在PropertyGroup中添加如下代碼
<PropertyGroup Label="Globals">
<!-- 資源文件加載,防止編譯器堆空間不足 -->
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
【領(lǐng)QT開(kāi)發(fā)教程學(xué)習(xí)資料,點(diǎn)擊下方鏈接免費(fèi)領(lǐng)取↓↓,先碼住不迷路~】
點(diǎn)擊→領(lǐng)取「鏈接」
在Qt中,要想使計(jì)算機(jī)發(fā)出響聲,最簡(jiǎn)單的方法是調(diào)用QApplication : : beep()靜態(tài)函數(shù)。而Qt Multimedia模塊中提供了多個(gè)類(lèi)來(lái)實(shí)現(xiàn)不同層次的音頻輸入,輸出和處理。
QSound類(lèi)提供了播放.wav聲音文件的方法。
Qt 提供了 GUI 應(yīng)用程序中最常用的音頻操作:異步播放聲音文件。 使用靜態(tài) play() 函數(shù)最容易做到這一點(diǎn):
QSound::play("mysounds/bells.wav");
或者,首先從聲音文件創(chuàng)建一個(gè) QSound 對(duì)象,然后調(diào)用 play() 槽:
QSound bells("mysounds/bells.wav");
bells.play();
在這兩種情況下,文件可能是本地文件或資源中的文件。
一旦創(chuàng)建了 QSound 對(duì)象,就可以查詢(xún)它的 fileName() 和 loops() 總數(shù)(即聲音播放的次數(shù))。 可以使用 setLoops() 函數(shù)更改重復(fù)次數(shù)。 播放聲音時(shí),loopsRemaining() 函數(shù)返回剩余的重復(fù)次數(shù)。 使用 isFinished() 函數(shù)來(lái)確定聲音是否播放完畢。
使用 QSound 對(duì)象播放的聲音可能會(huì)比靜態(tài) play() 函數(shù)使用更多的內(nèi)存,但它也可能播放得更快(取決于底層平臺(tái)的音頻設(shè)施)。
如果您需要更好地控制播放聲音,請(qǐng)考慮 QSoundEffect 或 QAudioOutput 類(lèi)。
QSound(const QString &filename, QObject *parent=nullptr)
virtual ~QSound()
QString fileName() const
bool isFinished() const
int loops() const
int loopsRemaining() const
void setLoops(int number)
void play()
void stop()
void play(const QString &filename)
QSoundEffect類(lèi)提供了一種播放低延遲聲音效果的方法 。
這個(gè)類(lèi)允許你以較低的延遲方式播放未壓縮的音頻文件(通常是WAV文件),并且適用于“反饋”類(lèi)型的聲音,以響應(yīng)用戶(hù)的動(dòng)作(例如虛擬鍵盤(pán)聲音,彈出對(duì)話框的正面或負(fù)面反饋,或游戲聲音)。 如果低延遲不重要,可以考慮使用QMediaPlayer類(lèi),因?yàn)樗С指鼜V泛的媒體格式,并且資源消耗更少。
看個(gè)例子:
QSoundEffect effect;
effect.setSource(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/video_call.wav"));
effect.setLoopCount(QSoundEffect::Infinite);
effect.setVolume(0.8f);
effect.play();
通常應(yīng)該重用音效,這樣可以提前完成所有解析和準(zhǔn)備工作,并且只在必要時(shí)觸發(fā)。 這有助于降低延遲音頻播放。
class MyGame
{
public:
MyGame(): m_videoCall(this)
{
m_videoCall.setSource(QUrl::fromLocalFile("video_call.wav"));
m_videoCall.setVolume(0.25f);
?
// Set up click handling etc.
connect(clickSource, &QPushButton::clicked, &m_videoCall, &QSoundEffect::play);
}
private:
QSoundEffect m_videoCall;
}
由于QSoundEffect需要更多的資源來(lái)實(shí)現(xiàn)較低的延遲播放,平臺(tái)可能會(huì)限制同時(shí)播放聲音效果的數(shù)量。
【領(lǐng)QT開(kāi)發(fā)教程學(xué)習(xí)資料,點(diǎn)擊下方鏈接免費(fèi)領(lǐng)取↓↓,先碼住不迷路~】
點(diǎn)擊→領(lǐng)取「鏈接」
//設(shè)置源(wav文件路徑)
void setSource(const QUrl &url)
//設(shè)置循環(huán)次數(shù)
void setLoopCount(int loopCount)
//設(shè)置靜音
void setMuted(bool muted)
//設(shè)置音量0~1之間
void setVolume(qreal volume)
//音效是否加載完畢
bool isLoaded() const
//是否是靜音
bool isMuted() const
//是否正在播放
bool isPlaying() const
void play() //播放
void stop() //停止
void categoryChanged()
void loadedChanged()
void loopCountChanged()
void loopsRemainingChanged()
void mutedChanged()
void playingChanged()
void sourceChanged()
void statusChanged()
void volumeChanged()
枚舉 | 描述 |
QSoundEffect::Null | 未設(shè)置源或源為空。 |
QSoundEffect::Loading | SoundEffect 正在嘗試加載源。 |
QSoundEffect::Ready | 源已加載并準(zhǔn)備好播放。 |
QSoundEffect::Error | 運(yùn)行過(guò)程中出現(xiàn)錯(cuò)誤,例如加載源失敗。 |
QMediaPlayer類(lèi)是一個(gè)高級(jí)媒體播放類(lèi)。 它可以用來(lái)播放歌曲、電影和網(wǎng)絡(luò)廣播等內(nèi)容。 要播放的內(nèi)容被指定為QMediaContent對(duì)象,可以將其視為附加了附加信息的主要或規(guī)范URL。 當(dāng)提供QMediaContent時(shí),可以開(kāi)始播放。
QMediaPlayer player;
player.setMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/That-Girl.mp3"));
player.setVolume(50);
player.play();
QVideoWidget可以與QMediaPlayer一起用于視頻渲染,QMediaPlaylist用于訪問(wèn)播放列表功能。
QVideoWidget wid;
wid.show();
?
QMediaPlaylist playList;
playList.addMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/That-Girl.mp3"));
playList.addMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/干坤坤.mp4"));
?
QMediaPlayer player;
player.setPlaylist(&playList);
//player.setMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/That-Girl.mp3"));
player.setVolume(50);
playList.next();
player.setVideoOutput(&wid);
player.play();
//該值是當(dāng)前媒體的總播放時(shí)間,以毫秒為單位。 該值可能在QMediaPlayer對(duì)象的生命周期中發(fā)生變化,并且可能在初始回放開(kāi)始時(shí)不可用,請(qǐng)連接到durationChanged()信號(hào)來(lái)接收狀態(tài)通知。
qint64 duration() const
//將QVideoWidget視頻輸出附加到媒體播放器。
void setVideoOutput(QVideoWidget *output)
void setVideoOutput(QGraphicsVideoItem *output)
void setVideoOutput(QAbstractVideoSurface *surface)
//暫停播放當(dāng)前源
void pause()
//開(kāi)始或恢復(fù)播放當(dāng)前源
void play()
//設(shè)置當(dāng)前媒體源。 使用mediaStatusChanged()和error()信號(hào),以便在加載媒體和加載過(guò)程中發(fā)生錯(cuò)誤時(shí)得到通知
void setMedia(const QMediaContent &media, QIODevice *stream=nullptr)
//設(shè)置靜音
void setMuted(bool muted)
//設(shè)置倍速播放
void setPlaybackRate(qreal rate)
//設(shè)置播放列表
void setPlaylist(QMediaPlaylist *playlist)
//設(shè)置播放位置,以媒體開(kāi)始后的毫秒數(shù)為單位。 位置的周期性變化將用信號(hào)positionChanged()表示,更新間隔可以用QMediaObject的方法setNotifyInterval()設(shè)置。
void setPosition(qint64 position)
//此屬性保存當(dāng)前播放音量。 播放音量是線性縮放的,從0(靜音)到100(全音量)。默認(rèn)為100
void setVolume(int volume)
//停止播放,并將播放位置重置到開(kāi)始
void stop()
//表示當(dāng)前播放內(nèi)容已更改為media。
void currentMediaChanged(const QMediaContent &media)
//表示內(nèi)容的持續(xù)時(shí)間已更改為持續(xù)時(shí)間,以毫秒表示。
void durationChanged(qint64 duration)
//產(chǎn)生了錯(cuò)誤
void error(QMediaPlayer::Error error)
//表示媒體來(lái)源已轉(zhuǎn)變?yōu)閙edia。
void mediaChanged(const QMediaContent &media)
//表示當(dāng)前媒體的狀態(tài)已經(jīng)改變
void mediaStatusChanged(QMediaPlayer::MediaStatus status)
//靜音狀態(tài)改變
void mutedChanged(bool muted)
//播放速率改變
void playbackRateChanged(qreal rate)
//播放位置改變
void positionChanged(qint64 position)
//表示播放器對(duì)象的狀態(tài)已經(jīng)改變。
void stateChanged(QMediaPlayer::State state)
//音量改變
void volumeChanged(int volume)
(enum QMediaPlayer::Error)媒體播放器產(chǎn)生的具體錯(cuò)誤。
枚舉 | 描述 |
MediaPlayer::NoError | 沒(méi)有錯(cuò)誤發(fā)生 |
QMediaPlayer::ResourceError | 無(wú)法解析媒體源 |
QMediaPlayer::FormatError | 媒體資源的格式不受(完全)支持。 重新播放是可能的,但沒(méi)有音頻或視頻組件。 |
QMediaPlayer::NetworkError | 網(wǎng)絡(luò)錯(cuò)誤 |
QMediaPlayer::AccessDeniedError | 沒(méi)有播放媒體資源的適當(dāng)權(quán)限。 |
QMediaPlayer::ServiceMissingError | 找不到有效的播放服務(wù),無(wú)法繼續(xù)播放。 |
(enum QMediaPlayer::Flag)播放標(biāo)志。
枚舉 | 描述 |
QMediaPlayer::LowLatency | 該播放器預(yù)計(jì)將用于簡(jiǎn)單的音頻格式,播放沒(méi)有明顯的延遲。 這種回放服務(wù)可以用于蜂鳴聲、鈴聲等。 |
QMediaPlayer::StreamPlayback | 該播放器預(yù)計(jì)將播放基于QIODevice的流。 如果傳遞給QMediaPlayer構(gòu)造器,將選擇支持流回放的服務(wù)。 |
QMediaPlayer::VideoSurface | 期望播放器能夠呈現(xiàn)為QAbstractVideoSurface輸出。 |
(enum QMediaPlayer::MediaStatus)定義媒體播放器當(dāng)前媒體的狀態(tài)。
枚舉 | 描述 |
QMediaPlayer::UnknownMediaStatus | 無(wú)法確定媒體的狀態(tài)。 |
QMediaPlayer::NoMedia | 沒(méi)有當(dāng)前的媒體。 播放器處于停止?fàn)顟B(tài)。 |
QMediaPlayer::LoadingMedia | 當(dāng)前媒體正在加載中。 播放器可能處于任何狀態(tài)。 |
QMediaPlayer::LoadedMedia | 已加載當(dāng)前媒體。 播放器處于停止?fàn)顟B(tài)。 |
QMediaPlayer::StalledMedia | 由于緩沖不足或其他一些臨時(shí)中斷,當(dāng)前媒體的播放已停止。 播放器處于PlayingState或PausedState |
QMediaPlayer::BufferingMedia | 播放器正在緩沖數(shù)據(jù),但緩沖了足夠的數(shù)據(jù)以供播放。 播放器處于PlayingState或PausedState。 |
QMediaPlayer::BufferedMedia | 播放器已經(jīng)完全緩沖了當(dāng)前的媒體。 播放器處于PlayingState或PausedState。 |
QMediaPlayer::EndOfMedia | 播放已經(jīng)結(jié)束。 播放器處于停止?fàn)顟B(tài)。 |
QMediaPlayer::InvalidMedia | 當(dāng)前媒體無(wú)法播放。 播放器處于停止?fàn)顟B(tài)。 |
(enum QMediaPlayer::State)媒體播放器的當(dāng)前狀態(tài)。
枚舉 | 描述 |
QMediaPlayer::StoppedState | 播放停止?fàn)顟B(tài) |
QMediaPlayer::PlayingState | 播放進(jìn)行狀態(tài) |
QMediaPlayer::PausedState | 播放暫停狀態(tài) |
QMediaPlaylist類(lèi)提供了要播放的媒體內(nèi)容列表。
QMediaPlaylist旨在與其他媒體對(duì)象一起使用,如QMediaPlayer。
QMediaPlaylist允許訪問(wèn)服務(wù)固有的播放列表功能(如果可用的話),否則它提供本地內(nèi)存播放列表實(shí)現(xiàn)。
playlist=new QMediaPlaylist;
playlist->addMedia(QUrl("http://example.com/movie1.mp4"));
playlist->addMedia(QUrl("http://example.com/movie2.mp4"));
playlist->addMedia(QUrl("http://example.com/movie3.mp4"));
playlist->setCurrentIndex(1);
?
player=new QMediaPlayer;
player->setPlaylist(playlist);
?
videoWidget=new QVideoWidget;
player->setVideoOutput(videoWidget);
videoWidget->show();
?
player->play();
根據(jù)播放列表源代碼的實(shí)現(xiàn),大多數(shù)播放列表更改操作可以是異步的。
【領(lǐng)QT開(kāi)發(fā)教程學(xué)習(xí)資料,點(diǎn)擊下方鏈接免費(fèi)領(lǐng)取↓↓,先碼住不迷路~】
點(diǎn)擊→領(lǐng)取「鏈接」
QMediaPlaylist(QObject *parent=nullptr)
virtual ~QMediaPlaylist()
bool addMedia(const QMediaContent &content)
bool addMedia(const QList<QMediaContent> &items)
bool insertMedia(int pos, const QMediaContent &content)
bool insertMedia(int pos, const QList<QMediaContent> &items)
bool removeMedia(int pos)
bool removeMedia(int start, int end)
bool clear()
bool save(const QUrl &location, const char *format=nullptr)
bool save(QIODevice *device, const char *format)
void load(const QNetworkRequest &request, const char *format=nullptr)
void load(const QUrl &location, const char *format=nullptr)
void load(QIODevice *device, const char *format=nullptr)
int currentIndex() const
QMediaContent currentMedia() const
QMediaContent media(int index) const
int nextIndex(int steps=1) const
int previousIndex(int steps=1) const
int mediaCount() const
bool moveMedia(int from, int to)
void setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
QMediaPlaylist::Error error() const
QString errorString() const
bool isEmpty() const
bool isReadOnly() const
void next()
void previous()
void setCurrentIndex(int playlistPosition)
void shuffle()
void currentIndexChanged(int position)
void currentMediaChanged(const QMediaContent &content)
void loadFailed()
void loaded()
void mediaAboutToBeInserted(int start, int end)
void mediaAboutToBeRemoved(int start, int end)
void mediaChanged(int start, int end)
void mediaInserted(int start, int end)
void mediaRemoved(int start, int end)
void playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
(enum QMediaPlaylist::Error)QMediaPlaylist錯(cuò)誤碼。
枚舉 | 描述 |
QMediaPlaylist::NoError | 沒(méi)有錯(cuò)誤 |
QMediaPlaylist::FormatError | 格式錯(cuò)誤 |
QMediaPlaylist::FormatNotSupportedError | 格式不支持 |
QMediaPlaylist::NetworkError | 網(wǎng)絡(luò)錯(cuò)誤 |
QMediaPlaylist::AccessDeniedError | 訪問(wèn)錯(cuò)誤(拒絕訪問(wèn)) |
(enum QMediaPlaylist::PlaybackMode)描述了播放列表中的播放順序。
枚舉 | 描述 |
QMediaPlaylist::CurrentItemOnce | 單曲播放一次 |
QMediaPlaylist::CurrentItemInLoop | 單曲循環(huán) |
QMediaPlaylist::Sequential | 順序播放(列表播放完結(jié)束) |
QMediaPlaylist::Loop | 列表循環(huán)(列表播放完,從頭開(kāi)始繼續(xù)播放) |
QMediaPlaylist::Random | 隨機(jī)播放 |
QMediaContent類(lèi)提供對(duì)與媒體內(nèi)容相關(guān)的資源的訪問(wèn)。
QMediaContent在多媒體框架內(nèi)用作媒體內(nèi)容的邏輯句柄。 一個(gè)QMediaContent對(duì)象包含一個(gè)QNetworkRequest,它提供了內(nèi)容的URL。
非空QMediaContent將始終具有對(duì)通過(guò)request()方法可用的內(nèi)容的引用。
另外,QMediaContent可以表示播放列表,并包含指向有效QMediaPlaylist對(duì)象的指針。 在這種情況下URL是可選的,可以是空的,也可以指向播放列表的URL。
QMediaContent(QMediaPlaylist *playlist, const QUrl &contentUrl=QUrl(), bool takeOwnership=false)
QMediaContent(const QMediaContent &other)
QMediaContent(const QNetworkRequest &request)
QMediaContent(const QUrl &url)
QMediaContent()
QMediaContent &operator=(const QMediaContent &other)
~QMediaContent()
bool isNull() const
QMediaPlaylist *playlist() const
QNetworkRequest request() const
bool operator!=(const QMediaContent &other) const
bool operator==(const QMediaContent &other) const
QMediaPlayer類(lèi)可用來(lái)播放視頻,只不過(guò)需要搭配專(zhuān)門(mén)的視頻顯示控件來(lái)使用。
void setVideoOutput(QVideoWidget *output)
void setVideoOutput(QGraphicsVideoItem *output)
//當(dāng)前媒體的視頻是否可用,如果可用,可以使用QVideoWidget類(lèi)來(lái)查看視頻。
bool isVideoAvailable() const
QVideoWidget類(lèi)提供了一個(gè)小部件,用于呈現(xiàn)由媒體對(duì)象生成的視頻。
將 QVideoWidget 附加到 QMediaObject 允許它顯示該媒體對(duì)象的視頻或圖像輸出。 QVideoWidget 通過(guò)在其構(gòu)造函數(shù)中傳遞指向 QMediaObject 的指針附加到媒體對(duì)象,并通過(guò)銷(xiāo)毀 QVideoWidget 來(lái)分離。
player=new QMediaPlayer;
?
playlist=new QMediaPlaylist(player);
playlist->addMedia(QUrl("http://example.com/myclip1.mp4"));
playlist->addMedia(QUrl("http://example.com/myclip2.mp4"));
?
videoWidget=new QVideoWidget;
player->setVideoOutput(videoWidget);
?
videoWidget->show();
playlist->setCurrentIndex(1);
player->play();
注意:一次只能將一個(gè)顯示輸出附加到媒體對(duì)象。
QVideoWidget(QWidget *parent=nullptr)
virtual ~QVideoWidget()
Qt::AspectRatioMode aspectRatioMode() const
int brightness() const //亮度
int contrast() const //對(duì)比度
int hue() const //色調(diào)
bool isFullScreen() const //是否全屏
int saturation() const //飽和度
//設(shè)置視頻縮放時(shí),寬度和高度的變化模式
void setAspectRatioMode(Qt::AspectRatioMode mode)
//調(diào)整顯示視頻的亮度。有效亮度值范圍在 -100 到 100 之間,默認(rèn)值為 0。
void setBrightness(int brightness)
//調(diào)整顯示的視頻的對(duì)比度。有效對(duì)比度值范圍在-100到100之間,默認(rèn)值為0。
void setContrast(int contrast)
//調(diào)整顯示視頻的色調(diào)。有效的色調(diào)值范圍在 -100 到 100 之間,默認(rèn)值為 0。
void setHue(int hue)
//調(diào)整顯示視頻的飽和度。 有效的飽和度值范圍在-100到100之間,默認(rèn)值是0。
void setSaturation(int saturation)
//設(shè)置窗口全屏顯示
void setFullScreen(bool fullScreen)
//亮度改變
void brightnessChanged(int brightness)
//對(duì)比度改變
void contrastChanged(int contrast)
//是否全屏狀態(tài)改變
void fullScreenChanged(bool fullScreen)
//飽和度改變
void saturationChanged(int saturation)
//色調(diào)改變
void hueChanged(int hue)
https://www.cnblogs.com/lxuechao/p/12677357.html
QCameraInfo 類(lèi)提供有關(guān)相機(jī)設(shè)備的一般信息。
QCameraInfo 允許您查詢(xún)系統(tǒng)上當(dāng)前可用的相機(jī)設(shè)備。
靜態(tài)函數(shù) defaultCamera() 和 availableCameras() 為您提供所有可用相機(jī)的列表。
此示例打印所有可用相機(jī)的名稱(chēng):
const QList<QCameraInfo> cameras=QCameraInfo::availableCameras();
for (const QCameraInfo &cameraInfo : cameras)
qDebug() << cameraInfo.deviceName();
一個(gè)QCameraInfo可以用來(lái)構(gòu)造一個(gè)QCamera。 下面的例子實(shí)例化所有可用相機(jī)設(shè)備中第一個(gè)相機(jī)設(shè)備QCamera:
const QList<QCameraInfo> cameras=QCameraInfo::availableCameras();
camera=new QCamera(cameras.first());
你也可以使用QCameraInfo來(lái)獲得一個(gè)相機(jī)設(shè)備的一般信息,例如描述,在系統(tǒng)上的物理位置,或相機(jī)傳感器的方向。
QCamera myCamera;
QCameraInfo cameraInfo(myCamera);
?
if (cameraInfo.position()==QCamera::FrontFace)
qDebug() << "攝像頭位于硬件系統(tǒng)的正面。";
else if (cameraInfo.position()==QCamera::BackFace)
qDebug() << "攝像頭位于硬件系統(tǒng)的背面。";
?
qDebug() << "相機(jī)傳感器方向是 " << cameraInfo.orientation() << " 度.";
QCamera類(lèi)為系統(tǒng)攝像機(jī)設(shè)備提供接口。
QCamera可以與QCameraViewfinder一起使用,用于取景器顯示,QMediaRecorder用于視頻錄制,QCameraImageCapture用于圖像拍攝。
你可以使用QCameraInfo列出可用的相機(jī)并選擇使用哪一個(gè)。
QCamera::CaptureModes captureMode() const
void setCaptureMode(QCamera::CaptureModes mode)
void setViewfinder(QVideoWidget *viewfinder)
void setViewfinder(QGraphicsVideoItem *viewfinder)
捕獲模式
枚舉 | 描述 |
QCamera::CaptureViewfinder | 取景器模式,只是簡(jiǎn)單的顯示 |
QCamera::CaptureStillImage | 幀捕獲模式,比如:拍照 |
QCamera::CaptureVideo | 視頻捕獲模式,比如:錄制視頻 |
者:Mino
原因:html代碼下載到WebView后,webkit開(kāi)始解析網(wǎng)頁(yè)各個(gè)節(jié)點(diǎn),發(fā)現(xiàn)有外部樣式文件或者外部腳本文件時(shí),會(huì)異步發(fā)起網(wǎng)絡(luò)請(qǐng)求下載文件,但如果在這之前也有解析到image節(jié)點(diǎn),那勢(shì)必也會(huì)發(fā)起網(wǎng)絡(luò)請(qǐng)求下載相應(yīng)的圖片。在網(wǎng)絡(luò)情況較差的情況下,過(guò)多的網(wǎng)絡(luò)請(qǐng)求就會(huì)造成帶寬緊張,影響到css或js文件加載完成的時(shí)間,造成頁(yè)面空白loading過(guò)久。
解決方法:告訴WebView先不要自動(dòng)加載圖片,等頁(yè)面finish后再發(fā)起圖片加載。
//設(shè)置是否開(kāi)啟密碼保存功能,不建議開(kāi)啟,默認(rèn)已經(jīng)做了處理,存在盜取密碼的危險(xiǎn)
WebView.setSavePassword(false);
原因:4.0以上的系統(tǒng)我們開(kāi)啟硬件加速后,WebView渲染頁(yè)面更加快速,拖動(dòng)也更加順滑。但有個(gè)副作用就是,當(dāng)WebView視圖被整體遮住一塊,然后突然恢復(fù)時(shí)(比如使用SlideMenu將WebView從側(cè)邊滑出來(lái)時(shí)),這個(gè)過(guò)渡期會(huì)出現(xiàn)白塊同時(shí)界面閃爍。
解決方法:是在過(guò)渡期前將WebView的硬件加速臨時(shí)關(guān)閉,過(guò)渡期后再開(kāi)啟。
/**
* 請(qǐng)求網(wǎng)絡(luò)出現(xiàn)error
* @param view view
* @param errorCode 錯(cuò)誤
* @param description description
* @param failingUrl 失敗鏈接
*/
@Override
public void onReceivedError(WebView view, int errorCode, String description, String
failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if (errorCode==404) {
//用javascript隱藏系統(tǒng)定義的404頁(yè)面信息
String data="Page NO FOUND!";
view.loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
} else {
if (webListener!=null){
webListener.showErrorView();
}
}
}
// 向主機(jī)應(yīng)用程序報(bào)告Web資源加載錯(cuò)誤。這些錯(cuò)誤通常表明無(wú)法連接到服務(wù)器。
// 值得注意的是,不同的是過(guò)時(shí)的版本的回調(diào),新的版本將被稱(chēng)為任何資源(iframe,圖像等)
// 不僅為主頁(yè)。因此,建議在回調(diào)過(guò)程中執(zhí)行最低要求的工作。
// 6.0 之后
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.M) {
X5WebUtils.log("服務(wù)器異常"+error.getDescription().toString());
}
//ToastUtils.showToast("服務(wù)器異常6.0之后");
//當(dāng)加載錯(cuò)誤時(shí),就讓它加載本地錯(cuò)誤網(wǎng)頁(yè)文件
//mWebView.loadUrl("file:///android_asset/errorpage/error.html");
if (webListener!=null){
webListener.showErrorView();
}
}
/**
* 這個(gè)方法主要是監(jiān)聽(tīng)標(biāo)題變化操作的
* @param view view
* @param title 標(biāo)題
*/
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
if (title.contains("404") || title.contains("網(wǎng)頁(yè)無(wú)法打開(kāi)")){
if (webListener!=null){
webListener.showErrorView();
}
} else {
// 設(shè)置title
}
}
原因:WebView.loadUrl("url") 不會(huì)立馬就回調(diào) onPageStarted 或者 onProgressChanged 因?yàn)樵谶@一時(shí)間段,WebView 有可能在初始化內(nèi)核,也有可能在與服務(wù)器建立連接,這個(gè)時(shí)間段容易出現(xiàn)白屏,白屏用戶(hù)體驗(yàn)是很糟糕的。
解決方法:提前顯示進(jìn)度條雖然不是提升性能 , 但是對(duì)用戶(hù)體驗(yàn)來(lái)說(shuō)也是很重要的一點(diǎn)。
/**
* 在加載資源時(shí)通知主機(jī)應(yīng)用程序發(fā)生SSL錯(cuò)誤
* 作用:處理https請(qǐng)求
* @param view view
* @param handler handler
* @param error error
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
if (error!=null){
String url=error.getUrl();
}
//https忽略證書(shū)問(wèn)題
if (handler!=null){
//表示等待證書(shū)響應(yīng)
handler.proceed();
// handler.cancel(); //表示掛起連接,為默認(rèn)方式
// handler.handleMessage(null); //可做其他處理
}
}
原因:WebView 默認(rèn)開(kāi)啟密碼保存功能 mWebView.setSavePassword(true),如果該功能未關(guān)閉,在用戶(hù)輸入密碼時(shí),會(huì)彈出提示框,詢(xún)問(wèn)用戶(hù)是否保存密碼,如果選擇”是”,密碼會(huì)被明文保到 /data/data/com.package.name/databases/webview.db 中,這樣就有被盜取密碼的危險(xiǎn)。
解決方法:通過(guò) WebSettings.setSavePassword(false) 關(guān)閉密碼保存提醒功能。
@Override
protected void onDestroy() {
try {
//有音頻播放的web頁(yè)面的銷(xiāo)毀邏輯
//在關(guān)閉了Activity時(shí),如果Webview的音樂(lè)或視頻,還在播放。就必須銷(xiāo)毀Webview
//但是注意:webview調(diào)用destory時(shí),webview仍綁定在Activity上
//這是由于自定義webview構(gòu)建時(shí)傳入了該Activity的context對(duì)象
//因此需要先從父容器中移除webview,然后再銷(xiāo)毀webview:
if (webView !=null) {
ViewGroup parent=(ViewGroup) webView.getParent();
if (parent !=null) {
parent.removeView(webView);
}
webView.removeAllViews();
webView.destroy();
webView=null;
}
} catch (Exception e) {
}
super.onDestroy();
}
原因:當(dāng)WebView加載頁(yè)面出錯(cuò)時(shí)(一般為404 NOT FOUND,Android WebView會(huì)默認(rèn)顯示一個(gè)出錯(cuò)界面。當(dāng)WebView加載出錯(cuò)時(shí),會(huì)在WebViewClient實(shí)例中的onReceivedError(),還有onReceivedTitle方法接收到錯(cuò)誤。
解決方法:自定義錯(cuò)誤頁(yè)面樣式。
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
String host=Uri.parse(url).getHost();
if (!BuildConfig.IS_DEBUG) {
if (Arrays.binarySearch(domainList, host) < 0) {
//不在白名單內(nèi),非法網(wǎng)址,這個(gè)時(shí)候給用戶(hù)強(qiáng)烈而明顯的提示
} else {
//合法網(wǎng)址
}
}
}
原因:webView加載一些別人的url時(shí)候,有時(shí)候會(huì)發(fā)生證書(shū)認(rèn)證錯(cuò)誤的情況。
解決方法:要將正常的呈現(xiàn)頁(yè)面給用戶(hù),我們需要忽略證書(shū)錯(cuò)誤,需要調(diào)用WebViewClient類(lèi)的onReceivedSslError方法,調(diào)用handler.proceed()來(lái)忽略該證書(shū)錯(cuò)誤。
//在onResume里面設(shè)置setJavaScriptEnabled(true)。
@Override
protected void onResume() {
super.onResume();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(true);
}
}
//在onStop里面設(shè)置setJavaScriptEnabled(false);
@Override
protected void onStop() {
super.onStop();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(false)
}
}
原因:WebView頁(yè)面中播放了音頻,退出Activity后音頻仍然在播放。
解決方法:需要在Activity的onDestory()中從父容器中移除WebView。
@Override
protected void onDestroy() {
try {
//有音頻播放的web頁(yè)面的銷(xiāo)毀邏輯
//在關(guān)閉了Activity時(shí),如果Webview的音樂(lè)或視頻,還在播放。就必須銷(xiāo)毀Webview
//但是注意:webview調(diào)用destory時(shí),webview仍綁定在Activity上
//這是由于自定義webview構(gòu)建時(shí)傳入了該Activity的context對(duì)象
//因此需要先從父容器中移除webview,然后再銷(xiāo)毀webview:
if (webView !=null) {
ViewGroup parent=(ViewGroup) webView.getParent();
if (parent !=null) {
parent.removeView(webView);
}
webView.removeAllViews();
webView.destroy();
webView=null;
}
} catch (Exception e) {
}
super.onDestroy();
}
原因:客戶(hù)端內(nèi)的WebView都是可以通過(guò)客戶(hù)端的某個(gè)schema打開(kāi)的,而要打開(kāi)頁(yè)面的URL很多都并不寫(xiě)在客戶(hù)端內(nèi),而是可以由URL中的參數(shù)傳遞過(guò)去的。上面4.0.5 使用scheme協(xié)議打開(kāi)鏈接風(fēng)險(xiǎn)已經(jīng)說(shuō)明了scheme使用的危險(xiǎn)性。
解決方法:設(shè)置運(yùn)行訪問(wèn)的白名單,或者當(dāng)用戶(hù)打開(kāi)外部鏈接前給用戶(hù)強(qiáng)烈而明顯的提示。設(shè)置白名單操作其實(shí)和過(guò)濾廣告是一個(gè)意思,這里你可以放一些合法的網(wǎng)址允許訪問(wèn)。
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
String host=Uri.parse(url).getHost();
if (!BuildConfig.IS_DEBUG) {
if (Arrays.binarySearch(domainList, host) < 0) {
//不在白名單內(nèi),非法網(wǎng)址,這個(gè)時(shí)候給用戶(hù)強(qiáng)烈而明顯的提示
} else {
//合法網(wǎng)址
}
}
}
原因:有些手機(jī)你如果webView加載的html里,有一些js一直在執(zhí)行比如動(dòng)畫(huà)之類(lèi)的東西,如果此刻webView 掛在了后臺(tái)這些資源是不會(huì)被釋放用戶(hù)也無(wú)法感知。導(dǎo)致一直占有cpu 耗電特別快。
解決方法:WebView在后臺(tái)的時(shí)候,會(huì)調(diào)用onStop方法,即此時(shí)關(guān)閉js交互,回到前臺(tái)調(diào)用onResume再開(kāi)啟js交互。
//在onResume里面設(shè)置setJavaScriptEnabled(true)。
@Override
protected void onResume() {
super.onResume();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(true);
}
}
//在onStop里面設(shè)置setJavaScriptEnabled(false);
@Override
protected void onStop() {
super.onStop();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(false)
}
}
原因:WebView從Lollipop(5.0)開(kāi)始webView默認(rèn)不允許混合模式, https當(dāng)中不能加載http資源, 而開(kāi)發(fā)的時(shí)候可能使用的是https的鏈接,但是鏈接中的圖片可能是http的,所以顯示圖片失敗。
解決方案:需要設(shè)置開(kāi)啟。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。