Promise改写获取萤石云直播地址接口示例

目录
  • 改写原因
  • 技术选择
  • 源码

改写原因

通常情况下,萤石云的直播地址都是在服务端进行获取,然后存储到数据库中,但是萤石云官方默认同一个ip最多只能使用5个appKey,否则会爆出appKey数量超出安全限制的错误提示。

因此改为前端进行api的调用,来分散ip和appKey之间的绑定(这一点对开发者而言其实意义并不是很大,应为开发者的ip是固定的,测试过程中迟早也会超出数量限制)。

技术选择

需求明确之后,有两种方案可供选择。

  • ajax回调
  • Promise异步编程解决方案

整个直播链接的获取流程大致如下:

可想而知,如果单纯用ajax进行回调,无疑会陷入回调地狱中,于是果断选择了Promise进行改写(进步源于折腾)。

源码

let serial, channelNo;
/**
 * 向服务器查询摄像头直播链接
 *
 * @param cameraId 摄像头id
 * @param perspective 是否允许查看其他用户的摄像头
 *
 * 服务器首先查询数据库直播链接缓存
 * ------如果数据库有缓存,则服务器将直接返回cameraBean的信息
 * ------如果没有缓存,则查找当前用户的accessToken
 * ------------如果数据库保存有accessToken,则返回accessToken
 * ------------数据库没有保存accessToken,则返回appKey/appSecret,由浏览器进行下一步accessToken的获取
 */
function step1(cameraId, perspective) {
    return new Promise(function (resolve, reject) {
            $.ajax({
                type: "GET",
                url: "/cameraManage/getCameraAddress?id=" + cameraId + "&perspective=" + perspective,
                success: function (data) {
                    if (data.state == 'success') {
                        resolve(data.data);
                    } else {
                        layer.msg(data.msg);
                        console.log(data.msg);
                    }
                },
                error: function (e) {
                    layer.msg("网络异常请稍后再试");
                    console.log("error");
                }
            });
        }
    )
}
/**
 * 接收step1返回的结果,判断结果类型
 * ------如果是camera对象或者是accessToken,则直接携带该数据进入step3
 * ------如果是appKey/appSecret,则调用开放平台接口,查询accessToken,并上传至服务器保存,进行step3
 */
function step2(data) {
    serial = data.serial;
    channelNo = data.channelNo;
    return new Promise(function (resolve, reject) {
        if (data.camera || data.accessToken) {//服务器直接返回了摄像头直播信息或accessToken
            resolve(data);
        } else if (data.appKey && data.appSecret) {//服务器返回了appKey && appSecret
            $.ajax({
                type: "POST",
                url: "https://open.ys7.com/api/lapp/token/get",
                data: {
                    appKey: data.appKey,
                    appSecret: data.appSecret
                },
                dataType: "json",
                success: function (data) {
                    let tokenData = data.data;
                    if (data.code == "200" && tokenData) {
                        resolve(tokenData);
                        uploadAccessToken(tokenData.accessToken, tokenData.expireTime, 1);
                    }
                },
                error: function (e) {
                    layer.msg("网络异常请稍后再试");
                    console.log(e);
                }
            });
        }
    });
}
/**
 * 接收step2返回的数据,camera或accessToken
 * ------如果是camera对象,则直接返回
 * ------如果是accessToken,则调用开放平台接口,查询直播链接,并上传至服务器保存
 */
function step3(data) {
    if (data.camera) {
        // console.log("上一步直接返回了camera");
        return data.camera;
    }
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: "https://open.ys7.com/api/lapp/live/video/list",
            data: {
                accessToken: data.accessToken,
            },
            dataType: "json",
            success: function (data) {
                let addressData = data.data;
                if (data.code != '200' || !addressData) {
                    layer.msg("直播链接获取失败");
                    console.log("直播链接获取失败");
                    return;
                }
                for (let i = 0; i < addressData.length; i++) {
                    if (addressData[i].deviceSerial == serial && addressData[i].channelNo == channelNo) {
                        let argObject = {
                            serial: addressData[i].deviceSerial,
                            channelNo: addressData[i].channelNo,
                            flv: addressData[i].flvAddress,
                            flvHd: addressData[i].hdFlvAddress,
                            hls: addressData[i].liveAddress,
                            hlsHd: addressData[i].hdAddress,
                            rtmp: addressData[i].rtmp,
                            rtmpHd: addressData[i].rtmpHd
                        };
                        // console.log("获取了直播链接");
                        // console.log(argObject);
                        resolve(argObject);
                        uploadYs7CameraAddress(argObject);
                        break;
                    }
                }
            },
            error: function (e) {
                layer.msg("网络异常请稍后再试");
                console.log(e);
            }
        });
    });
}
/**
 * 获取摄像头直播链接调用接口
 * @param cameraId 摄像头id
 * @param perspective 是否允许当前用户查看其他用户的摄像头
 */
function getCameraAddress(cameraId, perspective) {
    return step1(cameraId, perspective).then(step2).then(step3);
}
/**
 * 将accessToken上传至服务器保存
 */
function uploadAccessToken(accessToken, expireTime, cameraType) {
    $.ajax({
        type: "POST",
        url: "/cameraManage/uploadAccessToken",
        data: {
            accessToken: accessToken,
            expireTime: expireTime,
            cameraType: cameraType
        },
        dataType: "json",
    });
}
/**
 * 将得到的摄像头链接上传至服务器保存
 */
function uploadYs7CameraAddress(args) {
    args.id = 0;
    $.ajax({
        type: "POST",
        url: "/cameraManage/uploadYs7CameraAddress",
        data: args,
        dataType: "json",
    });
}

之后前端调用摄像头的接口只需要编写如下代码就可以了

getCameraAddress(cameraId, 0).then(data => {
    if (data == null || data == undefined) {
        //未绑定摄像头的错误提示
        ...
        return;
    }
    //获得链接之后的正常操作流程
   ...
});

以上就是Promise改写获取萤石云直播地址接口示例的详细内容,更多关于Promise获取直播地址接口的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue中Promise的使用方法详情

    目录 一.使用 1.promise是一种异步解决方案 2.asyncawait 简介: promise是什么,它可以说是异步编程的一种解决方法,就拿传统的ajax发请求来说,单个还好,如果是一个请求回来的数据还要被其他请求调用,不断地嵌套,可想而知,代码看起来是很乱的,promise主要是为了解决这种情景而出现的. 一.使用 1.promise是一种异步解决方案 由于ajax异步方式请求数据时,我们不能知道数据具体回来的事件,所以过去只能将一个callback函数传递给ajax封装的方法,当aj

  • vue中返回结果是promise的处理方式

    目录 返回结果是promise的处理 对promise的一些理解 1.promise是一种异步解决方案 2.async await 返回结果是promise的处理 调用element-ui中提供的方法是,经常返回结果类型对象是promise, 如果某个函数调用的结果打印后返回的是promise,就马上用saync和await进行优化,async放到方法名称的前面,await放到方法里面 对promise的一些理解 1.promise是一种异步解决方案 由于ajax异步方式请求数据时,我们不能知道

  • 小程序接口的promise化的实现方法

    最近在写微信小程序,为了能用上 async/await 方法,需要把微信提供的异步操作包装成 Promise 对象,为此写了一个简单的 promise(fie) 函数: /** * @function promise - 将 wx 接口 promise 化 * * @param { String|Function } wxApi - 需要转换的接口/接口名 * @param { Object|Any } [originParam = {}] - 原接口要求的参数对象 * @param { Obj

  • JavaScript中Promise的执行顺序详解

    目录 前言 代码分析 then 方法何时调用? 总结 前言 最近看到一个 Promise 相关的很有意思的代码: new Promise((resolve) => { console.log(1) resolve() }).then(() => { new Promise((resolve) => { console.log(2) resolve() }).then(() => { console.log(4) }) }).then(() => { console.log(3

  • 详解将微信小程序接口Promise化并使用async函数

    前言 小程序一直到现在接口还是和刚开始一样使用的回调函数的方式,如果想在小程序中不使用框架的情况下使用Promise+Async怎么办呢? 2019最新解决方案 1. 将接口Promise化 首先建一个文件wxPromise.js const promisify = name => option => { return new Promise((resolve, reject) => wx[name]({ ...option, success: resolve, fail: reject

  • Vue-admin-template 报Uncaught (in promise) error问题及解决

    目录 Vue-admin-template 报Uncaught (in promise) error 问题描述 解决问题 Vue常见错误解决 Vue-admin-template 报Uncaught (in promise) error 问题描述 在使用Vue-admin-template时,配置好后端,在请求时,突然报错 而且后端接到请求了,并且返回数据了. 解决问题 找了半天,发现问题在request.js中. 可以发现,是因为状态码不匹配,所以,直接被抛出异常了! 将状态码2000改成自己

  • Promise改写获取萤石云直播地址接口示例

    目录 改写原因 技术选择 源码 改写原因 通常情况下,萤石云的直播地址都是在服务端进行获取,然后存储到数据库中,但是萤石云官方默认同一个ip最多只能使用5个appKey,否则会爆出appKey数量超出安全限制的错误提示. 因此改为前端进行api的调用,来分散ip和appKey之间的绑定(这一点对开发者而言其实意义并不是很大,应为开发者的ip是固定的,测试过程中迟早也会超出数量限制). 技术选择 需求明确之后,有两种方案可供选择. ajax回调 Promise异步编程解决方案 整个直播链接的获取流

  • Java获取电脑真实IP地址的示例代码

    /** * @author yins * @date 2018年8月12日下午9:53:58 */ import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; /** * 获取本地真正的IP地址,即获得有线或者无线WiFi地址. * 过滤虚拟机.蓝

  • Java 获取本机IP地址的实例代码

    目录 前言 一.规则 二.获取 1.使用 2.工具类 前言 在Java中如何准确的获取到本机IP地址呢?网上大部分的做法是InetAddress.getLocalHost().getHostAddress().这的确能获取到本机IP地址,但是是不准确的.因为忽略了一个问题,网络环境是多变的,一台计算机不同的网卡有多个IP地址,Lan.WiFi.蓝牙.热点.虚拟机网卡等. 一.规则 127.xxx.xxx.xxx 属于 “loopback” 地址,即只能你自己的本机可见,就是本机地址,比较常见的有

  • 微信公众号平台接口开发 获取微信服务器IP地址方法解析

    官方说明 目前看不出来这个接口有哪些具体运用,但是既然有这个接口,那我们就试试能不能用 访问接口 修改WeCharBase.cs,新增以下2个方法 public static string ServerIPs { get { return GetServerIPs(); } } /// <summary>获取所有服务器IP</summary> /// <returns></returns> private static string GetServerIPs

  • c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址 // GetHostIP.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") int main(int argc,

  • 微信小程序如何获取用户收货地址

    获取用户收货地址需要用户点击授权,所以有两种情况,确认授权.取消授权. 情况一,用户第一次访问用户地址授权,并且点击确定授权. 情况二,用户点击取消授权后,再次获取授权 流程: (代码逻辑整理) 1.点击事件触发函数,获取用户当前设置 2.根据用户当前设置中的用户授权结果,判断是否包含收货地址授权 3.如果包含收货地址授权并且没有取消过收货地址授权,直接调用wx.chooseAddress(),获取用户收货地址. 4.取消过收货地址授权,调用wx.openSetting(),调起客户端小程序设置

  • vue2.x 通过后端接口代理,获取qq音乐api的数据示例

    前言: 部分qq音乐的api接口不能直接通过jsonp访问,需要通过官方的代理才能获取,如:歌词,推荐歌单等 1. webpack.dev.conf.js中创建接口: // 开头调用: var express = require('express') var axios = require('axios') var app = express() var apiRoutes = express.Router() app.use('/api', apiRoutes) // devServer的最后

  • java如何获取本机IP地址

    本文实例为大家分享了java实现获取本机IP地址的具体代码,供大家参考,具体内容如下 原因:同一台机子上开着两个web工程,现在有需求需要保证两个项目之间交互的安全问题.因为有个旧的项目,所以尽量不做改动.只能在新项目中做改动. 处理办法:获取本地的IP地址,有请求进来时查看请求的来源,只有来源是本地IP的才予以通过. 代码如下: /** * 任务调度调用拦截器 */ public class TaskControlInterceptor implements Interceptor { //存

  • php与阿里云短信接口接入操作案例分析

    本文实例讲述了php与阿里云短信接口接入操作.分享给大家供大家参考,具体如下: 使用阿里云短信API,需要在控制台获取以下必要参数,其中需要自己手机验证+官方审核多次,尤其审核需要保持耐心. 1. accessKeyId  相当于你的个人账户密钥: 2. accessKeySecret 与上是成对的: 3. SignName  个人签名,在发出去的短信中,这个签名会显示在开头,类似 [签名]亲爱的用户...... 这种格式,SignName需要通过提交审核: 4.TemplateCode  模板

  • SpringBoot实现阿里云短信接口对接的示例代码

    前言 公司最近项目需要一个手机验证码的功能,任务确定后,倍感亚历山大,以为和第三方对接的都好麻烦,查阿里的API.网上大神写的博客,各种查之后才发现,简单的一塌糊涂,这里想说个问题,不知道其他的攻城狮们是不是和我一样的心里,刚接触个没做过的任务时,会一脸懵里的着急,无从下手的感觉,后来会了,就觉得简单的一*,在这里我说一下自己的体会,遇到任何难点,先理思路.任务拆分.逐个查资料,其实一套下来,就不会那种一脸懵逼的干着急... 所需条件 1.阿里云账户 2.开通云通讯中的短信服务 3.申请短信签名

随机推荐