yy8848青蘋果影私人視院濰坊百度快速排名優(yōu)化
目錄
- 關(guān)于直播
- 直播流程
- 直播視頻格式封裝
- 推流和拉流
- 獲取攝像頭和麥克風(fēng)權(quán)限
- navigator.getUserMedia()
- MediaDevices.getUserMedia()
- WebRTC
- 騰訊云快直播
關(guān)于直播
視頻直播技術(shù)大全、直播架構(gòu)、技術(shù)原理和實(shí)現(xiàn)思路方案整理
直播流程
-
視頻采集端:
1、視頻采集:使用攝像頭設(shè)備獲取實(shí)時(shí)視頻流。
2、視頻處理: 對采集到的視頻進(jìn)行處理,可以包括美顏、濾鏡、水印等效果的添加。
3、音視頻編碼壓縮: 將處理后的音視頻數(shù)據(jù)進(jìn)行編碼壓縮,常用的編碼方式有H.264視頻編碼和AAC音頻編碼。 -
直播流視頻服務(wù)端:
1、視頻流解析編碼:接收視頻采集端傳來的音視頻數(shù)據(jù)流,進(jìn)行解析和解碼。
2、推送RTMP/HLS格式視頻流:將解碼后的音視頻數(shù)據(jù)流封裝成RTMP或HLS格式,并推送到流媒體服務(wù)器上。這些流媒體服務(wù)器會處理客戶端的連接和請求,將直播內(nèi)容分發(fā)給客戶端。 -
視頻播放端:
1、音視頻解碼:在播放端,接收到來自直播流視頻服務(wù)端的數(shù)據(jù)流,進(jìn)行解碼,得到原始的音頻和視頻數(shù)據(jù)。
2、播放+聊天互動:將解碼后的音視頻數(shù)據(jù)進(jìn)行播放,同時(shí)提供用戶界面供觀眾觀看??梢栽诓シ哦藢?shí)現(xiàn)一些互動功能,比如彈幕、點(diǎn)贊、評論等。
直播視頻格式封裝
直播視頻通常會經(jīng)過特定的封裝格式,以便在網(wǎng)絡(luò)上傳輸和播放。這些封裝格式可以將音頻、視頻、元數(shù)據(jù)等信息進(jìn)行組合和管理,以確保流暢的傳輸和播放體驗(yàn)。
FLV: 一種由Adobe公司開發(fā)的流媒體封裝格式,最初用于Flash播放器和RTMP協(xié)議傳輸。它可以容納音頻、視頻、文本和元數(shù)據(jù),并且適用于實(shí)時(shí)傳輸和播放。
TS: 一種用于傳輸多媒體內(nèi)容的封裝格式,常用于數(shù)字電視和IPTV。它可以容納多路音頻、視頻和數(shù)據(jù)流,適合實(shí)時(shí)傳輸和廣播。HLS協(xié)議中使用的就是TS格式來封裝音視頻流。
MP4: 一種通用的多媒體封裝格式,可以容納音頻、視頻、字幕和元數(shù)據(jù)。它被廣泛用于存儲和傳輸音視頻內(nèi)容,也可以用于直播。MP4格式通常使用H.264視頻編碼和AAC音頻編碼。
推流和拉流
推流(Publishing)
和拉流(Subscribing)
是在實(shí)時(shí)音視頻通信中常見的術(shù)語,用于描述音視頻數(shù)據(jù)的傳輸過程。推流指的是將本地音視頻數(shù)據(jù)發(fā)送到服務(wù)器,而拉流則是從服務(wù)器接收遠(yuǎn)程音視頻數(shù)據(jù)。
HLS 是由蘋果公司開發(fā)的一種流媒體傳輸協(xié)議,主要用于在iOS設(shè)備、Web瀏覽器和其他支持HLS的設(shè)備上實(shí)現(xiàn)實(shí)時(shí)的音視頻流播放。HLS將音視頻流切割成一系列小的媒體文件(使用 .ts 格式進(jìn)行封裝,將音視頻流分割成小的.ts文件),通過HTTP協(xié)議逐個傳輸和播放。
優(yōu)點(diǎn):
1、適用于多種設(shè)備和平臺,包括iOS、Android、Web等。
2、支持自適應(yīng)碼率,根據(jù)網(wǎng)絡(luò)狀況動態(tài)調(diào)整視頻質(zhì)量。
3、在不同帶寬下都能提供較好的流暢播放體驗(yàn)。
4、使用HTTP協(xié)議傳輸,不需要特定的服務(wù)器支持。
缺點(diǎn):
1、延遲相對較高,通常在10秒左右。
2、需要將媒體流切割成小文件,增加服務(wù)器壓力和存儲開銷。
RTMP 是Adobe公司開發(fā)的實(shí)時(shí)消息傳輸協(xié)議,基于TCP協(xié)議傳輸,最初用于Flash播放器與媒體服務(wù)器之間的音視頻傳輸。
優(yōu)點(diǎn):
1、延遲相對較低,通常在1-3秒左右,適合實(shí)時(shí)互動。
2、支持即時(shí)性的直播,適用于一些對延遲要求較高的場景。
3、在Flash播放器上有較好的兼容性。
缺點(diǎn):
1、不適用于iOS設(shè)備和某些平臺,因?yàn)椴槐粡V泛支持。
2、需要專門的RTMP服務(wù)器支持,部署和維護(hù)相對復(fù)雜。
3、需要考慮防火墻和代理等網(wǎng)絡(luò)限制。
獲取攝像頭和麥克風(fēng)權(quán)限
navigator.getUserMedia()
MDN-navigator.getUserMedia()
Navigator.getUserMedia()
方法提醒用戶需要使用音頻(0 或者 1)和(0 或者 1)視頻輸入設(shè)備,比如相機(jī),屏幕共享,或者麥克風(fēng)。
語法: navigator.getUserMedia ( constraints, successCallback, errorCallback );
代碼:
<body><video autoplay id="video" width="400" height="300"></video><script>var video = document.getElementById('video');//作兼容處理navigator.getMedia = navigator.getUserMedia ||navagator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.msGetUserMedia;navigator.getMedia({ audio: true, video: true },function (stream) {//MDN文檔案例中這樣寫會報(bào)錯:video.src = window.URL.createObjectURL(stream);video.srcObject = streamvideo.onloadedmetadata = function (e) {video.play();};},function (err) {console.log("The following error occurred: " + err.name);});</script>
</body>
雖然這個api依然可以使用,但是官網(wǎng)上已經(jīng)換了另一個api——MediaDevices.getUserMedia()
MediaDevices.getUserMedia()
MDN-MediaDevices.getUserMedia()
MediaDevices.getUserMedia()
會提示用戶給予使用媒體輸入的許可,媒體輸入會產(chǎn)生一個MediaStream,里面包含了請求的媒體類型的軌道。此流可以包含一個視頻軌道(來自硬件或者虛擬視頻源,比如相機(jī)、視頻采集設(shè)備和屏幕共享服務(wù)等等)、一個音頻軌道(同樣來自硬件或虛擬音頻源,比如麥克風(fēng)、A/D 轉(zhuǎn)換器等等),也可能是其他軌道類型。
語法:
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { /* 使用這個 stream stream */ }).catch(function (err) { /* 處理 error */});
代碼:
<video autoplay id="video" width="400" height="300"></video>
<script>var video = document.getElementById('video');navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(function (stream) {/* 使用這個 stream stream */video.srcObject = streamvideo.onloadedmetadata = function (e) {video.play();};}).catch(function (err) {/* 處理 error */console.log("The following error occurred: " + err.name);});</script>
WebRTC
MDN-WebRTC API
WebRTC
(Web Real-Time Communication)是一種支持瀏覽器之間實(shí)時(shí)通信的開放式標(biāo)準(zhǔn)和技術(shù),它使得瀏覽器可以直接在不需要插件或額外的軟件的情況下進(jìn)行音頻、視頻和數(shù)據(jù)的傳輸和通信。WebRTC 技術(shù)的核心目標(biāo)是實(shí)現(xiàn)實(shí)時(shí)的、點(diǎn)對點(diǎn)的通信,包括視頻聊天、音頻通話、數(shù)據(jù)共享等功能。
代碼:
<body><!-- 顯示本地視頻 --><h2>本地視頻</h2><video id="localVideo" autoplay playsinline style="width: 300px;"></video><!-- 顯示遠(yuǎn)程視頻 --><h2>遠(yuǎn)程視頻</h2><video id="remoteVideo" autoplay playsinline style="width: 300px;"></video><button id="startCall">發(fā)起通話</button><button id="answerCall">接聽通話</button>//呼叫者:<script>const localVideo = document.getElementById('localVideo');let localStream;// 呼叫者:獲取本地?cái)z像頭和麥克風(fēng)權(quán)限navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => {localStream = stream;localVideo.srcObject = localStream;}).catch(error => {console.error('獲取本地媒體流失敗:', error);});const startCallButton = document.getElementById('startCall');startCallButton.addEventListener('click', () => {startCall();});async function startCall() {// 呼叫者:創(chuàng)建PeerConnectionconst peerConnection = new RTCPeerConnection();// 添加本地媒體流到PeerConnectionlocalStream.getTracks().forEach(track => {peerConnection.addTrack(track, localStream);});// 呼叫者:創(chuàng)建Offer并設(shè)置本地描述peerConnection.createOffer().then(offer => peerConnection.setLocalDescription(offer)).then(() => {// 發(fā)送本地描述到遠(yuǎn)程const offerSdp = peerConnection.localDescription;// 在實(shí)際應(yīng)用中,需要將offerSdp發(fā)送給遠(yuǎn)程端// 遠(yuǎn)程端通過RTCPeerConnection.setRemoteDescription()設(shè)置遠(yuǎn)程描述}).catch(error => {console.error('創(chuàng)建Offer失敗:', error);});}</script>//被呼叫者:<script>const remoteVideo = document.getElementById('remoteVideo');let remoteStream;const answerCallButton = document.getElementById('answerCall');answerCallButton.addEventListener('click', () => {answerCall();});async function answerCall() {// 創(chuàng)建PeerConnectionconst peerConnection = new RTCPeerConnection();// 設(shè)置ontrack事件處理程序以接收遠(yuǎn)程流peerConnection.ontrack = event => {remoteStream = event.streams[0];remoteVideo.srcObject = remoteStream;};// 在實(shí)際應(yīng)用中,你需要獲取呼叫者發(fā)送的offerSdp// 并通過RTCPeerConnection.setRemoteDescription()設(shè)置遠(yuǎn)程描述// 創(chuàng)建Answer并設(shè)置本地描述const answer = await peerConnection.createAnswer();await peerConnection.setLocalDescription(answer);const answerSdp = peerConnection.localDescription;// 在實(shí)際應(yīng)用中,你需要將answerSdp發(fā)送給呼叫者// 呼叫者通過RTCPeerConnection.setRemoteDescription()設(shè)置遠(yuǎn)程描述}</script>
</body>
騰訊云快直播
騰訊云直播-WebRTC協(xié)議推流
云直播提供了推流
SDK TXLivePusher
用于 Web 推流,負(fù)責(zé)將瀏覽器采集的音視頻畫面通過 WebRTC 協(xié)議推送到直播服務(wù)器。目前支持?jǐn)z像頭采集、麥克風(fēng)采集、屏幕分享采集、本地媒體文件采集和用戶自定義采集等采集方式,支持對采集到的內(nèi)容進(jìn)行本地混流處理,然后推送到后端服務(wù)器。
1、引入初始化腳本(需要在 HTML 的 body 部分引入腳本,如果在 head 部分引入會報(bào)錯。)
<script src="https://video.sdk.qcloudecdn.com/web/TXLivePusher-2.1.0.min.js" charset="utf-8"></script>
2、創(chuàng)建視頻容器
<div id="local_video" style="width:100%;height:500px;display:flex;align-items:center;justify-content:center;"></div>
3、生成推流 SDK 實(shí)例
//通過全局對象 TXLivePusher 生成 SDK 實(shí)例,后續(xù)操作都是通過實(shí)例完成。const livePusher = new TXLivePusher();// 指定本地視頻播放器容器 div,瀏覽器采集到的音視頻畫面會渲染到這個 div 當(dāng)中。livePusher.setRenderView('local_video');// 設(shè)置音視頻流 livePusher.setVideoQuality('720p');// 設(shè)置音頻質(zhì)量livePusher.setAudioQuality('standard');// 自定義設(shè)置幀率livePusher.setProperty('setVideoFPS', 25);
4、開啟直播推流
// 開啟直播// 打開攝像頭 livePusher.startCamera();// 打開麥克風(fēng)livePusher.startMicrophone();//傳入云直播推流地址,開始推流。livePusher.startPush(推流地址);
使用騰訊云直播服務(wù)時(shí),推流地址需要滿足騰訊云標(biāo)準(zhǔn)直播推流 URL 的格式 ,如下所示,它由四個部分組成:
5、關(guān)閉直播
// 關(guān)閉直播// 停止直播推流livePusher.stopPush();// 關(guān)閉攝像頭livePusher.stopCamera();// 關(guān)閉麥克風(fēng)livePusher.stopMicrophone();
完整代碼:
<body><div id="local_video" style="width:100%;height:500px;display:flex;align-items:center;justify-content:center;"></div></div><script src="https://video.sdk.qcloudecdn.com/web/TXLivePusher-2.1.0.min.js" charset="utf-8"></script><script>//通過全局對象 TXLivePusher 生成 SDK 實(shí)例,后續(xù)操作都是通過實(shí)例完成。const livePusher = new TXLivePusher();// 指定本地視頻播放器容器 div,瀏覽器采集到的音視頻畫面會渲染到這個 div 當(dāng)中。livePusher.setRenderView('local_video');// 設(shè)置音視頻流 livePusher.setVideoQuality('720p');// 設(shè)置音頻質(zhì)量livePusher.setAudioQuality('standard');// 自定義設(shè)置幀率livePusher.setProperty('setVideoFPS', 25);// 開啟直播// 打開攝像頭 livePusher.startCamera();// 打開麥克風(fēng)livePusher.startMicrophone();//傳入云直播推流地址,開始推流。livePusher.startPush(推流地址);// 關(guān)閉直播// 停止直播推流livePusher.stopPush();// 關(guān)閉攝像頭livePusher.stopCamera();// 關(guān)閉麥克風(fēng)livePusher.stopMicrophone();</script>
</body>
如有誤,請指正!