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 = snObj
this.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 += 1
this.$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 += 1
this.$refs.uToast.show({
message: "拍摄失败,原因:" + JSON.stringify(data.msg),
duration: 1000 * 3
})
console.error(e)
}
},
clearInterval() {
if (this.screenShotTimer) {
return
}
this.screenShotCount -= 1
this.screenShotTimer = setInterval(() => {
if (this.screenShotCount > 0) {
this.screenShotCount -= 1
} else {
clearInterval(this.screenShotTimer)
this.screenShotTimer = null
this.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>