更新记录

1.0.14(2026-08-12)

  1. 优化

1.0.13(2026-08-12)

  1. 增加清晰度切换接口

1.0.12(2026-08-11)

  1. 增加鸿蒙支持
查看更多

平台兼容性

uni-app(3.8.1)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - 5.0 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(3.8.1)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 - -

其他

多语言 暗黑模式 宽屏模式

萤石SDK

  • 预览:直播、截图抓图、声音开关
  • 对讲:对讲、对讲音频音量大小
  • 回放:回放、倍数回放、进度拖拽

集成步骤

  • 拷贝demo示例项目里的AndroidManifest.xml文件到项目根目录
  • 咨询或定制请点击上面"进入交流群"按钮私聊作者
  • 登陆萤石管理后台创建应用获取到appKey、token,替换demo里App.vue里的appkey和token
  • 替换playback.nvue和realPlay.nvue里的deviceSerial和cameraNo

文档

    import {
    EZOpen
} from "@/uni_modules/wrs-uts-ezopen"
  • 是否开启日志

EZOpen.showSDKLog(true)
  • 是否开启调试流

EZOpen.setDebugStreamEnable(true)
  • 是否开启P2P

EZOpen.enableP2P(true)
  • 初始化sdk

let appkey = "xxx" // 替换成自己应用的appKey
let token = "xxx" // 替换成自己应用的token
let apiUrl = "https://open.ys7.com" // 国内固定这个
let authUrl = "https://openauth.ys7.com" // 国内固定这个
let isEnableSDKWithTKToken = false
if (token.startsWith("tk.")) {
    isEnableSDKWithTKToken = true
}
EZOpen.enableSDKWithTKToken(isEnableSDKWithTKToken)

let params = {}
params.appKey = appkey
params.apiUrl = apiUrl
params.authUrl = authUrl
if (isEnableSDKWithTKToken) {
    params.httpToken = token
} else {
    params.accessToken = token
}
EZOpen.sdkInit(params)
  • 抓图

let params = {}
params.deviceSerial = ""
params.cameraNo = 0
EZOpen.captureCamera(params, (resp) => {
    console.log("captureCamera resp:" + JSON.stringify(resp))
    let result = resp.result
    if (result) {
        // result是抓图的地址
        this.imageSrc = result
    }
})

组件


        <!--  #ifdef  APP-HARMONY -->
<embed :style="'width:'+width+'px;height:'+height+'px;'" tag="vlc" :options="options"
    @onevent="onEvent"></embed>
<!--  #endif -->
<!--  #ifndef  APP-HARMONY -->
<wrs-uts-ezopenplayer ref='vlc' :params="params" :style="'width:'+width+'px;height:'+height+'px;'"
    @onEvent="onEvent"></wrs-uts-ezopenplayer>
<!--  #endif -->
  • 使用了该组件的页面需要用nvue或uvue
  • 属性params是json格式的字符串

let deviceSerial = ""
let cameraNo = 0

let params = {}
params.businessArray = [{
    business: "setUrl", // 业务
    params: { // 业务参数
        deviceSerial: deviceSerial,
        cameraNo: cameraNo,
        autoPlay: true
    }
}]
let paramsStr = JSON.stringify(params)
let width = windowWidth
let height = width / (16.0 / 9.0)
return {
    params: paramsStr,
    options: {
        params: paramsStr
    },
    deviceSerial: deviceSerial,
    cameraNo: cameraNo,
    width: width,
    height: height,
    imageSrc: null,
    msg: null
}
  • 回调事件

            onEvent(event) {
    const detail = event.detail
    console.log("onEvent detail:" + JSON.stringify(detail))
    let opt = detail.opt

    // console.log("onEvent detail:" + JSON.stringify(detail))
    switch (opt) {
        // 消息事件,仅支持Android
        case "onEvent": {
            // what码值:
            // public static final int MSG_GET_CAMERA_INFO_SUCCESS = 100;
            //  public static final int MSG_GET_CAMERA_INFO_FAIL = 101;
            //  public static final int MSG_REALPLAY_PLAY_SUCCESS = 102;
            //  public static final int MSG_REALPLAY_PLAY_FAIL = 103;
            //  public static final int MSG_SET_VEDIOMODE_SUCCESS = 105;
            //  public static final int MSG_SET_VEDIOMODE_FAIL = 106;
            //  public static final int MSG_START_RECORD_SUCCESS = 107;
            //  public static final int MSG_START_RECORD_FAIL = 108;
            //  public static final int MSG_REALPLAY_PASSWORD_ERROR = 111;
            //  public static final int MSG_REALPLAY_ENCRYPT_PASSWORD_ERROR = 112;
            //  public static final int MSG_REALPLAY_VOICETALK_SUCCESS = 113;
            //  public static final int MSG_REALPLAY_VOICETALK_FAIL = 114;
            //  public static final int MSG_REALPLAY_VOICETALK_STOP = 115;
            //  public static final int MSG_REALPLAY_UPDATE_TALK_VOLUME = 116;
            //  public static final int MSG_PTZ_GET_SUCCESS = 122;
            //  public static final int MSG_PTZ_SET_SUCCESS = 123;
            //  public static final int MSG_PTZ_SET_FAIL = 124;
            //  public static final int MSG_REALPLAY_PLAY_START = 125;
            //  public static final int MSG_REALPLAY_CONNECTION_START = 126;
            //  public static final int MSG_REALPLAY_CONNECTION_SUCCESS = 127;
            //  public static final int MSG_REALPLAY_CHECK_SUCCESS = 131;
            //  public static final int MSG_REALPLAY_CHECK_FAIL = 132;
            //  public static final int MSG_REALPLAY_STOP_SUCCESS = 133;
            //  public static final int MSG_REALPLAY_PLAY_PREPARED = 139;
            //  public static final int MSG_PRIVATE_TOKEN_GET_SUCCESS = 135;
            //  public static final int MSG_VIDEO_LEVEL_AUTO_IMPROVE = 136;
            //  public static final int MSG_VIDEO_LEVEL_AUTO_REDUCE = 137;
            //  public static final int MSG_SET_VEDIOMODE_AUTO_SUCCESS = 138;
            //  public static final int MSG_NET_CHANGED = 140;
            let what = detail.what
            switch (what) {
                // MSG_REALPLAY_PLAY_SUCCESS 播放成功
                case 102:

                    break;
                    // MSG_REALPLAY_PLAY_FAIL播放失败
                case 103:

                    break;
                    // MSG_REALPLAY_VOICETALK_SUCCESS 对讲成功
                case 113:

                    break;
                    // MSG_REALPLAY_VOICETALK_FAIL 对讲失败
                case 114:

                    break;
                    // MSG_PTZ_GET_SUCCESS
                case 122:
                    break;
                default:
                    break;
            }
        }
        break;
        // 收到播放消息,仅支持iOS
        case "onReceivedMessage": {

            let playerType = detail.playerType
            if (playerType == 0) { // 播放器的回调
                console.log("视频播放器")
            } else { // 对讲的回调
                console.log("对讲播放器")
            }
            // messageCode值:
            // PLAYER_REALPLAY_START = 1,        //直播开始
            // PLAYER_VIDEOLEVEL_CHANGE = 2,     //直播流清晰度切换中
            // PLAYER_STREAM_RECONNECT = 3,      //直播流取流正在重连
            // PLAYER_VOICE_TALK_START = 4,      //对讲开始
            // PLAYER_VOICE_TALK_END = 5,        //对讲结束
            // PLAYER_STREAM_START = 10,         //录像取流开始
            // PLAYER_PLAYBACK_START = 11,       //录像回放开始播放
            // PLAYER_PLAYBACK_STOP = 12,        //录像回放结束播放
            // PLAYER_PLAYBACK_FINISHED = 13,    //录像回放被用户强制中断
            // PLAYER_PLAYBACK_PAUSE = 14,       //录像回放暂停
            // PLAYER_NET_CHANGED = 21,          //播放器检测到wifi变换过
            // PLAYER_NO_NETWORK = 22,           //播放器检测到无网络
            // PLAYER_CLOUD_IFRAME_CHANGED = 23, //云存储快放时,由全帧快放切换到抽帧快放的提示回调
            // PLAYER_PLAYSPEED_LOWER = 24,      //云存储快放时的降速通知(存在两次降速:当前倍速大于4倍速时,降到4倍速;当前为4倍速时,降为1倍速)
            // PLAYER_VIDEO_LEVEL_AUTO_IMPROVE = 25,//预览自动清晰度提升消息
            // PLAYER_VIDEO_LEVEL_AUTO_REDUCE = 26, //预览自动清晰度降低消息
            // PLAYER_PREPARED = 27,             //播放库已创建
            let messageCode = detail.messageCode
            switch (messageCode) {
                case 1: {
                    // 直播开始
                }
                break;
                case 2: {
                    // 直播流清晰度切换中
                }
                break;
                case 3: {
                    // 直播流取流正在重连
                }
                break;
                case 4: {
                    // 对讲开始
                }
                break;
                case 5: {
                    // 对讲结束
                }
                break;
                case 27: {
                    // 播放库已创建
                }
                break;
                default:
                    break;
            }
        }
        break;
        // 播放失败,仅支持iOS
        case "onPlayFailed": {
            let code = resp.code
            let playerType = detail.playerType
            if (playerType == 0) {
                console.log("视频播放器")
                // code取值:
                // EZ_NPC_CLIENT_PARAMETER_ERROR = 500001,           //参数错误
                // EZ_NPC_CLIENT_ORDER_ERROR = 500002,               //调用顺序出错
                // EZ_NPC_CLIENT_MEMORY_ERROR = 500003,              //分配内存失败
                // EZ_NPC_CLIENT_BUFFER_OVERFLOW_ERROR = 500004,     //缓冲区溢出
                // EZ_NPC_CLIENT_SYSTEM_NO_SUPPORT_ERROR = 500005,   //系统不支持
                // EZ_NPC_CLIENT_INVALID_PORT_ERROR = 500006,        //无效端口
                // EZ_NPC_CLIENT_STREAM_CLOSE_ERROR = 500101,        //流关闭
                // EZ_NPC_CLIENT_TRACK_CLOSE_ERROR = 500102,         //TRACK_CLOSE
                // EZ_NPC_CLIENT_NPCCREATE_ERROR = 500103,           //创建失败
                // EZ_NPC_CLIENT_TRSCREATE_ERROR = 500104,           //TRSCREATE_ERROR
                // EZ_NPC_CLIENT_FAIL_UNKNOWN_ERROR = 509999,        //FAIL_UNKNOWN
                if (code == 400035) { // 需要设备验证码

                } else if (code == 400036) { // 设备验证码不匹配

                }
            } else {
                console.log("对讲播放器")
            }
        }
        break;
        case "snapshot": {
            // 截图回调
            let filePath = detail.filePath
            if (filePath) {
                let path = detail.filePath
                this.imageSrc = "file://" + path
            } else {
                this.showMsg("截图失败:" + JSON.stringify(detail))
            }
        }
        break;
        // 对讲音频音量大小
        case "setVoiceTalkLoudnessCallback": {
            let v = detail.v

        }
        break;
    }
}

params.businessArray数组里支持的业务对象有:

  • 设置直播预览播放地址
{
        business: "setUrl", // 业务
        params: {
            deviceSerial: "xxx", // 设备码
            cameraNo: 1, // 相机编码
            autoPlay: true // 是否自动播放
        }
}

或者

{
        business: "setUrl", // 业务
        params: {
            url: "rtsp://xxxx", // 直播地址
            autoPlay: true // 是否自动播放
        }
}
  • 开始播放

{
        business: "startRealPlay"
}
  • 继续播放

{
        business: "stopRealPlay"
}
  • 是否开启声音,要在播放成功后才可以设置是否开启声音
{
    business: "setSound",
    params: {
        isOpen: true
    }
}
  • 清晰度切换

let params = {}
params.deviceSerial = deviceSerial
params.cameraNo = cameraNo
params.videoLevel = videoLevel
console.log("setVideoLevel params:" + JSON.stringify(params))
EZOpen.setVideoLevel(params, (resp) => {
    let flag = resp.flag
    if (flag) {
        console.log("切换成功")

        //清晰度切换成功后,再暂停播放,再重新播放
        let newParams = {}
        newParams.businessArray = [{
            business: "stopRealPlay"
        }, {
            business: "startRealPlay"
        }]
        console.log("vue params:" + JSON.stringify(newParams))
        let newParamsStr = this.formatNewParams(newParams)
        // android、ios
        this.params = newParamsStr
        // 鸿蒙
        this.options = {
            params: newParamsStr
        }
    } else {
        console.log("切换失败:" + JSON.stringify(resp))
    }
})
  • 截图
let name = new Date().getTime()
let path = EZOpen.getFilesDir() + "/" + name + ".jpg"

{
    business: "snapshot", // 截图
    params: {
        path: path // 本地保存图片的绝对地址
    }
}
  • 开启关闭对讲,全双工
{
    business: "startVoiceTalk", // 对讲
    params: {
        isOpen: false // 关闭
    }
}
  • 开启关闭对讲,半双工
{
    business: "setVoiceTalkStatus", // 对讲
    params: {
        isOpen: false // 关闭
    }
}
  • 对讲音频音量大小

    business: "setVoiceTalkLoudnessCallback",
    params: {
        interval: 0.15
    }
}
  • 回放

回放云端存储视频
{
        business: "setUrl", // 业务
        params: {
            deviceSerial: "xxx", // 设备码
            cameraNo: 1, // 相机编码
            cloudFileKey: "" // 从EZOpen.searchRecordFileFromCloud接口获取
        }
}

或

回放设备存储视频
{
        business: "setUrl", // 业务
        params: {
            deviceSerial: "xxx", // 设备码
            cameraNo: 1, // 相机编码
            deviceFileKey: "" // 从EZOpen.searchRecordFileFromDevice接口获取
        }
}
  • 倍速回放
{
    business: "setPlaybackRate", // 对讲
    params: {
        rate: "2" // 云端回放支持:"1/16", "1/8", "1/4", "1/2", "1", "2", "4", "8", "16", "32"  设备回放需要各自去根据设备获取
    }
}
  • 进度拖拽
{
    business: "seekPlayback", // 对讲
    params: {
        time: 21212121 // 播放时间戳,Android精确到毫秒,iOS精确到秒
    }
}
  • 获取云端存储视频
let params = {}
params.deviceSerial = ""
params.cameraNo = 0
params.startTime = 5444 // 开始时间戳,精确到秒
params.endTime = 555 // 结束时间戳,精确到秒
// console.log("searchRecordFileFromCloud params:" + JSON.stringify(params))
EZOpen.searchRecordFileFromCloud(params, (resp) => {
    let data = resp.data
    if (data) {
        let titles = []
        let count = data.length
        for (var i = 0; i < count; i++) {
            let model = data[i]
            let title = model.startTime + "-" + model.stopTime
            titles.push(title)
        }
        this.showActionSheet(titles, (index) => {
            let model = data[index]
            this.model = model
            let fileKey = model.fileKey
            let newParams = {}
            newParams.businessArray = [{
                business: "setUrl", // 对讲
                params: {
                    deviceSerial: this.deviceSerial,
                    cameraNo: this.cameraNo,
                    cloudFileKey: fileKey
                }
            }]

            let newParamsStr = this.formatNewParams(newParams)
            // android、ios
            this.params = newParamsStr
            // 鸿蒙
            this.options = {
                params: newParamsStr
            }
        })
    } else {
        console.log(JSON.stringify(resp))
    }
})
  • 获取设备存储视频

let params = {}
params.deviceSerial = this.deviceSerial
params.cameraNo = this.cameraNo
params.startTime = startTime // 开始时间戳,精确到秒
params.endTime = endTime // 结束时间戳,精确到秒
EZOpen.searchRecordFileFromDevice(params, (resp) => {
    let data = resp.data
    if (data) {
        let titles = []
        let count = data.length
        for (var i = 0; i < count; i++) {
            let model = data[i]
            let title = model.startTime + "-" + model.stopTime
            titles.push(title)
        }
        this.showActionSheet(titles, (index) => {
            let model = data[index]
            this.model = model
            let fileKey = model.fileKey
            let newParams = {}
            newParams.businessArray = [{
                business: "setUrl",
                params: {
                    deviceSerial: this.deviceSerial,
                    cameraNo: this.cameraNo,
                    deviceFileKey: fileKey
                }
            }]

            let newParamsStr = this.formatNewParams(newParams)
            // android、ios
            this.params = newParamsStr
            // 鸿蒙
            this.options = {
                params: newParamsStr
            }
        })
    } else {
        console.log(JSON.stringify(resp))
    }
})

隐私、权限声明

1. 本插件需要申请的系统权限列表:

网络

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: