| | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.*; |
| | | import java.net.ConnectException; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | |
| | | |
| | | @Autowired |
| | | private MediaConfig mediaConfig; |
| | | |
| | | |
| | | |
| | | public interface RequestCallback{ |
| | | void run(JSONObject response); |
| | |
| | | |
| | | return responseJSON; |
| | | } |
| | | |
| | | |
| | | public void sendPostForImg(String api, Map<String, Object> param, String targetPath, String fileName) { |
| | | OkHttpClient client = new OkHttpClient(); |
| | | String url = String.format("http://%s:%s/index/api/%s", mediaConfig.getIp(), mediaConfig.getHttpPort(), api); |
| | | JSONObject responseJSON = null; |
| | | logger.debug(url); |
| | | |
| | | FormBody.Builder builder = new FormBody.Builder(); |
| | | builder.add("secret",mediaConfig.getSecret()); |
| | | if (param != null && param.keySet().size() > 0) { |
| | | for (String key : param.keySet()){ |
| | | if (param.get(key) != null) { |
| | | builder.add(key, param.get(key).toString()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | FormBody body = builder.build(); |
| | | |
| | | Request request = new Request.Builder() |
| | | .post(body) |
| | | .url(url) |
| | | .build(); |
| | | try { |
| | | Response response = client.newCall(request).execute(); |
| | | if (response.isSuccessful()) { |
| | | if (targetPath != null) { |
| | | File snapFolder = new File(targetPath); |
| | | if (!snapFolder.exists()) { |
| | | snapFolder.mkdirs(); |
| | | } |
| | | File snapFile = new File(targetPath + "/" + fileName); |
| | | FileOutputStream outStream = new FileOutputStream(snapFile); |
| | | outStream.write(response.body().bytes()); |
| | | outStream.close(); |
| | | } |
| | | } |
| | | } catch (ConnectException e) { |
| | | logger.error(String.format("连接ZLM失败: %s, %s", e.getCause().getMessage(), e.getMessage())); |
| | | logger.info("请检查media配置并确认ZLM已启动..."); |
| | | }catch (IOException e) { |
| | | logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | public JSONObject getMediaList(String app, String stream, String schema, RequestCallback callback){ |
| | | Map<String, Object> param = new HashMap<>(); |
| | |
| | | param.put("local_port", localPortSStr); |
| | | sendPost("kick_sessions",param, null); |
| | | } |
| | | |
| | | public void getSnap(String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("url", flvUrl); |
| | | param.put("timeout_sec", timeout_sec); |
| | | param.put("expire_sec", expire_sec); |
| | | sendPostForImg("getSnap",param, targetPath, fileName); |
| | | } |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; |
| | | import com.genersoft.iot.vmp.service.IMediaService; |
| | | import com.genersoft.iot.vmp.service.IPlayService; |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.ResourceUtils; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | import javax.sip.ClientTransaction; |
| | | import javax.sip.Dialog; |
| | | import javax.sip.header.CallIdHeader; |
| | | import javax.sip.message.Response; |
| | | import java.io.File; |
| | | import java.io.FileNotFoundException; |
| | | import java.util.UUID; |
| | | |
| | | @Service |
| | |
| | | cmder.closeRTPServer(playResult.getDevice(), channelId); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); |
| | | msg.setData("Timeout"); |
| | | WVPResult wvpResult = new WVPResult(); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg("Timeout"); |
| | | msg.setData(wvpResult); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | result.onCompletion(()->{ |
| | | // 点播结束时调用截图接口 |
| | | try { |
| | | String path = ResourceUtils.getURL("classpath:").getPath()+"static/static/snap/"; |
| | | String fileName = deviceId + "_" + channelId + ".jpg"; |
| | | ResponseEntity responseEntity = (ResponseEntity)result.getResult(); |
| | | if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) { |
| | | WVPResult wvpResult = (WVPResult)responseEntity.getBody(); |
| | | if (wvpResult.getCode() == 0) { |
| | | StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData(); |
| | | String flvUrl = streamInfoForSuccess.getFlv(); |
| | | // 请求截图 |
| | | zlmresTfulUtils.getSnap(flvUrl, 5, 1, path, fileName); |
| | | } |
| | | } |
| | | |
| | | System.out.println(path); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | }); |
| | | if (streamInfo == null) { |
| | | // 发送点播消息 |
| | |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| | | Response response = event.getResponse(); |
| | | cmder.closeRTPServer(playResult.getDevice(), channelId); |
| | | msg.setData(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | WVPResult wvpResult = new WVPResult(); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | msg.setData(wvpResult); |
| | | resultHolder.invokeResult(msg); |
| | | if (errorEvent != null) { |
| | | errorEvent.response(event); |
| | |
| | | if (streamId == null) { |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| | | msg.setData(String.format("点播失败, redis缓存streamId等于null")); |
| | | WVPResult wvpResult = new WVPResult(); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg(String.format("点播失败, redis缓存streamId等于null")); |
| | | msg.setData(wvpResult); |
| | | resultHolder.invokeResult(msg); |
| | | return playResult; |
| | | } |
| | |
| | | if (rtpInfo != null && rtpInfo.getBoolean("exist")) { |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| | | msg.setData(JSON.toJSONString(streamInfo)); |
| | | |
| | | WVPResult wvpResult = new WVPResult(); |
| | | wvpResult.setCode(0); |
| | | wvpResult.setMsg("success"); |
| | | wvpResult.setData(streamInfo); |
| | | msg.setData(wvpResult); |
| | | |
| | | resultHolder.invokeResult(msg); |
| | | if (hookEvent != null) { |
| | | hookEvent.response(JSONObject.parseObject(JSON.toJSONString(streamInfo))); |
| | |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| | | Response response = event.getResponse(); |
| | | msg.setData(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | |
| | | WVPResult wvpResult = new WVPResult(); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | msg.setData(wvpResult); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | } |
| | |
| | | streamInfo.setTransactionInfo(transactionInfo); |
| | | redisCatchStorage.startPlay(streamInfo); |
| | | msg.setData(JSON.toJSONString(streamInfo)); |
| | | |
| | | WVPResult wvpResult = new WVPResult(); |
| | | wvpResult.setCode(0); |
| | | wvpResult.setMsg("sucess"); |
| | | wvpResult.setData(streamInfo); |
| | | msg.setData(wvpResult); |
| | | |
| | | resultHolder.invokeResult(msg); |
| | | } else { |
| | | logger.warn("设备预览API调用失败!"); |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.util.ResourceUtils; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | import java.io.FileNotFoundException; |
| | | import java.util.UUID; |
| | | |
| | | import javax.sip.message.Response; |
| | |
| | | '^/debug': '/' |
| | | } |
| | | }, |
| | | '/static/snap': { |
| | | target: 'http://localhost:18080', |
| | | changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/static/snap': '/static/snap' |
| | | // } |
| | | }, |
| | | |
| | | }, |
| | | |
| | |
| | | |
| | | this.$axios({ |
| | | method: 'get', |
| | | url:"/api/user/login", |
| | | url:"/api/user/login", |
| | | params: loginParam |
| | | }).then(function (res) { |
| | | console.log(JSON.stringify(res)); |
| | |
| | | <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> |
| | | <el-table-column prop="channelId" label="通道编号" width="210"> |
| | | </el-table-column> |
| | | <el-table-column prop="channelId" label="设备编号" width="210"> |
| | | <el-table-column prop="deviceId" label="设备编号" width="210"> |
| | | </el-table-column> |
| | | <el-table-column prop="name" label="通道名称"> |
| | | </el-table-column> |
| | | <el-table-column label="快照" width="80" align="center"> |
| | | <template slot-scope="scope"> |
| | | <img style="max-height: 3rem;max-width: 4rem;" |
| | | :id="scope.row.deviceId + '_' + scope.row.channelId" |
| | | :src="getSnap(scope.row)" |
| | | @error="getSnapErrorEvent($event.target.id)" |
| | | alt=""> |
| | | <!-- <el-image--> |
| | | <!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> |
| | | <!-- :src="getSnap(scope.row)"--> |
| | | <!-- @error="getSnapErrorEvent($event, scope.row)"--> |
| | | <!-- :fit="'contain'">--> |
| | | <!-- <div slot="error" class="image-slot">--> |
| | | <!-- <i class="el-icon-picture-outline"></i>--> |
| | | <!-- </div>--> |
| | | <!-- </el-image>--> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="subCount" label="子节点数"> |
| | | </el-table-column> |
| | |
| | | total: 0, |
| | | beforeUrl: "/deviceList", |
| | | isLoging: false, |
| | | autoList: true |
| | | autoList: true, |
| | | loadSnap:{} |
| | | }; |
| | | }, |
| | | |
| | |
| | | } else { |
| | | this.showSubchannels(); |
| | | } |
| | | |
| | | }, |
| | | initParam: function () { |
| | | this.deviceId = this.$route.params.deviceId; |
| | |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | |
| | | |
| | | }, |
| | | |
| | | //通知设备上传媒体流 |
| | |
| | | method: 'get', |
| | | url: '/api/play/start/' + deviceId + '/' + channelId |
| | | }).then(function (res) { |
| | | console.log(res.data) |
| | | let streamId = res.data.streamId; |
| | | that.isLoging = false; |
| | | if (!!streamId) { |
| | | // that.$refs.devicePlayer.play(res.data, deviceId, channelId, itemData.hasAudio); |
| | | that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { |
| | | streamInfo: res.data, |
| | | hasAudio: itemData.hasAudio |
| | | }); |
| | | that.initData(); |
| | | } else { |
| | | that.$message.error(res.data); |
| | | if (res.data.code == 0) { |
| | | |
| | | setTimeout(()=>{ |
| | | console.log("下载截图") |
| | | let snapId = deviceId + "_" + channelId; |
| | | that.loadSnap[snapId] = 0; |
| | | that.getSnapErrorEvent(snapId) |
| | | },5000) |
| | | that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { |
| | | streamInfo: res.data.data, |
| | | hasAudio: itemData.hasAudio |
| | | }); |
| | | that.initData(); |
| | | }else { |
| | | that.$message.error(res.data.msg); |
| | | } |
| | | }).catch(function (e) {}); |
| | | }, |
| | |
| | | } |
| | | }); |
| | | }, |
| | | getSnap: function (row){ |
| | | return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' |
| | | }, |
| | | getSnapErrorEvent: function (id){ |
| | | |
| | | if (typeof (this.loadSnap[id]) != "undefined") { |
| | | console.log("下载截图" + this.loadSnap[id]) |
| | | if (this.loadSnap[id] > 5) { |
| | | delete this.loadSnap[id]; |
| | | return; |
| | | } |
| | | setTimeout(()=>{ |
| | | this.loadSnap[id] ++ |
| | | document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) |
| | | },1000) |
| | | |
| | | } |
| | | }, |
| | | showDevice: function () { |
| | | this.$router.push(this.beforeUrl).then(() => { |
| | | this.initParam(); |
| | |
| | | <div v-for="index of timeNode" class="timeQuery-label-cell" :style="'left:' + (100.0/timeNode*index).toFixed(4) + '%'"> |
| | | <div class="timeQuery-label-cell-label">{{24/timeNode * index}}</div> |
| | | </div> |
| | | <ul> |
| | | <li v-for="item of allDataList" >{{!!item.name?item.name:item.dname}}</li> |
| | | </ul> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | name: "test", |
| | | data() { |
| | | return { |
| | | allDataList:[], |
| | | timeNode: 24, |
| | | recordData:[ |
| | | { |
| | |
| | | }; |
| | | }, |
| | | mounted() { |
| | | var list1 = [{ |
| | | key: Math.random()*10, |
| | | name: "人1" |
| | | },{ |
| | | key: Math.random()*10, |
| | | name: "人2" |
| | | },{ |
| | | key: Math.random()*10, |
| | | name: "人3" |
| | | }] |
| | | var list2 = [{ |
| | | key: Math.random()*10, |
| | | dname: "部门1" |
| | | },{ |
| | | key: Math.random()*10, |
| | | dname: "部门2" |
| | | },{ |
| | | key: Math.random()*10, |
| | | dname: "部门3" |
| | | }] |
| | | |
| | | var allData = list1.concat(list2) |
| | | allData.sort((a, b)=>{ |
| | | return a.key-b.key; |
| | | }) |
| | | this.allDataList = allData; |
| | | for (let i = 1; i <= 24; i++) { |
| | | console.log("<div class=\"timeQuery-label-cell\" style=\"left: " + (100.0/24*i).toFixed(4) + "%\"></div>") |
| | | } |