在WebRTC中,如何标记本地媒体流,以便远程对等方能够识别它?

在WebRTC中,如何标记本地媒体流,以便远程对等方能够识别它?,webrtc,mediastream,Webrtc,Mediastream,我正在构建一个WebRTC应用程序,用户可以在其中共享他们的相机和屏幕。 当客户端接收到流/曲目时,它需要知道它是摄像机流还是屏幕记录流。 这种区别在发送端很明显, 但是,当轨迹到达接收点时,这种区别就消失了 下面是我的应用程序中的一些示例代码: //注意,流之间的区别在发送端很明显。 const localWebcamStream=await navigator.mediaDevices.getUserMedia({…}); const screenpapturestream=wait nav

我正在构建一个WebRTC应用程序,用户可以在其中共享他们的相机和屏幕。 当客户端接收到流/曲目时,它需要知道它是摄像机流还是屏幕记录流。 这种区别在发送端很明显, 但是,当轨迹到达接收点时,这种区别就消失了

下面是我的应用程序中的一些示例代码:

//注意,流之间的区别在发送端很明显。
const localWebcamStream=await navigator.mediaDevices.getUserMedia({…});
const screenpapturestream=wait navigator.mediaedevices.getDisplayMedia({…});
//这称为信令逻辑
函数addLocalTrackStopeeConn(peerConn){
//我们这里的方法会丢失信息,因为我们的两条不同的流
//添加到PeerConnection的同质流包中
for(screenCaptureStream.getTracks()的常量轨迹){
peerConn.addTrack(track,屏幕捕获流);
}
for(localWebcamStream.getTracks()的常量跟踪){
addTrack(track,localWebcamStream);
}
}
//这称为信令逻辑
函数句柄remoteracksfromPeerConn(peerConn){
peerConn.ontrack=ev=>{
恒定流=电动流[0];
如果(流是摄影机流){//FIXME如何可靠地进行区分?
remoteWebcamVideoEl.srcObject=流;
}
否则如果(流是一个屏幕截图){//FIXME如何可靠地区分?
remoteScreenCaptureVideoEl.srcObject=流;
}
};
}
我理想的想象API将允许向曲目或流添加
.label
,如下所示:

//在发送端,添加任意元数据
track.label=“屏幕捕获”;
peerConn.addTrack(track,屏幕捕获流);
//在接收端,检索任意元数据
peerConn.ontrack=ev=>{
const trackType=ev.track.label;//接收曲目时获取标签
}
但是这个API实际上并不存在。 有, 但它是只读的,不能保存在传输中。 通过实验,, 发送端的.label属性具有信息性(例如,
标签:“FaceTime高清摄像头(内置)(05ac:8514)”
)。 但在接收端,同一音轨的
.label
不被保留。 (它似乎被替换成了轨道的
.id
,至少是铬合金的。)

描述了同样的问题, 并推荐了一个稍微可怕的解决方案: 在发送端咀嚼SDP, 然后在接收端grep SDP。 但这种解决方案感觉非常脆弱和低级

我知道有一个
MediaStreamTrack.id
属性。 还有一个
MediaStream.id
属性。 这两者似乎都在传播过程中得以保存。 这意味着我可以在侧通道中发送元数据, 例如信令信道或
数据信道
。 从发送端,我将发送
{“myStreams”:{“screen”:“,“camera”:“}}
。 在显示任何内容之前,接收端将等待,直到它同时拥有元数据和流。 但是,这种方法引入了一个侧通道(以及与之相关的不可避免的并发挑战), 侧通道感觉不必要的地方

我正在寻找一个惯用的、健壮的解决方案。 如何在发送端标记/标识MediaStreams,
因此,接收端知道哪个流是哪个流?

我最终在信令通道中发送了此元数据。包含
会话描述(SDP)的每个信令消息现在也在其旁边包含元数据对象,该元数据对象对SDP中描述的
媒体流
进行注释。这没有并发问题,因为在为
MediaStream
触发
track
事件之前,客户端将始终收到该
MediaStream
的SDP+元数据

所以之前我有这样的信号信息:

{
“种类”:“sessionDescription”,
//RTCSessionDescriptionIt
“sessionDescription”:{“type”:“offer”,“sdp”:“…”}
}
现在我有这样的信号消息:

{
“种类”:“sessionDescription”,
//RTCSessionDescriptionIt
“sessionDescription”:{“type”:“offer”,“sdp”:“…”},
//从MediaStream ID到任意域特定元数据的映射
“mediaStreamMetadata”:{
“Y6W4U6E57654AT3S5 Y43AT4Y5S46”:{“类型”:“摄像头”},
“ki8a3greu6e53a4s46uuu7dtdjtyt”:{“类型”:“屏幕”}
}
}

我最终在信令通道中发送了此元数据。包含
会话描述(SDP)的每个信令消息现在也在其旁边包含元数据对象,该元数据对象对SDP中描述的
媒体流
进行注释。这没有并发问题,因为在为
MediaStream
触发
track
事件之前,客户端将始终收到该
MediaStream
的SDP+元数据

所以之前我有这样的信号信息:

{
“种类”:“sessionDescription”,
//RTCSessionDescriptionIt
“sessionDescription”:{“type”:“offer”,“sdp”:“…”}
}
现在我有这样的信号消息:

{
“种类”:“sessionDescription”,
//RTCSessionDescriptionIt
“sessionDescription”:{“type”:“offer”,“sdp”:“…”},
//从MediaStream ID到任意域特定元数据的映射
“mediaStreamMetadata”:{
“Y6W4U6E57654AT3S5 Y43AT4Y5S46”:{“类型”:“摄像头”},
“ki8a3greu6e53a4s46uuu7dtdjtyt”:{“类型”:“屏幕”}
}
}

发送带有元数据的自定义流标签的更规范的方法是在发送之前(但在setLocalDescription之后)修改SDP,并修改
msid
属性(代表媒体流id,)。 这里的优点是,在远程端,媒体流
id
属性被解析并在ontrack事件流中可见。看