微信小程序连接“萤石云”

获取直播rtmp地址

备注:  1.萤石开发手册:https://open.ys7.com/doc/zh/uikit/wechat_miniapp.html

             2.微信公众平台:在微信公众平台里注册小程序必须选用企业账号(需要审核)

             3.可以采用复核资质快速注册小程序(无需任何费用和审核)

         

 

         4.萤石云小程序依赖微信实时音视频播放组件live-player,需要通过类目审核。审核通过后开启该组件的接口权限。

        5.在微信小程序中请求萤石开放平台API时,需预先设置通讯域名,小程序只可以和指定的域名进行网络通讯。您可以登录微信公众平台,在左侧导航栏单击 「开发」,然后单击 「开发设置」,在 「服务器域名」 区域,单击 「修改」,进行配置。

先获取直播rtmp地址,在播放视频(1.2顺序互换一下)!!!!!!!!!!!!

 代码部分:

1.视频播放:

wxml(视频播放区块)

<live-player id="videoPlayr"  binderror="error" bindstatechange="statechange" mode="RTC" src="{{videoSrc}}"  autoplay="true" ></live-player>

 注释:

  • bindstatechange:监听播放状态变化,通过e.detail.code获取当前播放状态值

  • mode属性默认为live(直播模式),萤石云小程序live-player组件为实时通话模式(mode="RTC"),该模式时延更低。

  • src:您的设备播放地址,目前仅支持flv,rtmp格式。萤石开放 API 仅提供 rtmp 播放协议地址。
  • autoplay:true表示自动播放,false表示手动播放。
  • cover-view组件 可覆盖在live-player组件之上,用于展示“播放按钮”、"全屏按钮"等播放器辅助功能。通过hidden="{true}"进行隐藏,hidden="{false}"进行展示。(此案例不需要)
let livePlayerContext   
page({
    data: {
        videoSrc: '' // 视频播放地址
    },
   onLoad: function () {
     livePlayerContext = wx.createLivePlayerContext('videoPlayr'); 
     //创建 LivePlayerContext 对象,以操作live-player组件
     // 调用接口获取videoSrc视频播放地址,videoPlayr为组件的id名
   },
  // 开始播放
  videoPlayer(){
    this.setData({
      play:'none',
      play2:'block'
    })
    livePlayerContext.play({
      success: ()=>{
         console.log("播放成功")
      },
      fail: (error)=>{
        console.log("播放失败:",error)
      }
      })
  },
  //暂停播放
  closePlayer(){
    this.setData({
      play:'block',
      play2:'none'
    })
    livePlayerContext.pause({
      success:()=>{
        console.log("暂停播放")
      },
      fail:(error)=>{
        console.log("暂停播放失败",error)
      }
    })
  },
  statechange(e) {   // 播放状态监听
    const { code } = e.detail;
    switch (code){
      case 2007: //启动loading
        break;
      case 2001: //连接服务器 
        break;
      case 2002: //已经连接 RTMP 服务器,开始拉流 
           break;
      case 2008: // 解码器启动
        console.log("case 2008: //解码器启动");
        break;
      case 2009: //视频分辨率改动
         console.log("case 2009: //视频分辨率改动");
        this.handlePlay(); // 视频分辨率改动可能导致播放暂停,可调用handlePlay()重启播放
        break;
      case 2004: 
        console.log("case 2004: // 视频播放开始");
        break;
      case 2003: 
          console.log("case 2003: //网络接收到首个视频数据包(IDR)");
          break;
      case 2103: //网络断连, 已启动自动重连(本小程序不自动重连)
          break;
      case 3001:
      case 3002:
      case 3003:
      case 3005: // RTMP 读/写失败,之后会发起网络重试
          console.log("播放失败");
          break;
      case 2105: // 当前视频播放出现卡顿
        break;
      case -2301: // 经多次重连抢救无效,更多重试请自行重启播放
        break;
    }
  },
})

 注释:livePlayerContext讲解

2.获取直播rtmp地址

  注释:

        1.返回数据,返回字段url为rtmp直播地址

        2.需要注册“萤石云”账号

        3.AccessToken在萤石云“我的账号”下的应用信息里

page({
    onLoad:function(){
    //请求rtmp直播地址
    wx.request({
      url: 'https://open.ys7.com/api/lapp/v2/live/address/get', 
      method: 'POST',
      data: {
        accessToken:"",
        deviceSerial:"",//设备序列号
        channelNo:"1",//通道号
        protocol:"3",//流轮播协议
        quality:"1",//视频清晰度
        expireTime:'86400'//过期时间
      },
      header: {
        'content-type': 'application/x-www-form-urlencoded' // 默认值(一定要加,不然会提 
         示"deviceSerial不能为空", code: "10001")
      },
      success:(res) =>{
        console.log(res.data);      
        if(res.data.code ==200 && res.data.data){
          console.log("请求rtmp直播地址成功!",res.data.data.url)
          this.setData({
            videoSrc:res.data.data.url
          })
          console.log(this.data.videoSrc)
        }else {
          // 微信提供的错误信息弹出框
          wx.showToast({
            title: res.data.msg,
            icon: 'none'
          })
        }
      }
    })
    }
})

               

3.云台控制

在前面两项的基础上来进行云台控制

注释:

        1.目前萤石云小程序只支持设备上、下、左、右四个方位的转向

        2.我们通过微信提供的 catchtouchstart 和 catchtouchend 监听手势移动开始和结束时的坐标值

        

 

    

<!-- 按钮区块 -->
<view class="mobile-ez-ptz-contaoner" id="ptz-img-container" 
catchtouchstart="handlePtzTouchStart" catchtouchend="handlePtzTouchEnd">
   <view class="mobile-ez-ptz-main">
     <image class="suspend" src="../../images/remoteControl/suspend.png"  style="display: 
     {{play}}"  catchtouchstart="videoPlayer"></image>
     <image class="play" src="../../images/remoteControl/play.png"  style="display: 
     {{play2}}" catchtouchstart="closePlayer"></image>
   </view>	
   <view class="mobile-ez-ptz-icon-top" id="mobile-ez-ptz-icon-top"></view>
   <view class="mobile-ez-ptz-icon-left"  id="mobile-ez-ptz-icon-left"></view>
   <view class="mobile-ez-ptz-icon-bottom" id="mobile-ez-ptz-icon-bottom"></view>
   <view class="mobile-ez-ptz-icon-right" id="mobile-ez-ptz-icon-right"></view>
</view>
page({
  // 计算移动起始方位
  handlePtzTouchStart(event){
    wx.createSelectorQuery().select('#ptz-img-container').boundingClientRect( (rect)                 
    => {
       let { clientX,clientY} = event.touches[0]; // 移动起始坐标值
       let rectLeft = rect.left; // 计算云台控制组件的位置
       let rectTop = rect.top; // 计算云台控制组件的位置

       var centerLeft = 104 + rectLeft; // 组件实际坐标值
       var centerTop = 104 + rectTop;// 组件实际坐标值
       var left = clientX - centerLeft; // 移动偏移量
       var top = clientY - centerTop; // 移动偏移量

       if(Math.abs(left) > Math.abs(top)){
         if(left>0){
           this.handlePtzControl(3); // 向右移动
         }else {
           this.handlePtzControl(2); // 向左移动
         }
       } else {
         if (top > 0) {
           this.handlePtzControl(1); // 向下移动

         } else {
           this.handlePtzControl(0); // 向上移动
         }
       }
     }).exec();
   },
  // 计算移动结束时方位
  handlePtzTouchEnd(event) {
    let { clientX, clientY } = event.changedTouches[0]; //移动结束坐标值
    const _this = this; 
    wx.createSelectorQuery().select('#ptz-img-container').boundingClientRect( (rect)                     
    => {
      let rectLeft = rect.left;// 计算云台控制组件的位置
      let rectTop = rect.top;// 计算云台控制组件的位置

      var centerLeft = 104 + rectLeft;  // 组件实际坐标值
      var centerTop = 104 + rectTop;// 组件实际坐标值
      var left = clientX - centerLeft;// 移动偏移量
      var top = clientY - centerTop;// 移动偏移量
      if (Math.abs(left) > Math.abs(top)) {
        if (left > 0) {
          _this.handlePtzControl(3,'stop');
        } else {
          _this.handlePtzControl(2, 'stop');
        }
      } else {
        if (top > 0) {
          _this.handlePtzControl(1, 'stop');
        } else {
          _this.handlePtzControl(0,'stop');
        }
      }
    }).exec();
  },
  // 调用接口控制云台转向(被执行两次开始点击一次,结束点击一次)
  handlePtzControl(position,type){ //position是方向(3:右,2:左,1:下,0:上),type是判断 
    开始还是结束
    const { accessToken, deviceSerial, channelNo } = this.data;
    var url = 'https://open.ys7.com/api/lapp/device/ptz/start';  //请求开始云台控制地址
    if(type == 'stop'){
      url = 'https://open.ys7.com/api/lapp/device/ptz/stop'//请求结束云台控制地址
    }
    wx.request({
      url: url, //请求地址上面的url局部变量(判断是开始云台控制地址/结束云台控制地址)
      method: 'POST',
      data: {
        "accessToken": accessToken,
        "deviceSerial": deviceSerial,//设备序列号
        "channelNo": channelNo,//通道号
        "direction": position, //操作命令:0-上,1-下,2-左,3-右,8-放大,9-缩小
        speed:1,
      },
      header: {
        'content-type': 'application/x-www-form-urlencoded' // 默认值
      },
      success: (res) => {
        console.log(res.data)
        const code = res.data.code;
        if(code == 10029){
          wx.showToast({
            title: '个人版接口调用超限,请升级企业版',
            icon: 'none',
          })
        } 
        if(code == 200){
          console.log('控制成功')
        } 
      }
    })
  },
})

 4.声音的暂停和播放

  closeSound(){
    this.setData({
      abc:'none',
      abc2:'block'
    })
    livePlayerContext.mute({
      success: ()=>{
        console.log("关闭声音")
     },
     fail: (error)=>{
       console.log(error)
       console.log('关闭声音失败')
     }
    })
  },
  openSound(){
    this.setData({
      abc:'block',
      abc2:'none'
    })
    livePlayerContext.resume({
      success: ()=>{
        console.log("开启声音")
     },
     fail: (error)=>{
       console.log(error)
       console.log('开启声音失败')
     }
    })
  },

   5.语音播报            

// 创建recorderManager对象
const recorderManager = wx.getRecorderManager();
const options = {
  duration: 60000, //指定录音的时长,单位 ms,最大为10分钟(600000),默认为1分钟(60000)
  sampleRate: 16000, //采样率
  numberOfChannels: 1, //录音通道数
  format: 'mp3', //音频格式,有效值 aac/mp3
}
page({
   onLoad:function(){
    // 监听录音结束事件
    recorderManager.onStop((res) => {
      const { recoderTime } = this.data;
      const { tempFilePath } = res;
      wx.uploadFile({
        url: 'https://open.ys7.com/api/lapp/voice/sendonce', //临时语音下发接口
        filePath: tempFilePath, //tempFilePaths[0],
        name: 'voiceFile',
        formData: {
          accessToken: accessToken,
          deviceSerial: deviceSerial,
          channelNo: channelNo,
        },
        header: {
          'content-type': 'amultipart/form-data' // 默认值
        },
        success:(res)=>{
          let data=res.data;
          if(!data.code){
            data=JSON.parse(data);
          }
          if(data.code==200){
            console.log('发送成功');
          }
        },
        fail:(error)=>{
          console.log('发送失败:',error);
        }
      })
    }) 
   },
  // 开始对讲
  speakStart(event){
    recorderManager.start(options);
    console.log("开始对讲");
    this.setData({
      a:'none',
      a2:'block',
    })
  },
    // 结束对讲
    speakEnd(event) {
    console.log("结束对讲")
    recorderManager.stop();
    this.setData({
      a:'block',
      a2:'none',
    })
  }
})

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 uniapp 微信小程序中接入萤石云,您需要完成以下步骤: 1.注册并登录萤石云开发者平台,创建应用并获取 AppKey 和 AppSecret。 2.在 uniapp 项目中安装并引入微信小程序官方提供的“微信小程序 API”插件。 3.在 uniapp 项目中安装并引入“uni-axios”插件,用于发送 HTTP 请求。 4.编写代码实现用户授权登录并获取 AccessToken。 5.编写代码实现调用萤石云提供的 API,例如获取设备列表、打开直播预览等。 下面是一个简单的示例代码: ```javascript // 引入 axios 模块 import axios from 'uni-axios' // 用户授权登录并获取 AccessToken async function login() { const res = await axios.post('https://open.ys7.com/api/lapp/token/get', { appKey: 'your_app_key', appSecret: 'your_app_secret' }) return res.data.data.accessToken } // 获取设备列表 async function getDeviceList(accessToken) { const res = await axios.get('https://open.ys7.com/api/lapp/device/list', { headers: { Authorization: `Bearer ${accessToken}` } }) return res.data.data.deviceList } // 打开直播预览 async function openLivePreview(accessToken, deviceSerial, channelNo) { const res = await axios.post('https://open.ys7.com/api/lapp/live/address/get', { accessToken, deviceSerial, channelNo }) return res.data.data.url } // 调用示例 async function main() { // 用户授权登录并获取 AccessToken const accessToken = await login() // 获取设备列表 const deviceList = await getDeviceList(accessToken) // 打开直播预览 const livePreviewUrl = await openLivePreview(accessToken, deviceList[0].deviceSerial, 1) console.log(livePreviewUrl) } main() ``` 请注意,以上代码仅供参考,实际应用中还需要考虑错误处理、用户体验等方面的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值