uniapp H5 对接 声网,截图
文章目录
- 安装依赖
- 创建容器
- 容器样式
- javascript代码
- ImageDataToBlob 方法
- 控制控制台LOG输出
安装依赖
- 版本
"agora-rtc-sdk-ng": "^4.22.0",
创建容器
<template><view class="videoValue " id="videoValue"><u-toast ref="uToast"></u-toast><view @click="screenshot()">截图</view></view>
</template>
容器样式
Hbuilder X 默认支持
less
语法
<style lang="less" scoped>.videoValue {width: 100%;height: 100%;}
</style>
javascript代码
- 导入
agora-rtc-sdk-ng
- 创建声网视频实例
AgoraRTC.createClient
<script>import AgoraRTC from 'agora-rtc-sdk-ng';import {wuRenJiApi} from '@/api/wu-ren-ji.js'// 机场直播声网const client = AgoraRTC.createClient({codec: 'vp9',// codec 设置支持 "vp8" (VP8)、"h264"(H.264) 具体差别自行研究mode: 'live', // "rtc"(通信场景) 和 "live"(直播场景)mediaType: 'video',});let userClient;// 当远端用户成功发布音视频轨道之后,SDK 会触发 user-published 事件。// 这个事件携带两个参数:远端用户对象 (user) 和远端发布的媒体类型 (mediaType)。// 此时,你可以调用 AgoraRTCClient.subscribe 发起订阅。client.on('user-published', async (user, mediaType) => {await client.subscribe(user, mediaType)if (mediaType === 'video') {await user.videoTrack.play('videoValue');userClient = user.videoTrack // 获取当前渲染的视频帧数据}});export default {data() {return {snObj: null,videoUser: null,shootErrorCount: 0, // 拍摄错误次数screenShotCount: 30,screenShotTimer: null}},mounted() {let snObj = uni.getStorageSync('snObj')// snObj 主要包含1个关键参数 deviceSn/**{"createName": null,"createDatetime": "2024-10-30 10:57:36","updateName": null,"deviceSn": "7CTxxxxxx1",}*/this.snObj = snObjthis.playVideo()},methods: {playVideo() {this.openJiChangZhiBo()},// 机场async openJiChangZhiBo() {let option = uni.getStorageSync('option')// option 包含3个关键参数 deviceSn/**{"token":"++/a1oP903NnBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxACwS3Nn","appId": "fcb7ca994xxxxxxxxxxxxxxx08b","channel": "7Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-0"}*/await this.startDockerLive(1) // 连接设备if (option.appId && option.channel && option.token) {// 这一步可有可无,(离开频道),一般用于在切换页面的时候,// 也就是路由改变离开频道不会导致视频一直在播放,从而减少消耗费用await this.leave(); // // 获得token渲染直播画面 连接声网实例视频const uid = await client.join(option.appId,option.channel,option.token,null // 设置null 或者不设置 自动分配数字 UID);} else {console.error('option', option);}},// 控制机场直播 0断开 1连接async startDockerLive(op = 0) {try {const data = await api.startLive({dockSN: this.snObj.deviceSn,op: op,}).catch(err => {throw new Error('控制机场直播 断开/连接抛异常' + err)});if (op === 1) {return data;}} catch (error) {console.error(error);}},async level() {await client.leave();},// 截图async screenshot() {try {if (this.shootErrorCount >= 5) {// uview框架this.$refs.uToast.show({message: `拍摄错误超过5次,请等待${this.screenShotCount}s后重试`})this.createInteVal()return}this.$refs.uToast.show({loading: true,message: '拍摄中...',type: "loading",duration: 1000 * 10})const resImg = await userClient.getCurrentFrameData()const blobData = await ImageDataToBlob(resImg) // 自行写个js文件吧代码粘过去引入// 创建一个 FileReader 对象const reader = new FileReader();// 定义读取完成后的回调reader.onloadend = async () => {// 获取转换后的 Base64 编码数据 // 这里已经是base64了,在浏览器可以直接打开看,// 但是因为url限制,无法看全,可以直接存到服务器,// 然后范围服务器的图片地址,或者是转File文件流传输到服务器const base64String = reader.result;let fileUrl = await this.uploadFile(base64String) // 这里我是把文件上传到服务器const data = await api.screenshot({fileName: fileUrl,deviceSn: this.snObj.deviceSn,}).catch(err => {this.shootErrorCount += 1this.$refs.uToast.show({message: "拍摄上传抛异常,原因:" + JSON.stringify(err),duration: 1000 * 3})throw new Error('上传抛异常' + JSON.stringify(err));})if (data.code === 200) {this.$refs.uToast.show({message: "拍摄成功,请前往我的相册查看",position: "center",duration: 1000 * 1.5})} else {this.$refs.uToast.show({message: "拍摄失败,原因:" + JSON.stringify(data.msg),duration: 1000 * 3})this.shootErrorCount += 1}};reader.readAsDataURL(blobData)} catch (e) {this.shootErrorCount += 1this.$refs.uToast.show({message: "拍摄失败,原因:" + JSON.stringify(data.msg),duration: 1000 * 3})console.error(e)}},clearInterval() {if (this.screenShotTimer) {return}this.screenShotCount -= 1this.screenShotTimer = setInterval(() => {if (this.screenShotCount > 0) {this.screenShotCount -= 1} else {clearInterval(this.screenShotTimer)this.screenShotTimer = nullthis.shootErrorCount = 0}}, 1000)}},}
</script>
ImageDataToBlob 方法
// Uint8ClampedArray 转blob
export function ImageDataToBlob(imageData) {let w = imageData.width;let h = imageData.height;let canvas = document.createElement('canvas');canvas.width = w;canvas.height = h;let ctx = canvas.getContext('2d');ctx.putImageData(imageData, 0, 0);return new Promise((resolve) => {canvas.toBlob(resolve);});
};
控制控制台LOG输出
AgoraRTC.setLogLevel(Number)
SDK 日志输出级别。按照输出日志最全到最少排列:
- 0: DEBUG。输出所有的 SDK 日志。
- 1: INFO。输出 INFO、WARNING 和 ERROR 级别的日志。
- 2: WARNING。输出 WARNING 和 ERROR 级别的日志。
- 3: ERROR。输出 ERROR 级别的日志。
- 4: NONE。不输出日志。
例如,如果你输入代码 AgoraRTC.setLogLevel(2);,就可以只看到WARNING 和 ERROR 级别的日志信息。
创建实例之前设置log
<script>AgoraRTC.setLogLevel(2)// 航线直播声网const client = AgoraRTC.createClient({codec: 'vp9',mode: 'live',});
</script>
相关文章:
uniapp H5 对接 声网,截图
文章目录 安装依赖创建容器容器样式 javascript代码ImageDataToBlob 方法 控制控制台LOG输出 安装依赖 版本"agora-rtc-sdk-ng": "^4.22.0", 创建容器 <template><view class"videoValue " id"videoValue"><u-toast…...

家谱管理系统|Java|SSM|VUE| 前后端分离
【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库…...

【LeetCode】200、岛屿数量
【LeetCode】200、岛屿数量 文章目录 一、并查集1.1 并查集1.2 多语言解法 二、洪水填充 DFS2.1 洪水填充 DFS 一、并查集 1.1 并查集 // go var sets int var father [90000]intfunc numIslands(grid [][]byte) int {n, m : len(grid), len(grid[0])build(grid, n, m)for i …...

idea报错:There is not enough memory to perform the requested operation.
文章目录 一、问题描述二、先解决三、后原因(了解) 一、问题描述 就是在使用 IDEA 写代码时,IDEA 可能会弹一个窗,大概提示你目前使用的 IDEA 内存不足,其实就是提醒你 JVM 的内存不够了,需要重新分配。弹…...
python ai ReAct 代理(ReAct Agent)
ReAct 代理(ReAct Agent)是一种结合了推理(Reasoning)和行动(Action)的智能代理框架,旨在通过交互式的方式解决复杂任务。ReAct 的核心思想是让代理在完成任务时,能够动态地推理下一…...

HTML入门教程|| HTML 基本标签(2)
HTML 列表 HTML列表 HTML 无序列表 ul 元素表示无序列表。 ul 元素中的项目使用 li 元素表示。 元素没有在HTML5中定义任何属性,并且您使用CSS控制列表的显示。 HTML5中的 type 和 compact 属性已过时。 您可以在以下代码中查看正在使用的 ul 元素。 <!D…...

MySQL root用户密码忘记怎么办(Reset root account password)
在使用MySQL数据库的的过程中,不可避免的会出现忘记密码的现象。普通用户的密码如果忘记,可以用更高权限的用户(例如root)进行重置。但是如果root用户的密码忘记了,由于root用户本身就是最高权限,那这个方法…...
groovy:多线程 简单示例
在Groovy中,多线程编程与Java非常相似,因为Groovy运行在Java虚拟机(JVM)上,并且可以利用Java的所有并发工具。以下是一些在Groovy中实现多线程编程的方法: class MyThread extends Thread {Overridevoid…...

SOME/IP 协议详解——序列化
文章目录 0. 概述1.基本数据序列化2.字符串序列化2.1 字符串通用规则2.2 固定长度字符串规则2.3 动态长度字符串规则 3.结构体序列化4. 带有标识符和可选成员的结构化数据类型5. 数组5.1 固定长度数组5.2 动态长度数组5.3 Enumeration(枚举)5.4 Bitfield…...

三、GIT与Github推送(上传)和克隆(下载)
GIT与Github推送(上传)和克隆(下载) 一、配置好SSH二、在Github创建仓库三、git克隆(下载)文件四、git推送(上传)文件到远程仓库 一、配置好SSH Git与Github上传和下载时需要使用到…...
18.2、网络安全评测技术与攻击
目录 网络安全测评技术与工具网络安全测评质量管理和标准 网络安全测评技术与工具 漏洞扫描技术可以用于测评,测评你安不安全,也可以用来风险评估安不安全,风险大不大 漏洞扫描包含网络安全漏洞扫描、主机安全漏洞扫描,还有数据…...

在 ArcGIS Pro/GeoScene Pro 中设计专题地图的符号系统
原始 按颜色对面进行符号化 打开符号系统 选择主符号系统 选择字段及其计算方式 更改临界值</...

CSS2笔记
一、CSS基础 1.CSS简介 2.CSS的编写位置 2.1 行内样式 2.2 内部样式 2.3 外部样式 3.样式表的优先级 4.CSS语法规范 5.CSS代码风格 二、CSS选择器 1.CSS基本选择器 通配选择器元素选择器类选择器id选择器 1.1 通配选择器 1.2 元素选择器 1.3 类选择器 1.4 ID选择器 1.5 基…...
移动端如何实现上拉加载
一、理解上拉加载的原理 上拉加载是一种在移动端很常见的交互方式,其原理是当用户在页面上向上滑动(即滚动条接近底部)时,触发一个加载更多数据的操作。这通常涉及到对滚动事件的监听以及判断滚动位置是否达到了触发加载的阈值。…...

【mysql】linux安装mysql客户端
参考文章: MySQL系列之如何在Linux只安装客户端 linux下安装mysql客户端client MySQL Community Downloads 查看linux版本方法: lsb_release -a cat /proc/version下载文件: rpm -ivh mysql-community-*可以删除错误的包: RP…...

YOLOv5部署到web端(flask+js简单易懂)
文章目录 前言最终实现效果图后端实现 主界面检测函数检测结果显示 前端实现 主界面(index.html)显示图片界面 总结 前言 最近,老板让写一个程序把yolov5检测模型部署到web端,在网页直接进行目标检测。经过1个星期的努力,终于实…...
【机器学习】深度学习(DNN)
文章目录 1. 神经网络结构2. 训练步骤3. 反向传播4. 为什么深,而不是宽(模块化)5. 初始化参数能否全为0? 1. 神经网络结构 输入层隐藏层:用于特征转换输出层:用于分类技巧:将网络中的参数写成矩…...

12.30-1-5学习周报
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 文章链接摘要Abstract一、方法介绍1.HAT-CIR2.Horde3.DWGRNet 二、实验总结 文章链接 https://arxiv.org/pdf/2405.04101 摘要 本博客介绍了论文《Continual lea…...

【MySQL】数据操作
数据操作 一、INSERT1、介绍2、语法3、语法介绍4、注意事项5、示例 二、插入否则更新1、介绍2、语法3、语法介绍4、示例 三、ROW_COUNT1、介绍2、示例 四、REPLACE1、介绍2、语法3、示例 五、UPDATE1、介绍2、语法3、示例 六、DELETE1、介绍2、语法3、语法介绍 七、TRUNCATE1、…...

python数据分析:使用pandas库读取和编辑Excel表
使用 Pandas,我们可以轻松地读取和写入Excel 文件,之前文章我们介绍了其他多种方法。 使用前确保已经安装pandas和 openpyxl库(默认使用该库处理Excel文件)。没有安装的可以使用pip命令安装: pip install pandas ope…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...