文档

普通IPC设备接入

更新时间:
一键部署

本文为您介绍如何通过设备SDK将普通IPC设备接入物联网平台。

前提条件

已开通智能视频服务

步骤一:创建视频产品和设备

  1. 登录物联网平台控制台

  2. 实例概览页,找到已创建的实例,单击实例名称。

  3. 在实例中创建摄像头设备所属产品,详细操作,请参见创建产品

    部分参数说明如下所示:

    • 所属品类需要选择智能生活 > 家居安防 > 摄像头,您也可以在选择品类面板的搜索框中输入摄像头,搜索该品类并选中。

    • 节点类型需要选择直连设备

      创建产品界面

  4. 创建产品页面的添加设备区域,单击前往添加

  5. 设备页面的设备列表页签,单击添加设备,在添加设备对话框中,输入设备信息,单击确认

    参数

    描述

    DeviceName

    设置设备名称。设备名称在产品内具有唯一性。支持英文字母、数字、短划线(-)、下划线(_)、at(@)、英文句号(.)和英文冒号(:),长度限制为4~32个字符。

    说明

    DeviceName可以为空。为空时,由物联网平台生成一个产品内唯一标识符作为设备的DeviceName。

    备注名称

    设置备注名称。支持中文、英文字母、日文、数字和下划线(_),长度限制为4~64个字符,一个中文或日文占2个字符。

  6. 设备创建成功后,在添加完成对话框,单击前往查看

    设备详情页面,单击查看,您可以查看、复制设备证书信息。设备证书由设备的ProductKey、DeviceName和DeviceSecret组成,是设备与物联网平台进行通信的重要身份认证,建议您妥善保管。

    参数

    说明

    ProductKey

    设备所属产品的ProductKey,即物联网平台为产品颁发的全局唯一标识符。

    DeviceName

    设备在产品内的唯一标识符。DeviceName与设备所属产品的ProductKey组合,作为设备标识,用来与物联网平台进行连接认证和通信。

    DeviceSecret

    物联网平台为设备颁发的设备密钥,用于认证加密。需与DeviceName成对使用。

步骤二:将设备接入物联网平台

本步骤在Linux系统下,运行设备端C语言版本的LinkVisual SDK Demo。推荐在64位的Ubuntu18.04的环境下使用Demo。

  1. 下载LinkVisual SDK Demo

    重要

    下载LinkVisual SDK Demo将默认您同意软件许可协议,下载前请仔细阅读。

  2. 登录Linux虚拟机,将下载的Demo包,上传至Linux虚拟机的开发环境。

  3. 在Demo包所在目录路径下执行以下命令,解压文件夹。

    tar -xf lv_2.1.2-lk_2.3.0-ubuntu.tar.gz
  4. 执行以下命令,打开文件夹。

    cd lv_2.1.2-lk_2.3.0-ubuntu

    文件夹的目录结构如下。

    1.jpg 
    avc_aac_1000k
    avc_aac_1000k.index
    avc_aac_1000k.meta
    avc_aac_500k
    avc_aac_500k.index
    avc_aac_500k.meta
    link_visual_ipc
  5. 执行以下命令,将设备接入智能视频服务。

    ./link_visual_ipc -p ${YourProductKey} -n ${YourDeviceName} -s ${YourDeviceSecret}

    其中,${YourProductKey}、${YourDeviceName}和${YourDeviceSecret}在上一步创建产品和设备时获取。显示如下日志,表示执行成功。

    运行成功

  6. 登录物联网平台控制台

    1. 单击目标企业版实例,在左侧导航栏选择设备管理>设备,查看设备状态

    2. 单击目标设备名称。单击物模型数据页签,在运行状态页签下查看物模型数据。1~3分钟后,单击事件管理页签,查看生成的智能告警事件。

      控制台

步骤三:获取直播播放地址

将IPC设备接入物联网智能视频服务后,需要实现一个HTTP Web Server供前端调用来获取播放地址。实现HTTP Web Server有很多方法,本文以Netty HTTP Server为例,展示获取直播播放地址的方法。您也可以根据实际情况,搭建HTTP Web Server。

本步骤使用的开发环境如下:

  1. 打开IntelliJ IDEA,新建示例工程Demo。

  2. 在工程Demo的pom.xml文件中,添加以下的Maven项目依赖。

    • LinkVisual Java SDK的Maven依赖坐标:

      <dependency>
         <groupId>com.aliyun</groupId>
         <artifactId>aliyun-java-sdk-linkvisual</artifactId>
         <version>1.5.23</version>
      </dependency>
    • 阿里云Java SDK公共包Maven依赖坐标:

      <dependency>
          <groupId>com.aliyun</groupId>
          <artifactId>aliyun-java-sdk-core</artifactId>
          <version>4.5.3</version>
      </dependency>
    • 集成Netty框架:

      <dependency>
          <groupId>io.netty</groupId>
          <artifactId>netty-all</artifactId>
          <version>4.1.29.Final</version>
      </dependency>
  3. src/main/java路径下新建文件SampleHttpServer.java,内容如下。

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.linkvisual.model.v20180120.QueryLiveStreamingRequest;
    import com.aliyuncs.linkvisual.model.v20180120.QueryLiveStreamingResponse;
    import com.aliyuncs.profile.DefaultProfile;
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.codec.http.*;
    import com.aliyuncs.profile.IClientProfile;
    
    import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
    
    /**
     * SampleHttpServer
     */
    public class SampleHttpServer {
    
        private static String LIVE_PATH = "/live/stream";
        private static String RESPONSE_SUCCESS_CODE = "200";
        private static IAcsClient client = null;
    
        private int port;
    
        public SampleHttpServer(int port) {
            this.port = port;
        }
    
        class HttpServerHandler extends ChannelInboundHandlerAdapter {
            @Override
            public void channelReadComplete(ChannelHandlerContext ctx) {
                ctx.flush();
            }
    
            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) {
                if (msg instanceof HttpRequest) {
                    QueryStringDecoder decoder = new QueryStringDecoder(((HttpRequest)msg).uri());
                    if (decoder.path().equals(LIVE_PATH)) {
                        // 从HTTP请求中获取设备ID、实例ID、播放协议等参数。注:此处省略异常处理逻辑
                        String iotId = decoder.parameters().get("iotId").get(0);
                        String scheme = decoder.parameters().get("scheme").get(0);
                        String instanceId = decoder.parameters().get("instanceId").get(0);
    
                        // 获取播放地址接口调用
                        QueryLiveStreamingRequest queryLiveStreamingRequest = new QueryLiveStreamingRequest();
                        queryLiveStreamingRequest.setIotId(iotId);
                        queryLiveStreamingRequest.setIotInstanceId(instanceId);
                        queryLiveStreamingRequest.setScheme(scheme);
                        
                        QueryLiveStreamingResponse queryLiveStreamingResponse = null;
                        try {
                            queryLiveStreamingResponse = client.getAcsResponse(queryLiveStreamingRequest);
                        } catch (Exception e) {
                            // 执行异常
                        }
    
                        if (queryLiveStreamingResponse != null && queryLiveStreamingResponse.getCode().equals(RESPONSE_SUCCESS_CODE)) {
                            // 返回播放地址
                            FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.OK,
                                    Unpooled.wrappedBuffer(queryLiveStreamingResponse.getData().getPath().getBytes()));
                            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
                            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, queryLiveStreamingResponse.getData().getPath().length());
                            response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
                            response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
                            ctx.write(response);
                        } else {
                            // 异常处理
                        }
                    } else {
                        FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST,
                                Unpooled.EMPTY_BUFFER);
                        ctx.write(response);
                    }
                }
            }
        }
    
        class HttpServerInitializer extends ChannelInitializer<SocketChannel> {
            @Override
            public void initChannel(SocketChannel ch) {
                ChannelPipeline p = ch.pipeline();
                p.addLast(new HttpServerCodec());
                p.addLast(new HttpServerHandler());
            }
        }
    
        public void start() {
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.option(ChannelOption.SO_BACKLOG, 1024);
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new HttpServerInitializer());
                try {
                    Channel ch = b.bind(port).sync().channel();
                    ch.closeFuture().sync();
                } catch (InterruptedException e) {}
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    
        public static void main(String[] args) {
            SampleHttpServer httpServer = new SampleHttpServer(8082);
    
            // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
            // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
            // 本示例以将AccessKey和AccessKeySecret保存在环境变量为例说明。
            String accessKeyID = System.getenv("CC_AK_ENV");
            String accessKeySecret = System.getenv("CC_SK_ENV");
            //您的设备所属的地域ID,无需修改。
            String regionId = "cn-shanghai"; 
            //请求域名,无需修改。
            String domain = "linkvisual.cn-shanghai.aliyuncs.com"; 
            //产品Code,无需修改。
            String productCode = "Linkvisual";
            try {
                DefaultProfile.addEndpoint(regionId, regionId, productCode, domain);
                IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyID, accessKeySecret);
    
                client = new DefaultAcsClient(profile);
            } catch (Exception e) {
    
            }
    
            // 启动HTTP服务
            httpServer.start();
        }
    }

    参数

    说明

    accessKeyID

    登录物联网平台控制台,将鼠标指针移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。

    说明

    如果使用RAM用户,您需授予该用户管理物联网平台的权限(AliyunIOTFullAccess)和管理物联网智能视频服务的权限(AliyunLinkVisualFullAccess),否则将连接失败。授权方法请参见授权RAM用户访问物联网平台

    accessKeySecret

  4. 运行程序文件SampleHttpServer.java,获取直播地址并启动HTTP Server。

步骤四:在Web端播放视频

开发Web端播放器后,根据已获取的直播播放地址,您可在Web端观看直播并控制Web端视频播放器。

  • 支持的音频编码协议:AAC

  • 支持的视频编码协议:H.264

  • 支持的浏览器:Chrome、Firefox、Edge、Safari和UC浏览器

  • Web端直播播放器支持的播放协议:HTTP-FLV和HLS

  1. 创建HTML文件web.html,内容如下。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset=utf-8 />
        <title>videojs-contrib-hls embed</title>
        <link href="//g.alicdn.com/code/lib/video.js/7.9.7/video-js.min.css" rel="stylesheet">
        <script src="//g.alicdn.com/code/lib/video.js/7.9.7/video.min.js"></script>
        <script src="//g.alicdn.com/linkplatform/videojs-plugins/0.0.3?videojs-tech-flv.js,videojs-plugin-hls-compat.js"></script>
    </head>
    
    
    <body>
    <div class="container">
        <div id="videoEl" class="video-js vjs-default-skin vjs-fluid"></div>
    </div>
    </body>
    
    <script>
        if (!videojs.getTech('flv')) {
            videojs.registerTech('flv', videojsTechFlv);
        }
        if (!videojs.getPlugin('hlsCompat')) {
            videojs.registerPlugin('hlsCompat', videojsPluginHlsCompat);
        }
    
        function getStreamUrl() {
            //请求播放地址,xx.xx.xx.xx为您的服务器地址,scheme为播放协议类型,iotId为设备ID,instanceId为实例ID
            return fetch('http://xx.xx.xx.xx:8082/live/stream?iotId=${Your_iotId}&scheme=${Your_scheme}&instanceId=${Your_instanceId}')
    
                .then(response => response.text())
                .then(data => {
                    console.log(data);
                    return data;
                });
        }
    
        function getSourceType(url) {
            let type = '';
            if (/\.flv/.test(url)) {
                type = 'video/x-flv';
            } else if (/\.m3u8/.test(url)) {
                type = 'application/x-mpegURL';
            } else if(/\.mp4/.test(url)) {
                type = 'video/mp4';
            }
            return type;
        }
    
        function createPlayer(cb) {
            var videoEl = document.getElementById('videoEl');
            var player = videojs(videoEl, {
                autoplay: false,
                muted: true,
                controls: true,
                preload: 'none',
                loop: false,
                techOrder: ['flv', 'html5'],
                flv: {
                    reconnInterval: 5000,
                    reconnTimes: 10,
                    getStreamUrl,
                    mediaDataSource: {
                        cors: true,
                        withCredentials: true
                    },
                    flvConfig: {
                        lazyLoadMaxDuration: 24 * 60 * 60,
                    },
                },
                html5: {
                    hls: {
                        cacheEncryptionKeys: true,
                    },
                },
            }, cb);
    
            player.on('error', (e) => {
                console.error('videojs error: ', e);
            });
            player.on('flvError', (e) => {
                console.error('flv error: ', e.errorInfo);
            });
    
            var wrappedPlayer = {
                play: function(loadSource) {
                    if (loadSource) {
                        if (!player.paused()) {
                            player.pause();
                        }
                        player.reset();
                        player.removeClass('vjs-paused');
                        player.addClass('vjs-waiting');
                        return getStreamUrl().then((url) => {
                            var source = {
                                src: url,
                                type: getSourceType(url)
                            };
                            player.src(source);
                            player.autoplay(true);
                            player.load();
                        });
                    }
    
                    return player.play();
                },
    
                pause: function() {
                    return player.pause();
                }
            }
    
            return wrappedPlayer;
        }
    
        if (!videojs.getTech('flv')) {
            videojs.registerTech('flv', videojsTechFlv);
        }
        if (!videojs.getPlugin('hlsCompat')) {
            videojs.registerPlugin('hlsCompat', videojsPluginHlsCompat);
        }
    
        const player = createPlayer(function () {
            player.play(true);
        });
    </script>
  2. 执行以下命令,获取视频播放地址。

    return fetch('http://xx.xx.xx.xx:8082/live/stream?iotId=${Your_iotId}&scheme=${Your_scheme}&instanceId=${Your_instanceId}')

    参数

    描述

    xx.xx.xx.xx

    您的服务器IP地址。

    ${Your_iotId}

    用于直播的IPC设备的设备ID,即物联网平台为该设备颁发的ID,设备的唯一标识符。可调用物联网平台QueryDeviceDetail查询。

    ${Your_scheme}

    直播播放协议:

    • flv:FLV播放协议。

    • hls:HLS播放协议。

    ${Your_instanceId}

    实例ID。您可在物联网平台控制台的实例概览页面,查看当前实例的ID。实例的更多信息,请参见实例概述

    重要

    若有ID值,必须传入该ID值,否则调用会失败。若无ID值,则无需传入。

  3. web.html静态页面托管到Web服务器,查看播放效果。请您根据实际情况托管HTML页面,本地Web服务器可选用Apache或Nginx等服务器。

  4. 在浏览器中观看直播视频。同时,可单击页面上的功能按钮,控制播放器。

  • 本页导读 (1)
文档反馈