您的位置 首页 > 德语词汇

codec是什么意思?WebRTC本地选择codec

大家好,今天来为大家解答codec是什么意思这个问题的一些问题点,包括WebRTC本地选择codec也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~

codec:编码译码器,编解码器。它是一个程序,也可以是算法,或者设备,用于编码(encode)和解码(decode)数据流。

codec是什么意思?WebRTC本地选择codec

WebRTC能让两个web或者app之间建立音视频通信。通信过程中,数据流的格式必须被两边的设备支持。

WebRTC提供了接口查询支持的codec,并且可以设置要使用的codec。本文演示选择视频codec的过程。示例

用户可以在发送视频流之前选择codec。把支持的codec类型列出来,用户自行选择。

开启视频后,建立连接前,我们可以选择设置codec。如上图蓝色区域所示。

先来准备页面。2个video控件分别显示收发视频。按钮分别控制开始,呼叫(发起连接)和挂断。

select用来选择codec。获取支持的codec信息,放到下拉栏里让用户选择。

以下是index.html主要内容

<divid="container">\n<h1><ahref="https://an.rustfisher.com/webrtc/peerconnection/change-codec/"title="WebRTC示例,修改codec">WebRTC示例,修改codec</a>\n</h1>\n\n<videoid="localVideo"playsinlineautoplaymuted></video>\n<videoid="remoteVideo"playsinlineautoplay></video>\n\n<divclass="box">\n<buttonid="startBtn">开始</button>\n<buttonid="callBtn">呼叫</button>\n<buttonid="hangupBtn">挂断</button>\n</div>\n\n<divclass="box">\n<span>选择Codec:</span>\n<selectid="codecPreferences"disabled>\n<optionselectedvalue="">Default</option>\n</select>\n<divid="actualCodec"></div>\n</div>\n<p>可以在控制台观察<code>MediaStream</code>,<code>localStream</code>,和<code>RTCPeerConnection</code></p>\n</div>\n\n<scriptsrc="../../src/js/adapter-2021.js"></script>\n<scriptsrc="js/main.js"async></script>

adapter-2021.js是存放在本地的文件。要使用最新的adapter,按以下地址引入

<scriptsrc="https://webrtc.github.io/adapter/adapter-latest.js"></script>

js

main.js控制主要逻辑。从开启摄像头开始。建立连接前可以选择codec。

建立连接的流程与「WebRTC模拟传输视频流,video通过本地节点peer传输视频流」类似。

先判断浏览器是否有RTCRtpTransceiver,并且要能支持setCodecPreferences方法

constsupportsSetCodecPreferences=window.RTCRtpTransceiver&&\n'setCodecPreferences'inwindow.RTCRtpTransceiver.prototype;

通过RTCRtpSender.getCapabilities('video')获取可支持的codec。然后把它们放进列表codecPreferences里

if(supportsSetCodecPreferences){\nconst{codecs}=RTCRtpSender.getCapabilities('video');\n\ncodecs.forEach(codec=>{\nif(['video/red','video/ulpfec','video/rtx'].includes(codec.mimeType)){\nreturn;\n}\nconstoption=document.createElement('option');\noption.value=(codec.mimeType+''+(codec.sdpFmtpLine||'')).trim();\noption.innerText=option.value;\ncodecPreferences.appendChild(option);\n});\ncodecPreferences.disabled=false;\n}

相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】

音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpegwebRTCrtmphlsrtspffplaysrs等等)有需要的可以点击788280672加群免费领取~

呼叫之前,找到用户选择的codec。调用transceiver.setCodecPreferences(codecs),把选中的codec交给transceiver。

if(supportsSetCodecPreferences){\n//获取选择的codec\nconstpreferredCodec=codecPreferences.options[codecPreferences.selectedIndex];\nif(preferredCodec.value!==''){\nconst[mimeType,sdpFmtpLine]=preferredCodec.value.split('');\nconst{codecs}=RTCRtpSender.getCapabilities('video');\nconstselectedCodecIndex=codecs.findIndex(c=>c.mimeType===mimeType&&c.sdpFmtpLine===sdpFmtpLine);\nconstselectedCodec=codecs[selectedCodecIndex];\ncodecs.splice(selectedCodecIndex,1);\ncodecs.unshift(selectedCodec);\nconsole.log(codecs);\nconsttransceiver=pc1.getTransceivers().find(t=>t.sender&&t.sender.track===localStream.getVideoTracks()[0]);\ntransceiver.setCodecPreferences(codecs);\nconsole.log('选择的codec',selectedCodec);\n}\n}

main.js完整代码如下

'usestrict';\n\nconsole.log('WebRTC示例,选择codec');\n\n//---------ui准备---------\nconststartBtn=document.getElementById('startBtn');\nconstcallBtn=document.getElementById('callBtn');\nconsthangupBtn=document.getElementById('hangupBtn');\nconstlocalVideo=document.getElementById('localVideo');\nconstremoteVideo=document.getElementById('remoteVideo');\n\ncallBtn.disabled=true;\nhangupBtn.disabled=true;\nstartBtn.addEventListener('click',start);\ncallBtn.addEventListener('click',call);\nhangupBtn.addEventListener('click',hangup);\n//---------------------------\n\n//--------codec的配置--------\nconstcodecPreferences=document.querySelector('#codecPreferences');\nconstsupportsSetCodecPreferences=window.RTCRtpTransceiver&&\n'setCodecPreferences'inwindow.RTCRtpTransceiver.prototype;\n//-----------------------------\n\nletstartTime;\n\nremoteVideo.addEventListener('resize',()=>{\nconsole.log(`Remotevideosizechangedto${remoteVideo.videoWidth}x${remoteVideo.videoHeight}`);\nif(startTime){\nconstelapsedTime=window.performance.now()-startTime;\nconsole.log('视频流连接耗时:'+elapsedTime.toFixed(3)+'ms');\nstartTime=null;\n}\n});\n\nletlocalStream;\nletpc1;\nletpc2;\nconstofferOptions={\nofferToReceiveAudio:1,\nofferToReceiveVideo:1\n};\n\nfunctiongetName(pc){\nreturn(pc===pc1)?'pc1':'pc2';\n}\n\nfunctiongetOtherPc(pc){\nreturn(pc===pc1)?pc2:pc1;\n}\n\n//启动本地视频\nasyncfunctionstart(){\nconsole.log('启动本地视频');\nstartBtn.disabled=true;\ntry{\nconststream=awaitnavigator.mediaDevices.getUserMedia({audio:true,video:true});\nconsole.log('获取到本地视频');\nlocalVideo.srcObject=stream;\nlocalStream=stream;\ncallBtn.disabled=false;\n}catch(e){\nalert(`getUserMedia()error:${e.name}`);\n}\nif(supportsSetCodecPreferences){\nconst{codecs}=RTCRtpSender.getCapabilities('video');\nconsole.log('RTCRtpSender.getCapabilities(video):\\n',codecs);\ncodecs.forEach(codec=>{\nif(['video/red','video/ulpfec','video/rtx'].includes(codec.mimeType)){\nreturn;\n}\nconstoption=document.createElement('option');\noption.value=(codec.mimeType+''+(codec.sdpFmtpLine||'')).trim();\noption.innerText=option.value;\ncodecPreferences.appendChild(option);\n});\ncodecPreferences.disabled=false;\n}else{\nconsole.warn('当前不支持更换codec');\n}\n}\n\n//呼叫并建立连接\nasyncfunctioncall(){\ncallBtn.disabled=true;\nhangupBtn.disabled=false;\nconsole.log('开始呼叫');\nstartTime=window.performance.now();\nconstvideoTracks=localStream.getVideoTracks();\nconstaudioTracks=localStream.getAudioTracks();\nif(videoTracks.length>0){\nconsole.log(`使用的摄像头:${videoTracks[0].label}`);\n}\nif(audioTracks.length>0){\nconsole.log(`使用的麦克风:${audioTracks[0].label}`);\n}\nconstconfiguration={};\npc1=newRTCPeerConnection(configuration);\npc1.addEventListener('icecandidate',e=>onIceCandidate(pc1,e));\npc2=newRTCPeerConnection(configuration);\npc2.addEventListener('icecandidate',e=>onIceCandidate(pc2,e));\npc2.addEventListener('track',gotRemoteStream);\n\nlocalStream.getTracks().forEach(track=>pc1.addTrack(track,localStream));\nif(supportsSetCodecPreferences){\n//获取选择的codec\nconstpreferredCodec=codecPreferences.options[codecPreferences.selectedIndex];\nif(preferredCodec.value!==''){\nconst[mimeType,sdpFmtpLine]=preferredCodec.value.split('');\nconst{codecs}=RTCRtpSender.getCapabilities('video');\nconstselectedCodecIndex=codecs.findIndex(c=>c.mimeType===mimeType&&c.sdpFmtpLine===sdpFmtpLine);\nconstselectedCodec=codecs[selectedCodecIndex];\ncodecs.splice(selectedCodecIndex,1);\ncodecs.unshift(selectedCodec);\nconsole.log(codecs);\nconsttransceiver=pc1.getTransceivers().find(t=>t.sender&&t.sender.track===localStream.getVideoTracks()[0]);\ntransceiver.setCodecPreferences(codecs);\nconsole.log('选择的codec',selectedCodec);\n}\n}\ncodecPreferences.disabled=true;\n\ntry{\nconstoffer=awaitpc1.createOffer(offerOptions);\nawaitonCreateOfferSuccess(offer);\n}catch(e){\nconsole.log(`Failed,pc1createOffer:${e.toString()}`);\n}\n}\n\nasyncfunctiononCreateOfferSuccess(desc){\ntry{\nawaitpc1.setLocalDescription(desc);\nconsole.log('pc1setLocalDescription成功');\n}catch(e){\nconsole.error('pc1setLocalDescription出错',e);\n}\ntry{\nawaitpc2.setRemoteDescription(desc);\nconsole.log('pc2setRemoteDescriptionok');\n}catch(e){\nconsole.error('pc2setRemoteDescriptionfail',e);\n}\ntry{\nconstanswer=awaitpc2.createAnswer();\nawaitonCreateAnswerSuccess(answer);\n}catch(e){\nconsole.log(`pc2createanswerfail:${e.toString()}`);\n}\n}\n\nfunctiongotRemoteStream(e){\nif(remoteVideo.srcObject!==e.streams[0]){\nremoteVideo.srcObject=e.streams[0];\nconsole.log('pc2receivedremotestream');\n}\n}\n\n//应答(接收)成功\nasyncfunctiononCreateAnswerSuccess(desc){\nconsole.log(`Answerfrompc2:\\n${desc.sdp}`);\nconsole.log('pc2setLocalDescriptionstart');\ntry{\nawaitpc2.setLocalDescription(desc);\n}catch(e){\nconsole.error('pc2setlocaldfail',e);\n}\nconsole.log('pc1setRemoteDescriptionstart');\ntry{\nawaitpc1.setRemoteDescription(desc);\n\n//Displaythevideocodecthatisactuallyused.\nsetTimeout(async()=>{\nconststats=awaitpc1.getStats();\nstats.forEach(stat=>{\nif(!(stat.type==='outbound-rtp'&&stat.kind==='video')){\nreturn;\n}\nconstcodec=stats.get(stat.codecId);\ndocument.getElementById('actualCodec').innerText='Using'+codec.mimeType+\n''+(codec.sdpFmtpLine?codec.sdpFmtpLine+'':'')+\n',payloadType='+codec.payloadType+'.Encoder:'+stat.encoderImplementation;\n});\n},1000);\n}catch(e){\nconsole.error(e);\n}\n}\n\nasyncfunctiononIceCandidate(pc,event){\ntry{\nawait(getOtherPc(pc).addIceCandidate(event.candidate));\nonAddIceCandidateSuccess(pc);\n}catch(e){\nonAddIceCandidateError(pc,e);\n}\nconsole.log(`${getName(pc)}ICEcandidate:\\n${event.candidate?event.candidate.candidate:'(null)'}`);\n}\n\nfunctiononAddIceCandidateSuccess(pc){\nconsole.log(`${getName(pc)}addIceCandidatesuccess`);\n}\n\nfunctiononAddIceCandidateError(pc,error){\nconsole.log(`${getName(pc)}failedtoaddICECandidate:${error.toString()}`);\n}\n\nlocalVideo.addEventListener('loadedmetadata',function(){\nconsole.log(`LocalvideovideoWidth:${this.videoWidth}px,videoHeight:${this.videoHeight}px`);\n});\n\nremoteVideo.addEventListener('loadedmetadata',function(){\nconsole.log(`RemotevideovideoWidth:${this.videoWidth}px,videoHeight:${this.videoHeight}px`);\n});\n\n//挂断\nfunctionhangup(){\nconsole.log('挂断');\npc1.close();\npc2.close();\npc1=null;\npc2=null;\nhangupBtn.disabled=true;\ncallBtn.disabled=false;\ncodecPreferences.disabled=false;\n}codec信息说明

观察控制台,打印出了可用codec信息(Mac,97.0.4692.71(正式版本)x86_64)。主要关注下面3种

{clockRate:90000,mimeType:'video/VP8'}\n{clockRate:90000,mimeType:'video/VP9',sdpFmtpLine:'profile-id=0'}\n{clockRate:90000,mimeType:'video/H264',sdpFmtpLine:'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f'}

clockRate是codec的时钟频率,单位hzsdpFmtpLine是codec的SDP里a=fmtp的参数信息mimeType里说的是视频编码类型,常见的有VP8和H264等等支持WebRTC的浏览器,必须要支持视频codecVP8和H264VP8与VP9

2010年5月Google收购了On2Technologies,获得了VP8。Opera,FireFox,Chrome和Chromium支持HTML5中的video播放VP8视频。

WebM作为一个容器格式,图像部分使用VP8,音频使用Vorbis和Opus。

VP9由Google开发,一个开放的无版权费的视频编码标准。开发初期曾用名“NextGenOpenVideo”。VP9也被视为是VP8的下一代视频编码标准。H264

H.264,又称为MPEG-4第10部分,高级视频编码是一种面向块,基于运动补偿的视频编码标准。到2014年,它已经成为高精度视频录制、压缩和发布的最常用格式之一。

目前我们用的比较多的还是H264。

关于本次codec是什么意思和WebRTC本地选择codec的问题分享到这里就结束了,如果解决了您的问题,我们非常高兴。

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023