Qt 之播放m3u8视频流
文章目錄
- 前言
- 一、m3u8是什么?
- m3u8 文件格式詳解
- 簡介
- M3U8 文件簡介
- 二、qt 如何播放?
- 1.播放流程
前言
項目中,需要播放視頻,拿到的數據是一個m3u8結尾的http鏈接,比如http://charge.zzzz.cc//fudao_79d049cdbe22116dd19bdc1bad150b90.m3u8?,然后本以為直接調用QMediaPlayer的接口即可,如下
player = new QMediaPlayer; connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3")); player->setVolume(50); player->play();或者qml:
MediaPlayer {id: player; }function startPlay(url) {player.source = url;player.videoPlayClicked = true;player.start(); }卻發現,針對m3u8這種url,不能直接播放,然后就研究了下什么是m3u8.
一、m3u8是什么?
m3u8 文件格式詳解
簡介
M3U8 是 Unicode 版本的 M3U,用 UTF-8 編碼。“M3U” 和 “M3U8” 文件都是蘋果公司使用的 HTTP Live Streaming(HLS) 協議格式的基礎,這種協議格式可以在 iPhone 和 Macbook 等設備播放。
上述文字定義來自于維基百科。可以看到,m3u8 文件其實是 HTTP Live Streaming(縮寫為 HLS) 協議的部分內容,而 HLS 是一個由蘋果公司提出的基于 HTTP 的流媒體網絡傳輸協議。
HLS 的工作原理是把整個流分成一個個小的基于 HTTP 的文件來下載,每次只下載一些。當媒體流正在播放時,客戶端可以選擇從許多不同的備用源中以不同的速率下載同樣的資源,允許流媒體會話適應不同的數據速率。在開始一個流媒體會話時,客戶端會下載一個包含元數據的 extended M3U (m3u8) playlist文件,用于尋找可用的媒體流。
HLS 只請求基本的 HTTP 報文,與實時傳輸協議(RTP)不同,HLS 可以穿過任何允許 HTTP 數據通過的防火墻或者代理服務器。它也很容易使用內容分發網絡來傳輸媒體流。
簡而言之,HLS 是新一代流媒體傳輸協議,其基本實現原理為將一個大的媒體文件進行分片,將該分片文件資源路徑記錄于 m3u8 文件(即 playlist)內,其中附帶一些額外描述(比如該資源的多帶寬信息···)用于提供給客戶端。客戶端依據該 m3u8 文件即可獲取對應的媒體資源,進行播放。
因此,客戶端獲取 HLS 流文件,主要就是對 m3u8 文件進行解析操作。
那么,下面就簡單介紹下 m3u8 文件。
M3U8 文件簡介
m3u8 文件實質是一個播放列表(playlist),其可能是一個媒體播放列表(Media Playlist),或者是一個主列表(Master Playlist)。但無論是哪種播放列表,其內部文字使用的都是 utf-8 編碼。
當 m3u8 文件作為媒體播放列表(Meida Playlist)時,其內部信息記錄的是一系列媒體片段資源,順序播放該片段資源,即可完整展示多媒體資源。其格式如下所示:
#EXTM3U #EXT-X-TARGETDURATION:10#EXTINF:9.009, http://media.example.com/first.ts #EXTINF:9.009, http://media.example.com/second.ts #EXTINF:3.003, http://media.example.com/third.ts對于點播來說,客戶端只需按順序下載上述片段資源,依次進行播放即可。而對于直播來說,客戶端需要 定時重新請求 該 m3u8 文件,看下是否有新的片段數據需要進行下載并播放。
當 m3u8 作為主播放列表(Master Playlist)時,其內部提供的是同一份媒體資源的多份流列表資源(Variant Stream)。其格式如下所示:
#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=150000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2" http://example.com/low/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=240000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2" http://example.com/lo_mid/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=440000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2" http://example.com/hi_mid/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=640000,RESOLUTION=640x360,CODECS="avc1.42e00a,mp4a.40.2" http://example.com/high/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.5" http://example.com/audio/index.m3u8該備用流資源指定了多種不同碼率,不同格式的媒體播放列表,并且,該備用流資源也可同時提供不同版本的資源內容,比如不同語言的音頻文件,不同角度拍攝的視屏文件等等。客戶可以根據不同的網絡狀態選取合適碼流的資源,并且最好根據用戶喜好選擇合適的資源內容。
以上,就是 m3u8 文件的大概內容
二、qt 如何播放?
1.播放流程
http://charge.zzzz.cc//fudao_79d049cdbe22116dd19bdc1bad150b90.m3u8?
fudao_79d049cdbe22116dd19bdc1bad150b90.m3u8
核心代碼如下(下載):
void M3u8DownloadManager::startDownLoad(const QByteArray &url) {QUrl surl = QUrl::fromEncoded(url);revData.clear();filename = getFileName(surl); //根據url獲得文件名 字符串解析if(QFile::exists(DevConfig::GetInstance()->getTempM3u8Dir() + filename)){qDebug() << "exists" << filename;emit getU3m8(DevConfig::GetInstance()->getTempM3u8Dir() + filename);return;}int linkpos = surl.toString().indexOf("&c=");QString link = surl.toString().mid(linkpos+3);QString urlDecode = QUrl::fromPercentEncoding(link.toLocal8Bit());QUrl linkUrl = QUrl(urlDecode);QNetworkRequest request(linkUrl);currentDownload = pManager->get(request);connect(currentDownload, SIGNAL(finished()),SLOT(downloadFinished()));connect(currentDownload, SIGNAL(readyRead()),SLOT(downloadReadyRead()));}保存下載文件
void M3u8DownloadManager::downloadFinished() {int datalen = revData.length();qDebug() << filename << datalen /*<< revData*/;QFile output;output.setFileName(DevConfig::GetInstance()->getTempM3u8Dir() + filename);if (!output.open(QIODevice::ReadWrite | QIODevice::Truncate)) {qDebug() <<"open file error" << output.errorString()<< output.fileName();return; // skip this download}output.write(revData,val);output.close();emit getU3m8(DevConfig::GetInstance()->getTempM3u8Dir() + filename);currentDownload->deleteLater(); }接受下載完信號,然后播放器播放
Connections{target: dataManageronGetU3m8:{player.source = "file:///"+ m3u8;player.videoPlayClicked = true;player.start();}}總結
以上是生活随笔為你收集整理的Qt 之播放m3u8视频流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 秒杀项目(1)项目环境搭建
- 下一篇: garageband for mac下载