一次webrtc视频拉流的摸爬滚打全纪录

简介: 上周五的上午突然接到了一个需求,要在前端页面中增加的摄像头的画面预览功能,要在周一(昨天)完成,我本来以为接入视频流并不会很困难,毕竟之前也做过视频相关的需求。

1682516723(1).png

上周五的上午突然接到了一个需求,要在前端页面中增加的摄像头的画面预览功能,要在周一(昨天)完成,我本来以为接入视频流并不会很困难,毕竟之前也做过视频相关的需求。

但是,真正做起来却不是那么简单。因为底层的同学给的视频流地址是一个rtsp协议的(例:rtsp://192.168.0.123:8081),在跟百娘“缠绵”了一番之后,最终得出结论——前端无法直接使用rtsp流播放(可能有,如果知道的大佬请评论区告知)。

在告知底层同学之后,过了一会我收到了一个链接

1682516775(1).png

他们吧rtsp流转成了WebRTC,乍一看我还有点兴奋,因为不久前刚看过WebRTC,感觉这回“简单”了。打开这个链接看到了监控的实时画面

1682516799(1).png

但是,给提供的材料有且仅有这一个链接,这我又摸不着头脑了,我了解的WebRTC是P2P的啊,需要双方的SDP进行协商连接,但这只有一个链接我怎么玩?!

一筹莫展之际,刻在前端开发DNA中的记忆被唤醒了——F12,然后发现了一个东西,直觉告诉我,真相就在不远处

1682516814(1).png

找到这个文件之后,一段段我熟悉的代码映入眼帘,我悟了。(suuid对应的就是摄像头的设备名称)

1682516876(1).png

最关键的在于下面那两个jquery请求,最后一个请求正是获取对端SDP的请求,一般使用P2P获取SDP都是用的socket,这里因为只有一端能够发起会话,所以用了http的形式。

事后我找到了他们rtsp转WebRTC所使用的工具RTSPtoWebRTC,打开github的第一眼我就认出来了

1682516900(1).png

书归正题,看懂了这段代码之后,我结合项目将这段代码转化为了我们项目中能用的形式

import { getRTCCodec, getRTCReceiver } from '@/services/camera';
/**
 * 预览摄像头
 * @param ele 要播放视频的video 标签元素
 * @param ip 视频流IP 地址
 * @param port 视频流端口
 * @param cameraName 摄像头名称
 */
export async function preview(ele, ip, port, cameraName) {
  // 创建新的媒体流
  let stream = new MediaStream();
  // 初始化 ice 配置
  let config = {
    iceServers: [
      {
        // stun 服务器地址, P2P打洞需要
        urls: ['stun:stun.l.google.com:19302'],
      },
    ],
  };
  // 兼容不同的浏览器
  const PeerConnection =
    window.RTCPeerConnection ||
    // @ts-ignore
    window.mozRTCPeerConnection ||
    window.webkitRTCPeerConnection;
  // 新建RTC连接
  const pc = new PeerConnection(config);
  // 需要协商时触发事件
  pc.onnegotiationneeded = handleNegotiationNeededEvent;
  pc.ontrack = function (event) {
    stream.addTrack(event.track);
    // 设置srcObject
    ele.srcObject = stream;
  };
  // 获取codec
  const codec = await getRTCCodec(ip, port, cameraName);
  codec.forEach((c) =>
    pc.addTransceiver(c.Type, {
      direction: 'sendrecv',
    }),
  );
  // 协商事件
  async function handleNegotiationNeededEvent() {
    // 生成本地Offer
    let offer = await pc.createOffer();
    // 设置本地Offer
    await pc.setLocalDescription(offer);
    let receiver;
    try {
      // 获取远端 answer
      receiver = await getRTCReceiver(
        ip,
        port,
        cameraName,
        pc.localDescription?.sdp,
      );
      // 设置远端 answer
      await pc.setRemoteDescription(
        new RTCSessionDescription({
          type: 'answer',
          // 解码远端answer
          sdp: atob(receiver),
        }),
      );
    } catch (e) {
      console.log(e);
    }
  }
}
复制代码

这里有个小坑,我一开始没太注意,这里卡了一段时间:获取对端answer的post请求参数,是一个字符串,类似于get请求的query格式参数,只不过挪到了body中,并不是使用json

/**
 * 获取摄像头的receiver
 * @param ip
 * @param port
 * @param cameraName
 */
export async function getRTCReceiver(
  ip: string,
  port: string,
  cameraName: string,
  sdp: any,
): Promise<any> {
  return await basePost(
    `http://${ip}:${port}/stream/receiver/${cameraName}`,
    // base64 sdp
    `suuid=${cameraName}&data=${btoa(sdp)}`,
    {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    true,
    true,
  );
}
复制代码

效果展示

1682516929(1).png


目录
打赏
0
0
0
0
2
分享
相关文章
音视频学习之rtsp推拉流学习2(流媒体服务器ZLMediaKit)
音视频学习之rtsp推拉流学习2(流媒体服务器ZLMediaKit)
754 0
庖丁解牛之-Android平台RTSP|RTMP播放器设计
我们在做Android平台RTSP或者RTMP播放器开发的时候,需要注意的点非常多,以下,以大牛直播SDK(官方)的接口为例,大概介绍下相关接口设计:
165 0
播放器之争:VLC VS SmartPlayer
好多开发者跟我们交流的时候提到,为什么有了VLC这种开源播放器,大牛直播SDK还要开发SmartPlayer?以下就针对VLC和SmartPlayer功能支持和涉及侧重,做个大概的比较:
355 0
Android平台基于RTMP或RTSP的一对一音视频互动技术方案探讨
随着智能门禁等物联网产品的普及,越来越多的开发者对音视频互动体验提出了更高的要求。目前市面上大多一对一互动都是基于WebRTC,优点不再赘述,我们这里先说说可能需要面临的问题:WebRTC的服务器部署非常复杂,可以私有部署,但是非常复杂。传输基于UDP,很难保证传输质量,由于UDP是不可靠的传输协议,在复杂的公网网络环境下,各种突发流量、偶尔的传输错误、网络抖动、超时等等都会引起丢包异常,都会在一定程度上影响音视频通信的质量,难以应对复杂的互联网环境,如跨区跨运营商、低带宽、高丢包等场景,行话说的好:从demo到实用,中间还差1万个WebRTC。
195 0
在高版本谷歌Chrome浏览器中用VLC播放海康、大华RTSP实时视频完全方案
随着互联网基础设施的完善以及4G、5G等技术的大规模商用,在Chrome、Firefox、Edge等浏览器播放RTSP视频流也慢慢成为了信息化系统的行业标准。早些年还可用VLC播放器在网页中播放RTSP视频流,好景不长,2015年Chrome、Firefox等浏览器取消了对 NPAPI插件的支持,导致在高版本的Chrome等网页中播放海康威视、大华等摄像头RTSP视频流也成了奢望。
2543 0
Android平台一对一音视频通话方案大比拼:WebRTC VS RTMP VS RTSP,谁才是王者?
【9月更文挑战第4天】本文详细对比了在Android平台上实现一对一音视频通话时常用的WebRTC、RTMP及RTSP三种技术方案。从技术原理、性能表现与开发难度等方面进行了深入分析,并提供了示例代码。WebRTC适合追求低延迟和高质量的场景,但开发成本较高;RTMP和RTSP则在简化开发流程的同时仍能保持较好的传输效果,适用于不同需求的应用场景。
349 1
Android平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台为例,介绍下如何集成RTSP、RTMP播放模块。
261 0
"震撼揭秘!Flutter如何玩转超低延迟RTSP/RTMP播放,跨平台视频流体验大升级,让你的应用秒变直播神器!"
【8月更文挑战第15天】Flutter作为跨平台UI框架,以其高效性和丰富生态著称。本文详述如何利用flutter_vlc_player等插件在Flutter中实现低延迟RTSP/RTMP播放,并提供代码示例。通过优化播放器设置,如禁用缓冲、启用帧丢弃等,可进一步减少延迟,提升用户观看体验,展现了Flutter在视频流媒体应用中的强大潜力。
193 0
### 惊天对决!Android平台一对一音视频通话方案大比拼:WebRTC VS RTMP VS RTSP,谁才是王者?
【8月更文挑战第14天】随着移动互联网的发展,实时音视频通信已成为移动应用的关键部分。本文对比分析了Android平台上WebRTC、RTMP与RTSP三种主流技术方案。WebRTC提供端到端加密与直接数据传输,适于高质量低延迟通信;RTMP适用于直播场景,但需服务器中转;RTSP支持实时流播放,但在复杂网络下稳定性不及WebRTC。三种方案各有优劣,WebRTC功能强大但集成复杂,RTMP和RTSP实现较简单但需额外编码支持。本文还提供了示例代码以帮助开发者更好地理解和应用这些技术。
200 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等