Commit 2310087e03ebc785a3e67f6d85ab4166b6f05ca0
1 parent
c7b2004e
规范化api, 进行中。。。
Showing
14 changed files
with
321 additions
and
76 deletions
pom.xml
| ... | ... | @@ -102,18 +102,15 @@ |
| 102 | 102 | <!-- <version>3.11</version>--> |
| 103 | 103 | <!-- </dependency>--> |
| 104 | 104 | |
| 105 | - <!--Swagger2 --> | |
| 105 | + <!--Swagger3 --> | |
| 106 | 106 | <!--在线文档 --> |
| 107 | 107 | <dependency> |
| 108 | 108 | <groupId>io.springfox</groupId> |
| 109 | - <artifactId>springfox-swagger2</artifactId> | |
| 110 | - <version>2.9.2</version> | |
| 111 | - </dependency> | |
| 112 | - <dependency> | |
| 113 | - <groupId>io.springfox</groupId> | |
| 114 | - <artifactId>springfox-swagger-ui</artifactId> | |
| 115 | - <version>2.6.1</version> | |
| 109 | + <artifactId>springfox-boot-starter</artifactId> | |
| 110 | + <version>3.0.0</version> | |
| 116 | 111 | </dependency> |
| 112 | + | |
| 113 | + <!--参数校验 --> | |
| 117 | 114 | <dependency> |
| 118 | 115 | <groupId>javax.validation</groupId> |
| 119 | 116 | <artifactId>validation-api</artifactId> | ... | ... |
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
| ... | ... | @@ -5,8 +5,10 @@ import java.util.logging.LogManager; |
| 5 | 5 | import org.springframework.boot.SpringApplication; |
| 6 | 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 7 | 7 | import org.springframework.context.ConfigurableApplicationContext; |
| 8 | +import springfox.documentation.oas.annotations.EnableOpenApi; | |
| 8 | 9 | |
| 9 | 10 | @SpringBootApplication |
| 11 | +@EnableOpenApi | |
| 10 | 12 | public class VManageBootstrap extends LogManager { |
| 11 | 13 | private static String[] args; |
| 12 | 14 | private static ConfigurableApplicationContext context; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/Swagger3Config.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiOperation; | |
| 4 | +import org.springframework.context.annotation.Bean; | |
| 5 | +import org.springframework.context.annotation.Configuration; | |
| 6 | +import springfox.documentation.builders.ApiInfoBuilder; | |
| 7 | +import springfox.documentation.builders.PathSelectors; | |
| 8 | +import springfox.documentation.builders.RequestHandlerSelectors; | |
| 9 | +import springfox.documentation.builders.RequestParameterBuilder; | |
| 10 | +import springfox.documentation.schema.ScalarType; | |
| 11 | +import springfox.documentation.service.ApiInfo; | |
| 12 | +import springfox.documentation.service.Contact; | |
| 13 | +import springfox.documentation.spi.DocumentationType; | |
| 14 | +import springfox.documentation.spring.web.plugins.Docket; | |
| 15 | + | |
| 16 | +import java.util.ArrayList; | |
| 17 | +import java.util.List; | |
| 18 | + | |
| 19 | +@Configuration | |
| 20 | +public class Swagger3Config { | |
| 21 | + | |
| 22 | + @Bean | |
| 23 | + public Docket createRestApi() { | |
| 24 | + return new Docket(DocumentationType.OAS_30) | |
| 25 | + .apiInfo(apiInfo()) | |
| 26 | + .select() | |
| 27 | + .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager")) | |
| 28 | + .paths(PathSelectors.any()) | |
| 29 | + .build() | |
| 30 | + .pathMapping("/"); | |
| 31 | + } | |
| 32 | + | |
| 33 | + private ApiInfo apiInfo() { | |
| 34 | + return new ApiInfoBuilder() | |
| 35 | + .title("WVP-PRO 接口文档") | |
| 36 | + .description("更多请咨询服务开发者(18010473990@@163.com)。") | |
| 37 | + .contact(new Contact("Ray。", "http://www.ruiyeclub.cn", "ruiyeclub@foxmail.com")) | |
| 38 | + .version("1.0") | |
| 39 | + .build(); | |
| 40 | + } | |
| 41 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -341,7 +341,7 @@ public class SIPCommander implements ISIPCommander { |
| 341 | 341 | @Override |
| 342 | 342 | public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { |
| 343 | 343 | try { |
| 344 | - | |
| 344 | + if (device == null) return; | |
| 345 | 345 | String ssrc = streamSession.createPlaySsrc(); |
| 346 | 346 | String streamId = null; |
| 347 | 347 | if (rtpEnable) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceConfig.java
| ... | ... | @@ -17,16 +17,22 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 17 | 17 | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| 18 | 18 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 19 | 19 | |
| 20 | +import io.swagger.annotations.Api; | |
| 21 | +import io.swagger.annotations.ApiImplicitParam; | |
| 22 | +import io.swagger.annotations.ApiImplicitParams; | |
| 23 | +import io.swagger.annotations.ApiOperation; | |
| 20 | 24 | import org.slf4j.Logger; |
| 21 | 25 | import org.slf4j.LoggerFactory; |
| 22 | 26 | import org.springframework.beans.factory.annotation.Autowired; |
| 27 | +import org.springframework.http.HttpRequest; | |
| 23 | 28 | import org.springframework.http.ResponseEntity; |
| 24 | 29 | import org.springframework.web.bind.annotation.*; |
| 25 | 30 | import org.springframework.web.context.request.async.DeferredResult; |
| 26 | 31 | |
| 32 | +@Api(tags = "国标设备配置") | |
| 27 | 33 | @CrossOrigin |
| 28 | 34 | @RestController |
| 29 | -@RequestMapping("/api") | |
| 35 | +@RequestMapping("/api/device/config") | |
| 30 | 36 | public class DeviceConfig { |
| 31 | 37 | |
| 32 | 38 | private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class); |
| ... | ... | @@ -42,14 +48,24 @@ public class DeviceConfig { |
| 42 | 48 | |
| 43 | 49 | /** |
| 44 | 50 | * 看守位控制命令API接口 |
| 45 | - * | |
| 46 | - * @param deviceId | |
| 47 | - * @param enabled 看守位使能1:开启,0:关闭 | |
| 48 | - * @param resetTime 自动归位时间间隔(可选) | |
| 49 | - * @param presetIndex 调用预置位编号(可选) | |
| 50 | - * @param channelId 通道编码(可选) | |
| 51 | + * @param deviceId 设备ID | |
| 52 | + * @param channelId 通道ID | |
| 53 | + * @param name 名称 | |
| 54 | + * @param expiration 到期时间 | |
| 55 | + * @param heartBeatInterval 心跳间隔 | |
| 56 | + * @param heartBeatCount 心跳计数 | |
| 57 | + * @return | |
| 51 | 58 | */ |
| 52 | - @GetMapping("/config/{deviceId}/basicParam") | |
| 59 | + @ApiOperation("看守位控制命令") | |
| 60 | + @GetMapping("/basicParam/{deviceId}") | |
| 61 | + @ApiImplicitParams({ | |
| 62 | + @ApiImplicitParam(name = "deviceId", value ="设备ID" ), | |
| 63 | + @ApiImplicitParam(name = "channelId", value ="通道ID" ), | |
| 64 | + @ApiImplicitParam(name = "name", value ="名称" ), | |
| 65 | + @ApiImplicitParam(name = "expiration", value ="到期时间" ), | |
| 66 | + @ApiImplicitParam(name = "heartBeatInterval", value ="心跳间隔" ), | |
| 67 | + @ApiImplicitParam(name = "heartBeatCount", value ="心跳计数" ), | |
| 68 | + }) | |
| 53 | 69 | public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId, |
| 54 | 70 | @RequestParam(required = false) String channelId, |
| 55 | 71 | @RequestParam(required = false) String name, |
| ... | ... | @@ -86,10 +102,18 @@ public class DeviceConfig { |
| 86 | 102 | |
| 87 | 103 | /** |
| 88 | 104 | * 设备配置查询请求API接口 |
| 89 | - * | |
| 90 | - * @param deviceId | |
| 105 | + * @param deviceId 设备ID | |
| 106 | + * @param configType 配置类型 | |
| 107 | + * @param channelId 通道ID | |
| 108 | + * @return | |
| 91 | 109 | */ |
| 92 | - @GetMapping("/config/{deviceId}/query/{configType}") | |
| 110 | + @ApiOperation("设备配置查询请求") | |
| 111 | + @ApiImplicitParams({ | |
| 112 | + @ApiImplicitParam(name = "deviceId", value ="设备ID" ), | |
| 113 | + @ApiImplicitParam(name = "channelId", value ="通道ID" ), | |
| 114 | + @ApiImplicitParam(name = "configType", value ="配置类型" ), | |
| 115 | + }) | |
| 116 | + @GetMapping("/query/{deviceId}/{configType}") | |
| 93 | 117 | public DeferredResult<ResponseEntity<String>> configDownloadApi(@PathVariable String deviceId, |
| 94 | 118 | @PathVariable String configType, |
| 95 | 119 | @RequestParam(required = false) String channelId) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceControl.java
| ... | ... | @@ -17,6 +17,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 17 | 17 | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| 18 | 18 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 19 | 19 | |
| 20 | +import io.swagger.annotations.Api; | |
| 21 | +import io.swagger.annotations.ApiImplicitParam; | |
| 22 | +import io.swagger.annotations.ApiImplicitParams; | |
| 23 | +import io.swagger.annotations.ApiOperation; | |
| 20 | 24 | import org.slf4j.Logger; |
| 21 | 25 | import org.slf4j.LoggerFactory; |
| 22 | 26 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -25,9 +29,10 @@ import org.springframework.http.ResponseEntity; |
| 25 | 29 | import org.springframework.web.bind.annotation.*; |
| 26 | 30 | import org.springframework.web.context.request.async.DeferredResult; |
| 27 | 31 | |
| 32 | +@Api(tags = "国标设备控制") | |
| 28 | 33 | @CrossOrigin |
| 29 | 34 | @RestController |
| 30 | -@RequestMapping("/api") | |
| 35 | +@RequestMapping("/api/device/control") | |
| 31 | 36 | public class DeviceControl { |
| 32 | 37 | |
| 33 | 38 | private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class); |
| ... | ... | @@ -44,10 +49,13 @@ public class DeviceControl { |
| 44 | 49 | /** |
| 45 | 50 | * 远程启动控制命令API接口 |
| 46 | 51 | * |
| 47 | - * @param deviceId | |
| 52 | + * @param deviceId 设备ID | |
| 48 | 53 | */ |
| 49 | - @GetMapping("/control/{deviceId}/teleboot") | |
| 50 | - @PostMapping("/control/{deviceId}/teleboot") | |
| 54 | + @ApiOperation("远程启动控制命令") | |
| 55 | + @ApiImplicitParams({ | |
| 56 | + @ApiImplicitParam(name = "deviceId", value ="设备ID", required = true), | |
| 57 | + }) | |
| 58 | + @GetMapping("/teleboot/{deviceId}") | |
| 51 | 59 | public ResponseEntity<String> teleBootApi(@PathVariable String deviceId) { |
| 52 | 60 | if (logger.isDebugEnabled()) { |
| 53 | 61 | logger.debug("设备远程启动API调用"); |
| ... | ... | @@ -68,11 +76,18 @@ public class DeviceControl { |
| 68 | 76 | /** |
| 69 | 77 | * 录像控制命令API接口 |
| 70 | 78 | * |
| 71 | - * @param deviceId | |
| 79 | + * @param deviceId 设备ID | |
| 72 | 80 | * @param recordCmdStr Record:手动录像,StopRecord:停止手动录像 |
| 73 | 81 | * @param channelId 通道编码(可选) |
| 74 | 82 | */ |
| 75 | - @GetMapping("/control/{deviceId}/record/{recordCmdStr}") | |
| 83 | + @ApiOperation("录像控制命令") | |
| 84 | + @ApiImplicitParams({ | |
| 85 | + @ApiImplicitParam(name = "deviceId", value ="设备ID", required = true), | |
| 86 | + @ApiImplicitParam(name = "channelId", value ="通道编码"), | |
| 87 | + @ApiImplicitParam(name = "recordCmdStr", value ="命令, 可选值:Record(手动录像),StopRecord(停止手动录像)", | |
| 88 | + required = true), | |
| 89 | + }) | |
| 90 | + @GetMapping("/record/{deviceId}/{recordCmdStr}") | |
| 76 | 91 | public DeferredResult<ResponseEntity<String>> recordApi(@PathVariable String deviceId, |
| 77 | 92 | @PathVariable String recordCmdStr, @RequestParam(required = false) String channelId) { |
| 78 | 93 | if (logger.isDebugEnabled()) { |
| ... | ... | @@ -102,10 +117,15 @@ public class DeviceControl { |
| 102 | 117 | /** |
| 103 | 118 | * 报警布防/撤防命令API接口 |
| 104 | 119 | * |
| 105 | - * @param deviceId | |
| 120 | + * @param deviceId 设备ID | |
| 106 | 121 | * @param guardCmdStr SetGuard:布防,ResetGuard:撤防 |
| 107 | 122 | */ |
| 108 | - @GetMapping("/control/{deviceId}/guard/{guardCmdStr}") | |
| 123 | + @ApiOperation("录像控制命令") | |
| 124 | + @ApiImplicitParams({ | |
| 125 | + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true), | |
| 126 | + @ApiImplicitParam(name = "guardCmdStr", value ="命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true) | |
| 127 | + }) | |
| 128 | + @GetMapping("/guard/{deviceId}/{guardCmdStr}") | |
| 109 | 129 | public DeferredResult<ResponseEntity<String>> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) { |
| 110 | 130 | if (logger.isDebugEnabled()) { |
| 111 | 131 | logger.debug("布防/撤防API调用"); |
| ... | ... | @@ -134,11 +154,17 @@ public class DeviceControl { |
| 134 | 154 | /** |
| 135 | 155 | * 报警复位API接口 |
| 136 | 156 | * |
| 137 | - * @param deviceId | |
| 157 | + * @param deviceId 设备ID | |
| 138 | 158 | * @param alarmMethod 报警方式(可选) |
| 139 | 159 | * @param alarmType 报警类型(可选) |
| 140 | 160 | */ |
| 141 | - @GetMapping("/control/{deviceId}/resetAlarm") | |
| 161 | + @ApiOperation("报警复位") | |
| 162 | + @ApiImplicitParams({ | |
| 163 | + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true), | |
| 164 | + @ApiImplicitParam(name = "alarmMethod", value ="报警方式"), | |
| 165 | + @ApiImplicitParam(name = "alarmType", value ="报警类型"), | |
| 166 | + }) | |
| 167 | + @GetMapping("/reset_alarm/{deviceId}") | |
| 142 | 168 | public DeferredResult<ResponseEntity<String>> resetAlarmApi(@PathVariable String deviceId, |
| 143 | 169 | @RequestParam(required = false) String alarmMethod, |
| 144 | 170 | @RequestParam(required = false) String alarmType) { |
| ... | ... | @@ -169,11 +195,15 @@ public class DeviceControl { |
| 169 | 195 | /** |
| 170 | 196 | * 强制关键帧API接口 |
| 171 | 197 | * |
| 172 | - * @param deviceId | |
| 173 | - * @param channelId | |
| 198 | + * @param deviceId 设备ID | |
| 199 | + * @param channelId 通道ID | |
| 174 | 200 | */ |
| 175 | - @GetMapping("/control/{deviceId}/iFrame") | |
| 176 | - @PostMapping("/control/{deviceId}/iFrame") | |
| 201 | + @ApiOperation("强制关键帧") | |
| 202 | + @ApiImplicitParams({ | |
| 203 | + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true), | |
| 204 | + @ApiImplicitParam(name = "channelId", value ="通道ID", required = true), | |
| 205 | + }) | |
| 206 | + @GetMapping("/i_frame/{deviceId}") | |
| 177 | 207 | public ResponseEntity<String> iFrame(@PathVariable String deviceId, |
| 178 | 208 | @RequestParam(required = false) String channelId) { |
| 179 | 209 | if (logger.isDebugEnabled()) { |
| ... | ... | @@ -196,13 +226,21 @@ public class DeviceControl { |
| 196 | 226 | /** |
| 197 | 227 | * 看守位控制命令API接口 |
| 198 | 228 | * |
| 199 | - * @param deviceId | |
| 229 | + * @param deviceId 设备ID | |
| 200 | 230 | * @param enabled 看守位使能1:开启,0:关闭 |
| 201 | 231 | * @param resetTime 自动归位时间间隔(可选) |
| 202 | 232 | * @param presetIndex 调用预置位编号(可选) |
| 203 | 233 | * @param channelId 通道编码(可选) |
| 204 | 234 | */ |
| 205 | - @GetMapping("/control/{deviceId}/homePosition/{enabled}") | |
| 235 | + @ApiOperation("看守位控制") | |
| 236 | + @ApiImplicitParams({ | |
| 237 | + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true), | |
| 238 | + @ApiImplicitParam(name = "enabled", value = "是否开启看守位 1:开启,0:关闭", required = true), | |
| 239 | + @ApiImplicitParam(name = "resetTime", value = "自动归位时间间隔"), | |
| 240 | + @ApiImplicitParam(name = "presetIndex", value = "调用预置位编号"), | |
| 241 | + @ApiImplicitParam(name = "channelId", value ="通道ID"), | |
| 242 | + }) | |
| 243 | + @GetMapping("/home_position/{deviceId}/{enabled}") | |
| 206 | 244 | public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId, |
| 207 | 245 | @PathVariable String enabled, |
| 208 | 246 | @RequestParam(required = false) String resetTime, | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceQuery.java
| ... | ... | @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.device; |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 5 | 5 | import com.github.pagehelper.PageInfo; |
| 6 | +import io.swagger.annotations.*; | |
| 6 | 7 | import org.slf4j.Logger; |
| 7 | 8 | import org.slf4j.LoggerFactory; |
| 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -21,10 +22,11 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 21 | 22 | |
| 22 | 23 | import javax.sip.message.Response; |
| 23 | 24 | |
| 25 | +@Api(tags = "国标设备查询1", value = "国标设备查询") | |
| 24 | 26 | @SuppressWarnings("rawtypes") |
| 25 | 27 | @CrossOrigin |
| 26 | 28 | @RestController |
| 27 | -@RequestMapping("/api") | |
| 29 | +@RequestMapping("/api/device/query") | |
| 28 | 30 | public class DeviceQuery { |
| 29 | 31 | |
| 30 | 32 | private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class); |
| ... | ... | @@ -40,7 +42,16 @@ public class DeviceQuery { |
| 40 | 42 | |
| 41 | 43 | @Autowired |
| 42 | 44 | private DeviceOffLineDetector offLineDetector; |
| 43 | - | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * 使用ID查询国标设备 | |
| 48 | + * @param deviceId 国标ID | |
| 49 | + * @return 国标设备 | |
| 50 | + */ | |
| 51 | + @ApiOperation("使用ID查询国标设备") | |
| 52 | + @ApiImplicitParams({ | |
| 53 | + @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true), | |
| 54 | + }) | |
| 44 | 55 | @GetMapping("/devices/{deviceId}") |
| 45 | 56 | public ResponseEntity<Device> devices(@PathVariable String deviceId){ |
| 46 | 57 | |
| ... | ... | @@ -51,7 +62,18 @@ public class DeviceQuery { |
| 51 | 62 | Device device = storager.queryVideoDevice(deviceId); |
| 52 | 63 | return new ResponseEntity<>(device,HttpStatus.OK); |
| 53 | 64 | } |
| 54 | - | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * 分页查询国标设备 | |
| 68 | + * @param page 当前页 | |
| 69 | + * @param count 每页查询数量 | |
| 70 | + * @return 分页国标列表 | |
| 71 | + */ | |
| 72 | + @ApiOperation("分页查询国标设备") | |
| 73 | + @ApiImplicitParams({ | |
| 74 | + @ApiImplicitParam(name = "page", value = "当前页", required = true), | |
| 75 | + @ApiImplicitParam(name = "count", value = "每页查询数量", required = true), | |
| 76 | + }) | |
| 55 | 77 | @GetMapping("/devices") |
| 56 | 78 | public PageInfo<Device> devices(int page, int count){ |
| 57 | 79 | |
| ... | ... | @@ -73,7 +95,16 @@ public class DeviceQuery { |
| 73 | 95 | * @param channelType 设备 false/子目录 true |
| 74 | 96 | * @return 通道列表 |
| 75 | 97 | */ |
| 98 | + @ApiOperation("分页查询通道") | |
| 76 | 99 | @GetMapping("/devices/{deviceId}/channels") |
| 100 | + @ApiImplicitParams({ | |
| 101 | + @ApiImplicitParam(name="deviceId", value = "设备id", required = true), | |
| 102 | + @ApiImplicitParam(name="page", value = "当前页", required = true), | |
| 103 | + @ApiImplicitParam(name="count", value = "每页查询数量", required = true), | |
| 104 | + @ApiImplicitParam(name="query", value = "查询内容"), | |
| 105 | + @ApiImplicitParam(name="online", value = "是否在线"), | |
| 106 | + @ApiImplicitParam(name="channelType", value = "设备/子目录-> false/true"), | |
| 107 | + }) | |
| 77 | 108 | public ResponseEntity<PageInfo> channels(@PathVariable String deviceId, |
| 78 | 109 | int page, int count, |
| 79 | 110 | @RequestParam(required = false) String query, |
| ... | ... | @@ -89,7 +120,16 @@ public class DeviceQuery { |
| 89 | 120 | PageInfo pageResult = storager.queryChannelsByDeviceId(deviceId, query, channelType, online, page, count); |
| 90 | 121 | return new ResponseEntity<>(pageResult,HttpStatus.OK); |
| 91 | 122 | } |
| 92 | - | |
| 123 | + | |
| 124 | + /** | |
| 125 | + * 同步设备通道 | |
| 126 | + * @param deviceId 设备id | |
| 127 | + * @return | |
| 128 | + */ | |
| 129 | + @ApiOperation("同步设备通道") | |
| 130 | + @ApiImplicitParams({ | |
| 131 | + @ApiImplicitParam(name="deviceId", value = "设备id", required = true), | |
| 132 | + }) | |
| 93 | 133 | @PostMapping("/devices/{deviceId}/sync") |
| 94 | 134 | public DeferredResult<ResponseEntity<Device>> devicesSync(@PathVariable String deviceId){ |
| 95 | 135 | |
| ... | ... | @@ -117,8 +157,17 @@ public class DeviceQuery { |
| 117 | 157 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); |
| 118 | 158 | return result; |
| 119 | 159 | } |
| 120 | - | |
| 121 | - @PostMapping("/devices/{deviceId}/delete") | |
| 160 | + | |
| 161 | + /** | |
| 162 | + * 移除设备 | |
| 163 | + * @param deviceId 设备id | |
| 164 | + * @return | |
| 165 | + */ | |
| 166 | + @ApiOperation("移除设备") | |
| 167 | + @ApiImplicitParams({ | |
| 168 | + @ApiImplicitParam(name="deviceId", value = "设备id", required = true), | |
| 169 | + }) | |
| 170 | + @DeleteMapping("/devices/{deviceId}/delete") | |
| 122 | 171 | public ResponseEntity<String> delete(@PathVariable String deviceId){ |
| 123 | 172 | |
| 124 | 173 | if (logger.isDebugEnabled()) { |
| ... | ... | @@ -140,13 +189,27 @@ public class DeviceQuery { |
| 140 | 189 | } |
| 141 | 190 | |
| 142 | 191 | /** |
| 143 | - * 分页查询通道数 | |
| 192 | + * 分页查询子目录通道 | |
| 193 | + * @param deviceId 通道id | |
| 144 | 194 | * @param channelId 通道id |
| 145 | 195 | * @param page 当前页 |
| 146 | 196 | * @param count 每页条数 |
| 197 | + * @param query 查询内容 | |
| 198 | + * @param online 是否在线 | |
| 199 | + * @param channelType 通道类型 | |
| 147 | 200 | * @return 子通道列表 |
| 148 | 201 | */ |
| 149 | - @GetMapping("/subChannels/{deviceId}/{channelId}/channels") | |
| 202 | + @ApiOperation("分页查询子目录通道") | |
| 203 | + @ApiImplicitParams({ | |
| 204 | + @ApiImplicitParam(name="deviceId", value = "设备id", required = true), | |
| 205 | + @ApiImplicitParam(name="channelId", value = "通道id", required = true), | |
| 206 | + @ApiImplicitParam(name="page", value = "当前页", required = true), | |
| 207 | + @ApiImplicitParam(name="count", value = "每页条数", required = true), | |
| 208 | + @ApiImplicitParam(name="query", value = "查询内容"), | |
| 209 | + @ApiImplicitParam(name="online", value = "是否在线"), | |
| 210 | + @ApiImplicitParam(name="channelType", value = "通道类型, 子目录"), | |
| 211 | + }) | |
| 212 | + @GetMapping("/sub_channels/{deviceId}/{channelId}/channels") | |
| 150 | 213 | public ResponseEntity<PageInfo> subChannels(@PathVariable String deviceId, |
| 151 | 214 | @PathVariable String channelId, |
| 152 | 215 | int page, |
| ... | ... | @@ -168,14 +231,36 @@ public class DeviceQuery { |
| 168 | 231 | return new ResponseEntity<>(pageResult,HttpStatus.OK); |
| 169 | 232 | } |
| 170 | 233 | |
| 234 | + /** | |
| 235 | + * 更新通道信息 | |
| 236 | + * @param deviceId 设备id | |
| 237 | + * @param channel 通道 | |
| 238 | + * @return | |
| 239 | + */ | |
| 240 | + @ApiOperation("更新通道信息") | |
| 241 | + @ApiImplicitParams({ | |
| 242 | + @ApiImplicitParam(name="deviceId", value = "设备id", required = true), | |
| 243 | + @ApiImplicitParam(name="channel", value = "通道", required = true), | |
| 244 | + }) | |
| 171 | 245 | @PostMapping("/channel/update/{deviceId}") |
| 172 | 246 | public ResponseEntity<PageInfo> updateChannel(@PathVariable String deviceId,DeviceChannel channel){ |
| 173 | 247 | storager.updateChannel(deviceId, channel); |
| 174 | 248 | return new ResponseEntity<>(null,HttpStatus.OK); |
| 175 | 249 | } |
| 176 | 250 | |
| 177 | - @GetMapping("/devices/{deviceId}/transport/{streamMode}") | |
| 178 | - @PostMapping("/devices/{deviceId}/transport/{streamMode}") | |
| 251 | + /** | |
| 252 | + * 修改数据流传输模式 | |
| 253 | + * @param deviceId 设备id | |
| 254 | + * @param streamMode 数据流传输模式 | |
| 255 | + * @return | |
| 256 | + */ | |
| 257 | + @ApiOperation("修改数据流传输模式") | |
| 258 | + @ApiImplicitParams({ | |
| 259 | + @ApiImplicitParam(name = "deviceId", value = "设备id", required = true), | |
| 260 | + @ApiImplicitParam(name = "streamMode", value = "数据流传输模式, 取值:" + | |
| 261 | + "UDP(udp传输),TCP-ACTIVE(tcp主动模式,暂不支持),TCP-PASSIVE(tcp被动模式)"), | |
| 262 | + }) | |
| 263 | + @PostMapping("/transport/{deviceId}/{streamMode}") | |
| 179 | 264 | public ResponseEntity<PageInfo> updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){ |
| 180 | 265 | Device device = storager.queryVideoDevice(deviceId); |
| 181 | 266 | device.setStreamMode(streamMode); |
| ... | ... | @@ -186,8 +271,12 @@ public class DeviceQuery { |
| 186 | 271 | /** |
| 187 | 272 | * 设备状态查询请求API接口 |
| 188 | 273 | * |
| 189 | - * @param deviceId | |
| 274 | + * @param deviceId 设备id | |
| 190 | 275 | */ |
| 276 | + @ApiOperation("设备状态查询") | |
| 277 | + @ApiImplicitParams({ | |
| 278 | + @ApiImplicitParam(name = "deviceId", value = "设备id", required = true), | |
| 279 | + }) | |
| 191 | 280 | @GetMapping("/devices/{deviceId}/status") |
| 192 | 281 | public DeferredResult<ResponseEntity<String>> deviceStatusApi(@PathVariable String deviceId) { |
| 193 | 282 | if (logger.isDebugEnabled()) { |
| ... | ... | @@ -216,9 +305,25 @@ public class DeviceQuery { |
| 216 | 305 | |
| 217 | 306 | /** |
| 218 | 307 | * 设备报警查询请求API接口 |
| 219 | - * | |
| 220 | - * @param deviceId | |
| 308 | + * @param deviceId 设备id | |
| 309 | + * @param startPriority 报警起始级别(可选) | |
| 310 | + * @param endPriority 报警终止级别(可选) | |
| 311 | + * @param alarmMethod 报警方式条件(可选) | |
| 312 | + * @param alarmType 报警类型 | |
| 313 | + * @param startTime 报警发生起始时间(可选) | |
| 314 | + * @param endTime 报警发生终止时间(可选) | |
| 315 | + * @return true = 命令发送成功 | |
| 221 | 316 | */ |
| 317 | + @ApiOperation("设备报警查询") | |
| 318 | + @ApiImplicitParams({ | |
| 319 | + @ApiImplicitParam(name = "deviceId", value = "设备id", required = true), | |
| 320 | + @ApiImplicitParam(name = "startPriority", value = "报警起始级别"), | |
| 321 | + @ApiImplicitParam(name = "endPriority", value = "报警终止级别"), | |
| 322 | + @ApiImplicitParam(name = "alarmMethod", value = "报警方式条件"), | |
| 323 | + @ApiImplicitParam(name = "alarmType", value = "报警类型"), | |
| 324 | + @ApiImplicitParam(name = "startTime", value = "报警发生起始时间"), | |
| 325 | + @ApiImplicitParam(name = "endTime", value = "报警发生终止时间"), | |
| 326 | + }) | |
| 222 | 327 | @GetMapping("/alarm/{deviceId}") |
| 223 | 328 | public DeferredResult<ResponseEntity<String>> alarmApi(@PathVariable String deviceId, |
| 224 | 329 | @RequestParam(required = false) String startPriority, | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gbStream/GbStreamController.java
| ... | ... | @@ -5,11 +5,16 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 5 | 5 | import com.genersoft.iot.vmp.vmanager.gbStream.bean.GbStreamParam; |
| 6 | 6 | import com.genersoft.iot.vmp.service.IGbStreamService; |
| 7 | 7 | import com.github.pagehelper.PageInfo; |
| 8 | +import io.swagger.annotations.Api; | |
| 9 | +import io.swagger.annotations.ApiImplicitParam; | |
| 10 | +import io.swagger.annotations.ApiImplicitParams; | |
| 11 | +import io.swagger.annotations.ApiOperation; | |
| 8 | 12 | import org.slf4j.Logger; |
| 9 | 13 | import org.slf4j.LoggerFactory; |
| 10 | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| 11 | 15 | import org.springframework.web.bind.annotation.*; |
| 12 | 16 | |
| 17 | +@Api(tags = "视频流关联到级联平台") | |
| 13 | 18 | @CrossOrigin |
| 14 | 19 | @RestController |
| 15 | 20 | @RequestMapping("/api/gbStream") |
| ... | ... | @@ -24,7 +29,18 @@ public class GbStreamController { |
| 24 | 29 | private IVideoManagerStorager storager; |
| 25 | 30 | |
| 26 | 31 | |
| 27 | - @RequestMapping(value = "/list") | |
| 32 | + /** | |
| 33 | + * 查询国标通道 | |
| 34 | + * @param page 当前页 | |
| 35 | + * @param count 每页条数 | |
| 36 | + * @return | |
| 37 | + */ | |
| 38 | + @ApiOperation("查询国标通道") | |
| 39 | + @ApiImplicitParams({ | |
| 40 | + @ApiImplicitParam(name = "page", value = "当前页", required = true ), | |
| 41 | + @ApiImplicitParam(name = "count", value = "每页条数", required = true ), | |
| 42 | + }) | |
| 43 | + @GetMapping(value = "/list") | |
| 28 | 44 | @ResponseBody |
| 29 | 45 | public PageInfo<GbStream> list(@RequestParam(required = false)Integer page, |
| 30 | 46 | @RequestParam(required = false)Integer count){ |
| ... | ... | @@ -33,11 +49,18 @@ public class GbStreamController { |
| 33 | 49 | } |
| 34 | 50 | |
| 35 | 51 | |
| 36 | - @RequestMapping(value = "/del") | |
| 52 | + /** | |
| 53 | + * 移除国标关联 | |
| 54 | + * @param gbStreamParam | |
| 55 | + * @return | |
| 56 | + */ | |
| 57 | + @ApiOperation("移除国标关联") | |
| 58 | + @ApiImplicitParams({ | |
| 59 | + @ApiImplicitParam(name = "gbStreamParam", value = "GbStreamParam", required = true ), | |
| 60 | + }) | |
| 61 | + @DeleteMapping(value = "/del") | |
| 37 | 62 | @ResponseBody |
| 38 | 63 | public Object del(@RequestBody GbStreamParam gbStreamParam){ |
| 39 | - System.out.println(2222); | |
| 40 | - System.out.println(gbStreamParam.getGbStreams().size()); | |
| 41 | 64 | if (gbStreamService.delPlatformInfo(gbStreamParam.getGbStreams())) { |
| 42 | 65 | return "success"; |
| 43 | 66 | }else { |
| ... | ... | @@ -46,7 +69,17 @@ public class GbStreamController { |
| 46 | 69 | |
| 47 | 70 | } |
| 48 | 71 | |
| 49 | - @RequestMapping(value = "/add") | |
| 72 | + /** | |
| 73 | + * 保存国标关联 | |
| 74 | + * @param gbStreamParam | |
| 75 | + * @return | |
| 76 | + */ | |
| 77 | + @ApiOperation("保存国标关联") | |
| 78 | +// @ApiImplicitParams({ | |
| 79 | +// @ApiImplicitParam(name = "app", value = "视频流应用名", required = true ), | |
| 80 | +// @ApiImplicitParam(name = "gbId", value = "国标ID", required = true ), | |
| 81 | +// }) | |
| 82 | + @PostMapping(value = "/add") | |
| 50 | 83 | @ResponseBody |
| 51 | 84 | public Object add(@RequestBody GbStreamParam gbStreamParam){ |
| 52 | 85 | System.out.println(3333); | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
| ... | ... | @@ -33,7 +33,7 @@ import javax.sip.message.Response; |
| 33 | 33 | |
| 34 | 34 | @CrossOrigin |
| 35 | 35 | @RestController |
| 36 | -@RequestMapping("/api") | |
| 36 | +@RequestMapping("/api/play") | |
| 37 | 37 | public class PlayController { |
| 38 | 38 | |
| 39 | 39 | private final static Logger logger = LoggerFactory.getLogger(PlayController.class); |
| ... | ... | @@ -59,7 +59,7 @@ public class PlayController { |
| 59 | 59 | @Autowired |
| 60 | 60 | private IMediaService mediaService; |
| 61 | 61 | |
| 62 | - @GetMapping("/play/{deviceId}/{channelId}") | |
| 62 | + @GetMapping("/start/{deviceId}/{channelId}") | |
| 63 | 63 | public DeferredResult<ResponseEntity<String>> play(@PathVariable String deviceId, |
| 64 | 64 | @PathVariable String channelId) { |
| 65 | 65 | |
| ... | ... | @@ -79,7 +79,7 @@ public class PlayController { |
| 79 | 79 | return playResult.getResult(); |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | - @PostMapping("/play/{streamId}/stop") | |
| 82 | + @PostMapping("/stop/{streamId}") | |
| 83 | 83 | public DeferredResult<ResponseEntity<String>> playStop(@PathVariable String streamId) { |
| 84 | 84 | |
| 85 | 85 | logger.debug(String.format("设备预览/回放停止API调用,streamId:%s", streamId)); |
| ... | ... | @@ -139,7 +139,7 @@ public class PlayController { |
| 139 | 139 | * @param streamId 流ID |
| 140 | 140 | * @return |
| 141 | 141 | */ |
| 142 | - @PostMapping("/play/{streamId}/convert") | |
| 142 | + @PostMapping("/convert/{streamId}") | |
| 143 | 143 | public ResponseEntity<String> playConvert(@PathVariable String streamId) { |
| 144 | 144 | StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); |
| 145 | 145 | if (streamInfo == null) { |
| ... | ... | @@ -179,7 +179,7 @@ public class PlayController { |
| 179 | 179 | * @param key |
| 180 | 180 | * @return |
| 181 | 181 | */ |
| 182 | - @PostMapping("/play/convert/stop/{key}") | |
| 182 | + @PostMapping("/convertStop/{key}") | |
| 183 | 183 | public ResponseEntity<String> playConvertStop(@PathVariable String key) { |
| 184 | 184 | |
| 185 | 185 | JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(key); | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java
| ... | ... | @@ -28,7 +28,7 @@ import java.util.UUID; |
| 28 | 28 | |
| 29 | 29 | @CrossOrigin |
| 30 | 30 | @RestController |
| 31 | -@RequestMapping("/api") | |
| 31 | +@RequestMapping("/api/playback") | |
| 32 | 32 | public class PlaybackController { |
| 33 | 33 | |
| 34 | 34 | private final static Logger logger = LoggerFactory.getLogger(PlaybackController.class); |
| ... | ... | @@ -51,7 +51,7 @@ public class PlaybackController { |
| 51 | 51 | @Autowired |
| 52 | 52 | private DeferredResultHolder resultHolder; |
| 53 | 53 | |
| 54 | - @GetMapping("/playback/{deviceId}/{channelId}") | |
| 54 | + @GetMapping("/start/{deviceId}/{channelId}") | |
| 55 | 55 | public DeferredResult<ResponseEntity<String>> play(@PathVariable String deviceId, @PathVariable String channelId, String startTime, |
| 56 | 56 | String endTime) { |
| 57 | 57 | |
| ... | ... | @@ -89,7 +89,7 @@ public class PlaybackController { |
| 89 | 89 | return result; |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | - @RequestMapping("/playback/{ssrc}/stop") | |
| 92 | + @RequestMapping("/stop/{ssrc}") | |
| 93 | 93 | public ResponseEntity<String> playStop(@PathVariable String ssrc) { |
| 94 | 94 | |
| 95 | 95 | cmder.streamByeCmd(ssrc); | ... | ... |
src/main/resources/application-dev.yml
| ... | ... | @@ -96,4 +96,10 @@ logging: |
| 96 | 96 | # [根据业务需求配置] |
| 97 | 97 | userSettings: |
| 98 | 98 | # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) |
| 99 | - savePositionHistory: false | |
| 100 | 99 | \ No newline at end of file |
| 100 | + savePositionHistory: false | |
| 101 | + | |
| 102 | +# 在线文档: swagger-ui(生产环境建议关闭) | |
| 103 | +springfox: | |
| 104 | + documentation: | |
| 105 | + swagger-ui: | |
| 106 | + enabled: true | |
| 101 | 107 | \ No newline at end of file | ... | ... |
web_src/src/components/DeviceList.vue
| ... | ... | @@ -136,7 +136,7 @@ |
| 136 | 136 | getDeviceList: function() { |
| 137 | 137 | let that = this; |
| 138 | 138 | this.getDeviceListLoading = true; |
| 139 | - this.$axios.get(`/api/devices`,{ | |
| 139 | + this.$axios.get(`/api/device/query/devices`,{ | |
| 140 | 140 | params: { |
| 141 | 141 | page: that.currentPage, |
| 142 | 142 | count: that.count |
| ... | ... | @@ -167,13 +167,12 @@ |
| 167 | 167 | //gb28181平台对接 |
| 168 | 168 | //刷新设备信息 |
| 169 | 169 | refDevice: function(itemData) { |
| 170 | - ///api/devices/{deviceId}/sync | |
| 171 | 170 | console.log("刷新对应设备:" + itemData.deviceId); |
| 172 | 171 | var that = this; |
| 173 | 172 | that.$refs[itemData.deviceId + 'refbtn' ].loading = true; |
| 174 | 173 | this.$axios({ |
| 175 | 174 | method: 'post', |
| 176 | - url: '/api/devices/' + itemData.deviceId + '/sync' | |
| 175 | + url: '/api/device/query/devices/' + itemData.deviceId + '/sync' | |
| 177 | 176 | }).then(function(res) { |
| 178 | 177 | console.log("刷新设备结果:"+JSON.stringify(res)); |
| 179 | 178 | if (!res.data.deviceId) { |
| ... | ... | @@ -217,7 +216,7 @@ |
| 217 | 216 | let that = this; |
| 218 | 217 | this.$axios({ |
| 219 | 218 | method: 'get', |
| 220 | - url: '/api/devices/' + row.deviceId + '/transport/' + row.streamMode | |
| 219 | + url: '/api/device/query/transport' + row.deviceId + '/' + row.streamMode | |
| 221 | 220 | }).then(function(res) { |
| 222 | 221 | |
| 223 | 222 | }).catch(function(e) { | ... | ... |
web_src/src/components/channelList.vue
| ... | ... | @@ -154,7 +154,7 @@ export default { |
| 154 | 154 | getDeviceChannelList: function () { |
| 155 | 155 | let that = this; |
| 156 | 156 | |
| 157 | - this.$axios.get(`/api/devices/${this.$route.params.deviceId}/channels`, { | |
| 157 | + this.$axios.get(`/api/device/query/devices/${this.$route.params.deviceId}/channels`, { | |
| 158 | 158 | params: { |
| 159 | 159 | page: that.currentPage, |
| 160 | 160 | count: that.count, |
| ... | ... | @@ -188,7 +188,7 @@ export default { |
| 188 | 188 | let that = this; |
| 189 | 189 | this.$axios({ |
| 190 | 190 | method: 'get', |
| 191 | - url: '/api/play/' + deviceId + '/' + channelId | |
| 191 | + url: '/api/play/start/' + deviceId + '/' + channelId | |
| 192 | 192 | }).then(function (res) { |
| 193 | 193 | console.log(res.data) |
| 194 | 194 | let streamId = res.data.streamId; |
| ... | ... | @@ -216,7 +216,7 @@ export default { |
| 216 | 216 | var that = this; |
| 217 | 217 | this.$axios({ |
| 218 | 218 | method: 'post', |
| 219 | - url: '/api/play/' + itemData.streamId + '/stop' | |
| 219 | + url: '/api/play/stop/' + itemData.streamId | |
| 220 | 220 | }).then(function (res) { |
| 221 | 221 | console.log(JSON.stringify(res)); |
| 222 | 222 | that.initData(); |
| ... | ... | @@ -251,7 +251,7 @@ export default { |
| 251 | 251 | showSubchannels: function (channelId) { |
| 252 | 252 | let that = this; |
| 253 | 253 | |
| 254 | - this.$axios.get(`/api/subChannels/${this.deviceId}/${this.parentChannelId}/channels`, { | |
| 254 | + this.$axios.get(`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, { | |
| 255 | 255 | params: { |
| 256 | 256 | page: that.currentPage, |
| 257 | 257 | count: that.count, |
| ... | ... | @@ -282,7 +282,7 @@ export default { |
| 282 | 282 | console.log(row) |
| 283 | 283 | this.$axios({ |
| 284 | 284 | method: 'post', |
| 285 | - url: `/api/channel/update/${this.deviceId}`, | |
| 285 | + url: `/api/device/query/channel/update/${this.deviceId}`, | |
| 286 | 286 | params: row |
| 287 | 287 | }).then(function (res) { |
| 288 | 288 | console.log(JSON.stringify(res)); | ... | ... |
web_src/src/components/dialog/devicePlayer.vue
| ... | ... | @@ -261,7 +261,7 @@ export default { |
| 261 | 261 | this.$refs.videoPlayer.pause() |
| 262 | 262 | that.$axios({ |
| 263 | 263 | method: 'post', |
| 264 | - url: '/api/play/' + that.streamId + '/convert' | |
| 264 | + url: '/api/play/convert/' + that.streamId | |
| 265 | 265 | }).then(function (res) { |
| 266 | 266 | if (res.data.code == 0) { |
| 267 | 267 | that.convertKey = res.data.key; |
| ... | ... | @@ -298,7 +298,7 @@ export default { |
| 298 | 298 | that.$refs.videoPlayer.pause() |
| 299 | 299 | this.$axios({ |
| 300 | 300 | method: 'post', |
| 301 | - url: '/api/play/convert/stop/' + this.convertKey | |
| 301 | + url: '/api/play/convertStop/' + this.convertKey | |
| 302 | 302 | }).then(function (res) { |
| 303 | 303 | if (res.data.code == 0) { |
| 304 | 304 | console.log(res.data.msg) |
| ... | ... | @@ -393,7 +393,7 @@ export default { |
| 393 | 393 | } else { |
| 394 | 394 | this.$axios({ |
| 395 | 395 | method: 'get', |
| 396 | - url: '/api/playback/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + | |
| 396 | + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + | |
| 397 | 397 | row.endTime |
| 398 | 398 | }).then(function (res) { |
| 399 | 399 | var streamInfo = res.data; |
| ... | ... | @@ -408,7 +408,7 @@ export default { |
| 408 | 408 | this.videoUrl = ''; |
| 409 | 409 | this.$axios({ |
| 410 | 410 | method: 'get', |
| 411 | - url: '/api/playback/' + this.streamId + '/stop' | |
| 411 | + url: '/api/playback/stop/' + this.streamId | |
| 412 | 412 | }).then(function (res) { |
| 413 | 413 | if (callback) callback() |
| 414 | 414 | }); | ... | ... |