WebRtc直播流的播放

WebRtc直播流的播放

后端服务已经使用ZLMediaKit框架提供了直播流地址

一、WebRtc原生播放器播放直播流

1、使用ZLMediaKit框架提供的ZLMRTCClient.js

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>播放示例</title> <!-- 引入 zlmrtcclient.js 1.0.2 --> <script src="http://117.40.242.70:35080/ZLMRTCClient.js"></script> </head> <body> <!-- 视频播放元素 --> <video autoplay controls></video> <script> // 1. 获取视频元素 const videoElement = document.getElementById('videoPlayer'); // 2. 配置参数(严格对应 1.0.2 版本的 defaults 结构) const config = { element: videoElement, // 绑定视频播放元素(必填) debug: true, // 开启调试日志,方便排查问题 zlmsdpUrl: 'http://117.40.242.70:35080/index/api/webrtc?app=live&stream=test1&type=play', // 后端提供的流地址(必填) simulcast: false, // 不启用 simulcast(早期版本可能不支持) useCamera: false, // 播放时不需要启用本地摄像头 audioEnable: true, // 启用音频 videoEnable: true, // 启用视频 recvOnly: true, // 仅接收流(播放模式) resolution: { w: 800, h: 450 }, // 视频分辨率 usedatachannel: false // 不使用数据通道 }; // 3. 创建实例(1.0.2 版本可能通过构造函数直接初始化,无需 connect 方法) const rtcClient = new ZLMRTCClient.Endpoint(config); // 4. 监听事件(1.0.2 版本的事件名可能与早期定义一致) // 监听错误事件 rtcClient.on('error', (err) => { console.error('ZLMRTCClient 错误:', err); }); // 监听 WebRTC 不支持事件 rtcClient.on('webrtcNotSupport', () => { alert('当前浏览器不支持 WebRTC,请更换浏览器'); }); var remoteStream = null; // 监听远程流添加事件(核心:获取到流后播放) rtcClient.on('WEBRTC_ON_REMOTE_STREAMS', (event) => { console.log('收到远程流,开始播放'); // 1.0.2 版本可能自动绑定到 element,若未自动绑定则手动设置 if (videoElement.srcObject !== event.streams) { const stream = event.streams[0]; remoteStream = stream; videoElement.srcObject = stream; } }); // 监听连接状态变化 rtcClient.on('WEBRTC_ON_CONNECTION_STATE_CHANGE', (state) => { console.log('连接状态:', state); // 可能的状态:connecting/connected/disconnected }); function stop() { if (!rtcClient) return; // 停止视频播放 videoElement.pause(); videoElement.srcObject = null; // 停止媒体流轨道 if (remoteStream) { remoteStream.getTracks().forEach(track => track.stop()); remoteStream = null; } // 断开连接并清理实例 if (rtcClient.disconnect) { rtcClient.disconnect(); } else if (rtcClient.close) { rtcClient.close(); } rtcClient = null; } </script> </body> </html>

ZLMRTCClient.js的版本不同,实例化对象rtcClient对象不同,这里使用的1.0.2是

new ZLMRTCClient.Endpoint(config)

二、使用开源的播放器easyPlayer

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>演示</title> <script src="./js/EasyPlayer-pro.js"></script> </head> <style> .player_item { position: relative; padding-bottom: 56%; background-color: black; margin-bottom: 20px; } .player_box { position: absolute; top: 0; bottom: 0; right: 0; left: 0; } .inputs { -webkit-appearance: none; background-color: #fff; background-image: none; border-radius: 4px; border: 1px solid #dcdfe6; box-sizing: border-box; color: #606266; display: inline-block; font-size: inherit; height: 36px; line-height: 36px; outline: none; padding: 0 15px; transition: border-color .2s cubic-bezier(.645, .045, .355, 1); width: 100%; max-width: 600px; margin-right: 16px; margin-bottom: 16px; margin-top: 16px; } .btn-item { cursor: pointer; display: inline-block; padding: 6px 12px; margin-right: 15px; border-radius: 4px; border: 1px #ccc solid; } .df { display: flex; align-items: center; margin-bottom: 16px; } .box { padding-top: 10px; margin: auto; max-width: 800px; } </style> <body> <div> <br> <h2>EasyPlayerPro案例演示</h2> <br> <div> <div></div> </div> <div> <input type="checkbox" /><span>音频</span> </div> <input type="text" value="ws://localhost:6230/ws_flv/live/stream_1_0.flv"> <div> <div>播放</div> <div>重播</div> <div>静音</div> <div>注销</div> </div> </div> <script> window.onload = function () { var playerInfo = null var config = { stretch: true, hasAudio: true, } playCreate() var input = document.getElementById('input'); var audio = document.getElementById('hasAudio'); var player = document.getElementById('onPlayer'); var replay = document.getElementById('onReplay'); var mute = document.getElementById('onMute'); var stop = document.getElementById('onStop'); if (config.hasAudio) audio.checked = true audio.onclick = () => { if (audio.checked == true) { config.hasAudio = true } else { config.hasAudio = false } } player.onclick = () => { onPlayer() } replay.onclick = () => { onReplay() } mute.onclick = () => { onMute() } stop.onclick = () => { onStop() } function playCreate() { var container = document.getElementById('player_box'); playerInfo = new EasyPlayerPro(container, config); } function onPlayer() { playerInfo && playerInfo.play(input.value).then(() => { }).catch((e) => { console.error(e); }); } function onMute() { if (!playerInfo) return playerInfo.setMute(true) } function onReplay() { onDestroy().then(() => { playCreate(); onPlayer() }); } function onDestroy() { return new Promise((resolve, reject) => { if (playerInfo) { playerInfo.destroy() playerInfo = null } setTimeout(() => { resolve(); }, 100); }) } function onStop() { onDestroy().then(() => { playCreate(); }); } } </script> </body> </html>

播放效果好,具有截图、视频录制等功能

Read more

Gazebo 机器人三维物理仿真平台

Gazebo 简介 Gazebo 是一款由 Open Robotics(前身为 Willow Garage 和 OSRF)开发的开源 3D 机器人仿真软件。它是目前世界上最流行的机器人仿真平台之一,被广泛应用于学术研究、工业开发和机器人竞赛中。 核心特性 1. 物理仿真引擎 * ODE(Open Dynamics Engine):默认物理引擎,支持刚体动力学 * Bullet:支持软体动力学和复杂碰撞检测 * Simbody:生物力学级精确仿真 * DART:基于广义坐标的高效动力学仿真 2. 3D 图形渲染 * OGRE(Object-Oriented Graphics Rendering Engine):提供高质量的 3D 可视化 * 支持逼真的光照、阴影、材质和纹理 * 可配置多摄像头视角和传感器可视化 3. 传感器仿真 支持多种机器人传感器的仿真:

云端微光,AI启航:低代码开发的智造未来

云端微光,AI启航:低代码开发的智造未来

文章目录 * 前言 * 一、引言:技术浪潮中的个人视角 * 初次体验腾讯云开发 Copilot * 1.1 低代码的时代机遇 * 1.1.1 为什么低代码如此重要? * 1.2 AI 的引入:革新的力量 * 1.1.2 Copilot 的亮点 * 1.3 初学者的视角 * 1.3.1 Copilot 带来的改变 * 二、体验记录:云开发 Copilot 的实际操作与感受 * 2.1 初步接触:云开发 Copilot 的界面和功能布局 * 2.2 操作过程详解:从需求输入到初步成果 * 2.2.1

真双端口RAM在FPGA中使用

真双端口RAM在FPGA中使用

真双端口RAM在FPGA中使用 真双端口RAM(True Dual-Port RAM, TDP BRAM)在FPGA中是功能强大的资源,但它是一把双刃剑。是否使用,完全取决于应用场景和设计约束。 下面我将从优势、风险、核心考量因素和应用建议四个方面详细拆解。 一、真双端口的独特优势(为什么想用它?) 这是单端口或伪双端口无法替代的: 1. 真正的并行存取 :两个端口可以 同时对任意地址 (包括同一地址)进行独立的读写操作。这在需要极高数据吞吐率或复杂数据交互的场景中至关重要。 2. 灵活的带宽加倍 :当两个端口都用于读或写时,有效带宽是单端口的两倍。 3. 实现复杂数据流结构 : * 无冲突的共享存储器 :两个处理器核无需仲裁即可访问共享数据池。 * 乒乓缓冲区的终极形态 :端口A写缓冲区0,端口B同时读缓冲区1,实现零延迟切换。 * 实时数据交叉访问 :如矩阵运算中,一个端口按行访问,另一个端口同时按列访问。 二、真双端口的核心“坑”与风险(为什么不随便用?) 这正是你问题的核心——“不易察觉的坑”。 同一地址读写冲突(Write/

protege+Neo4j+前端可视化知识图谱项目(教育领域)

protege+Neo4j+前端可视化知识图谱项目(教育领域)

声明:自己的学习笔记,仅供交流分享。 注意其中JDK版本的切换! 目录 1、工具下载 1.1protege的安装 1.2Neo4j的安装 2、Neo4j导入protege文件 2.1启动Neo4j 2.2protege导出owl文件转turtle文件 2.3导入Neo4j 1. 清除数据库中的所有数据 2. 初始化 RDF 导入配置 3. 导入 RDF 数据 4.查询所有(部分)数据 5.查询边关系 6.一些细节 3、Neo4j导出JSON文件 4、可视化前的操作 4.1利用python对数据进行处理 4.2学习VUE&Echarts 1、工具下载 1.