| | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.jetbrains.annotations.NotNull; |
| | | import org.springframework.core.MethodParameter; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.converter.HttpMessageConverter; |
| | |
| | | |
| | | /** |
| | | * 全局统一返回结果 |
| | | * @author lin |
| | | */ |
| | | @RestControllerAdvice |
| | | public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> { |
| | | |
| | | |
| | | @Override |
| | | public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { |
| | | public boolean supports(@NotNull MethodParameter returnType, @NotNull Class<? extends HttpMessageConverter<?>> converterType) { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { |
| | | public Object beforeBodyWrite(Object body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NotNull ServerHttpRequest request, @NotNull ServerHttpResponse response) { |
| | | // 排除api文档的接口,这个接口不需要统一 |
| | | String[] excludePath = {"/v3/api-docs","/api/v1"}; |
| | | String[] excludePath = {"/v3/api-docs","/api/v1","/index/hook"}; |
| | | for (String path : excludePath) { |
| | | if (request.getURI().getPath().startsWith(path)) { |
| | | return body; |
| | |
| | | } |
| | | |
| | | if (body instanceof String) { |
| | | return JSON.toJSON(WVPResult.success(body)); |
| | | return JSON.toJSONString(WVPResult.success(body)); |
| | | } |
| | | |
| | | return WVPResult.success(body); |
| | |
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | | |
| | | import javax.sip.RequestEvent; |
| | | import java.util.EventObject; |
| | | |
| | | |
| | | /** |
| | | * @author lin |
| | | */ |
| | | public class PlayBackResult<T> { |
| | | private int code; |
| | | private T data; |
| | | private MediaServerItem mediaServerItem; |
| | | private JSONObject response; |
| | | private SipSubscribe.EventResult event; |
| | | private SipSubscribe.EventResult<EventObject> event; |
| | | |
| | | public int getCode() { |
| | | return code; |
| | |
| | | this.response = response; |
| | | } |
| | | |
| | | public SipSubscribe.EventResult getEvent() { |
| | | public SipSubscribe.EventResult<EventObject> getEvent() { |
| | | return event; |
| | | } |
| | | |
| | | public void setEvent(SipSubscribe.EventResult event) { |
| | | public void setEvent(SipSubscribe.EventResult<EventObject> event) { |
| | | this.event = event; |
| | | } |
| | | } |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | |
| | | resultHolder.invokeAllResult(msg); |
| | | } else { |
| | | logger.warn("设备预览API调用失败!"); |
| | | msg.setData("设备预览API调用失败!"); |
| | | msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "设备预览API调用失败!")); |
| | | resultHolder.invokeAllResult(msg); |
| | | } |
| | | } |
| | |
| | | } |
| | | DeferredResult<String> result = new DeferredResult<>(30000L); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid, result); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | RequestMessage requestMessage = new RequestMessage(); |
| | | requestMessage.setId(uuid); |
| | | requestMessage.setKey(key); |
| | | PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); |
| | | String playBackTimeOutTaskKey = UUID.randomUUID().toString(); |
| | | String playBackTimeOutTaskKey = UUID.randomUUID().toString(); |
| | | dynamicTask.startDelay(playBackTimeOutTaskKey, ()->{ |
| | | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| | | playBackResult.setCode(-1); |
| | | playBackResult.setData(msg); |
| | | playBackCallback.call(playBackResult); |
| | | playBackResult.setData(requestMessage); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | |
| | | StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); |
| | | if (streamInfo == null) { |
| | | logger.warn("设备回放API调用失败!"); |
| | | msg.setData("设备回放API调用失败!"); |
| | | playBackResult.setCode(-1); |
| | | playBackResult.setData(msg); |
| | | playBackCallback.call(playBackResult); |
| | | return; |
| | | } |
| | | redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId()); |
| | | msg.setData(JSON.toJSONString(streamInfo)); |
| | | WVPResult<StreamInfo> success = WVPResult.success(streamInfo); |
| | | requestMessage.setData(success); |
| | | playBackResult.setCode(0); |
| | | playBackResult.setData(msg); |
| | | playBackResult.setData(requestMessage); |
| | | playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); |
| | | playBackResult.setResponse(inviteStreamInfo.getResponse()); |
| | | playBackCallback.call(playBackResult); |
| | | }, event -> { |
| | | dynamicTask.stop(playBackTimeOutTaskKey); |
| | | msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | | requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg))); |
| | | playBackResult.setCode(-1); |
| | | playBackResult.setData(msg); |
| | | playBackResult.setData(requestMessage); |
| | | playBackResult.setEvent(event); |
| | | playBackCallback.call(playBackResult); |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | |
| | | } |
| | | |
| | | resultHolder.put(key, uuid, result); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | RequestMessage requestMessage = new RequestMessage(); |
| | | requestMessage.setId(uuid); |
| | | requestMessage.setKey(key); |
| | | WVPResult<StreamInfo> wvpResult = new WVPResult<>(); |
| | | msg.setData(wvpResult); |
| | | requestMessage.setData(wvpResult); |
| | | PlayBackResult<RequestMessage> downloadResult = new PlayBackResult<>(); |
| | | downloadResult.setData(msg); |
| | | downloadResult.setData(requestMessage); |
| | | |
| | | String downLoadTimeOutTaskKey = UUID.randomUUID().toString(); |
| | | dynamicTask.startDelay(downLoadTimeOutTaskKey, ()->{ |
| | |
| | | resultHolder.invokeResult(msg); |
| | | } else { |
| | | logger.warn("设备预览API调用失败!"); |
| | | msg.setData("设备预览API调用失败!"); |
| | | msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "设备预览API调用失败!")); |
| | | resultHolder.invokeResult(msg); |
| | | } |
| | | } |
| | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | |
| | | @Parameter(name = "deviceId", description = "设备国标编号", required = true) |
| | | @Parameter(name = "channelId", description = "通道国标编号", required = true) |
| | | @GetMapping("/start/{deviceId}/{channelId}") |
| | | public DeferredResult<String> play(@PathVariable String deviceId, |
| | | public DeferredResult<WVPResult<String>> play(@PathVariable String deviceId, |
| | | @PathVariable String channelId) { |
| | | |
| | | // 获取可用的zlm |
| | |
| | | @Parameter(name = "deviceId", description = "设备国标编号", required = true) |
| | | @Parameter(name = "channelId", description = "通道国标编号", required = true) |
| | | @GetMapping("/stop/{deviceId}/{channelId}") |
| | | public DeferredResult<String> playStop(@PathVariable String deviceId, @PathVariable String channelId) { |
| | | public JSONObject playStop(@PathVariable String deviceId, @PathVariable String channelId) { |
| | | |
| | | logger.debug(String.format("设备预览/回放停止API调用,streamId:%s_%s", deviceId, channelId )); |
| | | |
| | | String uuid = UUID.randomUUID().toString(); |
| | | DeferredResult<String> result = new DeferredResult<>(); |
| | | if (deviceId == null || channelId == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400); |
| | | } |
| | | |
| | | // 录像查询以channelId作为deviceId查询 |
| | | String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId; |
| | | resultHolder.put(key, uuid, result); |
| | | StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); |
| | | if (streamInfo == null) { |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | msg.setData("点播未找到"); |
| | | resultHolder.invokeAllResult(msg); |
| | | storager.stopPlay(deviceId, channelId); |
| | | return result; |
| | | } |
| | | cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), null, eventResult -> { |
| | | redisCatchStorage.stopPlay(streamInfo); |
| | | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| | | RequestMessage msgForSuccess = new RequestMessage(); |
| | | msgForSuccess.setId(uuid); |
| | | msgForSuccess.setKey(key); |
| | | msgForSuccess.setData(String.format("success")); |
| | | resultHolder.invokeAllResult(msgForSuccess); |
| | | }); |
| | | |
| | | if (deviceId != null || channelId != null) { |
| | | JSONObject json = new JSONObject(); |
| | | json.put("deviceId", deviceId); |
| | | json.put("channelId", channelId); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | msg.setData(json.toString()); |
| | | resultHolder.invokeAllResult(msg); |
| | | } else { |
| | | logger.warn("设备预览/回放停止API调用失败!"); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | msg.setData("streamId null"); |
| | | resultHolder.invokeAllResult(msg); |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "点播未找到"); |
| | | } |
| | | |
| | | // 超时处理 |
| | | result.onTimeout(()->{ |
| | | logger.warn(String.format("设备预览/回放停止超时,deviceId/channelId:%s_%s ", deviceId, channelId)); |
| | | redisCatchStorage.stopPlay(streamInfo); |
| | | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | msg.setData("Timeout"); |
| | | resultHolder.invokeAllResult(msg); |
| | | }); |
| | | return result; |
| | | cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), null, null); |
| | | redisCatchStorage.stopPlay(streamInfo); |
| | | |
| | | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| | | JSONObject json = new JSONObject(); |
| | | json.put("deviceId", deviceId); |
| | | json.put("channelId", channelId); |
| | | return json; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 将不是h264的视频通过ffmpeg 转码为h264 + aac |
| | | * @param streamId 流ID |
| | | * @return |
| | | */ |
| | | @Operation(summary = "将不是h264的视频通过ffmpeg 转码为h264 + aac") |
| | | @Parameter(name = "streamId", description = "视频流ID", required = true) |
| | |
| | | |
| | | /** |
| | | * 结束转码 |
| | | * @param key |
| | | * @return |
| | | */ |
| | | @Operation(summary = "结束转码") |
| | | @Parameter(name = "key", description = "视频流key", required = true) |
| | |
| | | }); |
| | | |
| | | result.onTimeout(() -> { |
| | | logger.warn(String.format("语音广播操作超时, 设备未返回应答指令")); |
| | | logger.warn("语音广播操作超时, 设备未返回应答指令"); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setKey(key); |
| | | msg.setId(uuid); |
| | |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.service.IPlayService; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.util.ObjectUtils; |
| | | import org.springframework.util.StringUtils; |
| | | 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.IVideoManagerStorage; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | /** |
| | | * @author lin |
| | | */ |
| | | @Tag(name = "视频回放") |
| | | @CrossOrigin |
| | | @RestController |
| | |
| | | logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| | | } |
| | | |
| | | DeferredResult<String> result = playService.playBack(deviceId, channelId, startTime, endTime, null, wvpResult->{ |
| | | resultHolder.invokeResult(wvpResult.getData()); |
| | | }); |
| | | |
| | | return result; |
| | | return playService.playBack(deviceId, channelId, startTime, endTime, null, |
| | | playBackResult->resultHolder.invokeResult(playBackResult.getData())); |
| | | } |
| | | |
| | | |
| | |
| | | @GetMapping("/resume/{streamId}") |
| | | public void playResume(@PathVariable String streamId) { |
| | | logger.info("playResume: "+streamId); |
| | | JSONObject json = new JSONObject(); |
| | | StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); |
| | | if (null == streamInfo) { |
| | | json.put("msg", "streamId不存在"); |
| | | logger.warn("streamId不存在!"); |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在"); |
| | | } |
| | |
| | | <i class="el-icon-video-camera" ></i> |
| | | {{ item.substring(0,17)}} |
| | | </el-tag> |
| | | <!-- <a class="el-icon-download" style="color: #409EFF;font-weight: 600;margin-left: 10px;" :href="`${basePath}/${mediaServerId}/record/${recordFile.app}/${recordFile.stream}/${chooseDate}/${item}`" download />--> |
| | | <a class="el-icon-download" style="color: #409EFF;font-weight: 600;margin-left: 10px;" :href="`${basePath}/download.html?url=record/${recordFile.app}/${recordFile.stream}/${chooseDate}/${item}`" target="_blank" /> |
| | | </li> |
| | | </ul> |
| | |
| | | endTime: moment(this.taskTimeRange[1]).format('YYYY-MM-DD HH:mm:ss'), |
| | | } |
| | | }).then(function (res) { |
| | | if (res.data.code === 0 && res.data.msg === "success") { |
| | | if (res.data.code === 0 ) { |
| | | that.showTaskBox = false |
| | | that.getTaskList(false); |
| | | }else { |
| | |
| | | isEnd: isEnd, |
| | | } |
| | | }).then(function (res) { |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | if (isEnd){ |
| | | that.taskListEnded = res.data.data; |
| | | }else { |
| | |
| | | deletePlatformCommit: function(platform) { |
| | | var that = this; |
| | | that.$axios({ |
| | | method: 'delete', |
| | | url:`/api/platform/delete/${platform.serverGBId}` |
| | | method: 'delete', |
| | | url:`/api/platform/delete/${platform.serverGBId}` |
| | | }).then(function (res) { |
| | | if (res.data.code === 0) { |
| | | that.$message({ |
| | |
| | | streamId: row.stream |
| | | } |
| | | }).then((res) => { |
| | | if (res.data == "success") { |
| | | if (res.data.code === 0) { |
| | | that.initData() |
| | | } |
| | | }).catch(function (error) { |
| | |
| | | url: "/api/push/remove_form_gb", |
| | | data: row |
| | | }).then((res) => { |
| | | if (res.data == "success") { |
| | | if (res.data.code === 0) { |
| | | that.initData() |
| | | } |
| | | }).catch(function (error) { |
| | |
| | | count: that.count |
| | | } |
| | | }).then(function (res) { |
| | | that.total = res.data.total; |
| | | for (let i = 0; i < res.data.list.length; i++) { |
| | | res.data.list[i]["startBtnLoading"] = false; |
| | | if (res.data.code === 0) { |
| | | that.total = res.data.data.total; |
| | | for (let i = 0; i < res.data.data.list.length; i++) { |
| | | res.data.data.list[i]["startBtnLoading"] = false; |
| | | } |
| | | that.streamProxyList = res.data.data.list; |
| | | } |
| | | that.streamProxyList = res.data.list; |
| | | that.getListLoading = false; |
| | | that.getListLoading = false; |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | that.getListLoading = false; |
| | |
| | | url:`/api/onvif/search?timeout=3000`, |
| | | }).then((res) =>{ |
| | | this.getListLoading = false; |
| | | if (res.data.code == 0 ){ |
| | | if (res.data.code === 0 ){ |
| | | if (res.data.data.length > 0) { |
| | | this.$refs.onvifEdit.openDialog(res.data.data, (url)=>{ |
| | | if (url != null) { |
| | |
| | | }).then(function (res) { |
| | | that.getListLoading = false; |
| | | that.$set(row, 'startBtnLoading', false) |
| | | if (res.data == "success"){ |
| | | if (res.data.code === 0){ |
| | | that.initData() |
| | | }else { |
| | | that.$message({ |
| | |
| | | count: that.count |
| | | } |
| | | }).then(function (res) { |
| | | that.total = res.data.total; |
| | | that.userList = res.data.list; |
| | | if (res.data.code === 0) { |
| | | that.total = res.data.data.total; |
| | | that.userList = res.data.data.list; |
| | | } |
| | | that.getUserListLoading = false; |
| | | }).catch(function (error) { |
| | | that.getUserListLoading = false; |
| | |
| | | channelType: this.channelType |
| | | } |
| | | }).then( (res) =>{ |
| | | this.total = res.data.total; |
| | | this.deviceChannelList = res.data.list; |
| | | // 防止出现表格错位 |
| | | this.$nextTick(() => { |
| | | this.$refs.channelListTable.doLayout(); |
| | | }) |
| | | if (res.data.code === 0) { |
| | | this.total = res.data.data.total; |
| | | this.deviceChannelList = res.data.data.list; |
| | | // 防止出现表格错位 |
| | | this.$nextTick(() => { |
| | | this.$refs.channelListTable.doLayout(); |
| | | }) |
| | | } |
| | | |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | |
| | | count: this.count, |
| | | } |
| | | }).then((res)=> { |
| | | this.total = res.data.total; |
| | | this.deviceChannelList = res.data.list; |
| | | // 防止出现表格错位 |
| | | this.$nextTick(() => { |
| | | this.$refs.channelListTable.doLayout(); |
| | | }) |
| | | if (res.data.code === 0) { |
| | | this.total = res.data.total; |
| | | this.deviceChannelList = res.data.list; |
| | | // 防止出现表格错位 |
| | | this.$nextTick(() => { |
| | | this.$refs.channelListTable.doLayout(); |
| | | }) |
| | | } |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
New file |
| | |
| | | <template> |
| | | <div ref="container" @dblclick="fullscreenSwich" style="width:100%;height:100%;background-color: #000000;margin:0 auto;"> |
| | | <div class="buttons-box" id="buttonsBox"> |
| | | <div class="buttons-box-left"> |
| | | <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> |
| | | <i v-if="playing" class="iconfont icon-pause jessibuca-btn" @click="pause"></i> |
| | | <i class="iconfont icon-stop jessibuca-btn" @click="destroy"></i> |
| | | <i v-if="isNotMute" class="iconfont icon-audio-high jessibuca-btn" @click="mute()"></i> |
| | | <i v-if="!isNotMute" class="iconfont icon-audio-mute jessibuca-btn" @click="cancelMute()"></i> |
| | | </div> |
| | | <div class="buttons-box-right"> |
| | | <span class="jessibuca-btn">{{ kBps }} kb/s</span> |
| | | <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>--> |
| | | <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>--> |
| | | <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" |
| | | style="font-size: 1rem !important"></i> |
| | | <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i> |
| | | <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i> |
| | | <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | let jessibucaPlayer = {}; |
| | | export default { |
| | | name: 'jessibuca', |
| | | data() { |
| | | return { |
| | | playing: false, |
| | | isNotMute: false, |
| | | quieting: false, |
| | | fullscreen: false, |
| | | loaded: false, // mute |
| | | speed: 0, |
| | | performance: "", // 工作情况 |
| | | kBps: 0, |
| | | btnDom: null, |
| | | videoInfo: null, |
| | | volume: 1, |
| | | rotate: 0, |
| | | vod: true, // 点播 |
| | | forceNoOffscreen: false, |
| | | }; |
| | | }, |
| | | props: ['videoUrl', 'error', 'hasAudio', 'height'], |
| | | mounted() { |
| | | window.onerror = (msg) => { |
| | | // console.error(msg) |
| | | }; |
| | | console.log(this._uid) |
| | | let paramUrl = decodeURIComponent(this.$route.params.url) |
| | | this.$nextTick(() => { |
| | | this.updatePlayerDomSize() |
| | | window.onresize = () => { |
| | | this.updatePlayerDomSize() |
| | | } |
| | | if (typeof (this.videoUrl) == "undefined") { |
| | | this.videoUrl = paramUrl; |
| | | } |
| | | this.btnDom = document.getElementById("buttonsBox"); |
| | | console.log("初始化时的地址为: " + this.videoUrl) |
| | | this.play(this.videoUrl) |
| | | }) |
| | | }, |
| | | watch: { |
| | | videoUrl(newData, oldData) { |
| | | this.play(newData) |
| | | }, |
| | | immediate: true |
| | | }, |
| | | methods: { |
| | | updatePlayerDomSize() { |
| | | let dom = this.$refs.container; |
| | | let width = dom.parentNode.clientWidth |
| | | let height = (9 / 16) * width |
| | | |
| | | const clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight) |
| | | if (height > clientHeight) { |
| | | height = clientHeight |
| | | width = (16 / 9) * height |
| | | } |
| | | |
| | | dom.style.width = width + 'px'; |
| | | dom.style.height = height + "px"; |
| | | }, |
| | | create() { |
| | | let options = {}; |
| | | console.log("hasAudio " + this.hasAudio) |
| | | |
| | | jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign( |
| | | { |
| | | container: this.$refs.container, |
| | | videoBuffer: 0.2, // 最大缓冲时长,单位秒 |
| | | isResize: true, |
| | | decoder: "static/js/jessibuca/decoder.js", |
| | | useMSE: false, |
| | | showBandwidth: false, |
| | | isFlv: true, |
| | | // text: "WVP-PRO", |
| | | // background: "static/images/zlm-logo.png", |
| | | loadingText: "加载中", |
| | | hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio, |
| | | debug: false, |
| | | supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。 |
| | | operateBtns: { |
| | | fullscreen: false, |
| | | screenshot: false, |
| | | play: false, |
| | | audio: false, |
| | | recorder: false, |
| | | }, |
| | | record: "record", |
| | | vod: this.vod, |
| | | forceNoOffscreen: this.forceNoOffscreen, |
| | | isNotMute: this.isNotMute, |
| | | }, |
| | | options |
| | | )); |
| | | let jessibuca = jessibucaPlayer[this._uid]; |
| | | let _this = this; |
| | | jessibuca.on("load", function () { |
| | | console.log("on load init"); |
| | | }); |
| | | |
| | | jessibuca.on("log", function (msg) { |
| | | console.log("on log", msg); |
| | | }); |
| | | jessibuca.on("record", function (msg) { |
| | | console.log("on record:", msg); |
| | | }); |
| | | jessibuca.on("pause", function () { |
| | | _this.playing = false; |
| | | }); |
| | | jessibuca.on("play", function () { |
| | | _this.playing = true; |
| | | }); |
| | | jessibuca.on("fullscreen", function (msg) { |
| | | console.log("on fullscreen", msg); |
| | | _this.fullscreen = msg |
| | | }); |
| | | |
| | | jessibuca.on("mute", function (msg) { |
| | | console.log("on mute", msg); |
| | | _this.isNotMute = !msg; |
| | | }); |
| | | jessibuca.on("audioInfo", function (msg) { |
| | | // console.log("audioInfo", msg); |
| | | }); |
| | | |
| | | jessibuca.on("videoInfo", function (msg) { |
| | | // this.videoInfo = msg; |
| | | console.log("videoInfo", msg); |
| | | |
| | | }); |
| | | |
| | | jessibuca.on("bps", function (bps) { |
| | | // console.log('bps', bps); |
| | | |
| | | }); |
| | | let _ts = 0; |
| | | jessibuca.on("timeUpdate", function (ts) { |
| | | // console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts); |
| | | _ts = ts; |
| | | }); |
| | | |
| | | jessibuca.on("videoInfo", function (info) { |
| | | console.log("videoInfo", info); |
| | | }); |
| | | |
| | | jessibuca.on("error", function (error) { |
| | | console.log("error", error); |
| | | }); |
| | | |
| | | jessibuca.on("timeout", function () { |
| | | console.log("timeout"); |
| | | }); |
| | | |
| | | jessibuca.on('start', function () { |
| | | console.log('start'); |
| | | }) |
| | | |
| | | jessibuca.on("performance", function (performance) { |
| | | let show = "卡顿"; |
| | | if (performance === 2) { |
| | | show = "非常流畅"; |
| | | } else if (performance === 1) { |
| | | show = "流畅"; |
| | | } |
| | | _this.performance = show; |
| | | }); |
| | | jessibuca.on('buffer', function (buffer) { |
| | | // console.log('buffer', buffer); |
| | | }) |
| | | |
| | | jessibuca.on('stats', function (stats) { |
| | | // console.log('stats', stats); |
| | | }) |
| | | |
| | | jessibuca.on('kBps', function (kBps) { |
| | | _this.kBps = Math.round(kBps); |
| | | }); |
| | | |
| | | // 显示时间戳 PTS |
| | | jessibuca.on('videoFrame', function () { |
| | | |
| | | }) |
| | | |
| | | // |
| | | jessibuca.on('metadata', function () { |
| | | |
| | | }); |
| | | }, |
| | | playBtnClick: function (event) { |
| | | this.play(this.videoUrl) |
| | | }, |
| | | play: function (url) { |
| | | console.log(url) |
| | | if (jessibucaPlayer[this._uid]) { |
| | | this.destroy(); |
| | | } |
| | | this.create(); |
| | | jessibucaPlayer[this._uid].on("play", () => { |
| | | this.playing = true; |
| | | this.loaded = true; |
| | | this.quieting = jessibuca.quieting; |
| | | }); |
| | | if (jessibucaPlayer[this._uid].hasLoaded()) { |
| | | jessibucaPlayer[this._uid].play(url); |
| | | } else { |
| | | jessibucaPlayer[this._uid].on("load", () => { |
| | | console.log("load 播放") |
| | | jessibucaPlayer[this._uid].play(url); |
| | | }); |
| | | } |
| | | }, |
| | | pause: function () { |
| | | if (jessibucaPlayer[this._uid]) { |
| | | jessibucaPlayer[this._uid].pause(); |
| | | } |
| | | this.playing = false; |
| | | this.err = ""; |
| | | this.performance = ""; |
| | | }, |
| | | mute: function () { |
| | | if (jessibucaPlayer[this._uid]) { |
| | | jessibucaPlayer[this._uid].mute(); |
| | | } |
| | | }, |
| | | cancelMute: function () { |
| | | if (jessibucaPlayer[this._uid]) { |
| | | jessibucaPlayer[this._uid].cancelMute(); |
| | | } |
| | | }, |
| | | destroy: function () { |
| | | if (jessibucaPlayer[this._uid]) { |
| | | jessibucaPlayer[this._uid].destroy(); |
| | | } |
| | | if (document.getElementById("buttonsBox") == null) { |
| | | this.$refs.container.appendChild(this.btnDom) |
| | | } |
| | | jessibucaPlayer[this._uid] = null; |
| | | this.playing = false; |
| | | this.err = ""; |
| | | this.performance = ""; |
| | | |
| | | }, |
| | | eventcallbacK: function (type, message) { |
| | | // console.log("player 事件回调") |
| | | // console.log(type) |
| | | // console.log(message) |
| | | }, |
| | | fullscreenSwich: function () { |
| | | let isFull = this.isFullscreen() |
| | | jessibucaPlayer[this._uid].setFullscreen(!isFull) |
| | | this.fullscreen = !isFull; |
| | | }, |
| | | isFullscreen: function () { |
| | | return document.fullscreenElement || |
| | | document.msFullscreenElement || |
| | | document.mozFullScreenElement || |
| | | document.webkitFullscreenElement || false; |
| | | } |
| | | }, |
| | | destroyed() { |
| | | if (jessibucaPlayer[this._uid]) { |
| | | jessibucaPlayer[this._uid].destroy(); |
| | | } |
| | | this.playing = false; |
| | | this.loaded = false; |
| | | this.performance = ""; |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .buttons-box { |
| | | width: 100%; |
| | | height: 28px; |
| | | background-color: rgba(43, 51, 63, 0.7); |
| | | position: absolute; |
| | | display: -webkit-box; |
| | | display: -ms-flexbox; |
| | | display: flex; |
| | | left: 0; |
| | | bottom: 0; |
| | | user-select: none; |
| | | z-index: 10; |
| | | } |
| | | |
| | | .jessibuca-btn { |
| | | width: 20px; |
| | | color: rgb(255, 255, 255); |
| | | line-height: 27px; |
| | | margin: 0px 10px; |
| | | padding: 0px 2px; |
| | | cursor: pointer; |
| | | text-align: center; |
| | | font-size: 0.8rem !important; |
| | | } |
| | | |
| | | .buttons-box-right { |
| | | position: absolute; |
| | | right: 0; |
| | | } |
| | | </style> |
| | |
| | | method: 'get', |
| | | url: '/zlm/' + that.mediaServerChoose + '/index/api/getThreadsLoad' |
| | | }).then(function (res) { |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { |
| | | hour12: false |
| | | })); |
| | |
| | | url: '/zlm/' + that.mediaServerChoose + '/index/api/restartServer' |
| | | }).then(function (res) { |
| | | that.getAllSession(); |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '操作完成' |
| | |
| | | method: 'get', |
| | | url:`/api/platform/query/10000/1` |
| | | }).then(function (res) { |
| | | that.platformList = res.data.list; |
| | | that.platformList = res.data.data.list; |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | |
| | | method: 'get', |
| | | url:`/api/device/query/${this.deviceId}/sync_status/`, |
| | | }).then((res) => { |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | if (!this.syncFlag) { |
| | | this.syncFlag = true; |
| | | } |
| | |
| | | url: "/api/role/all" |
| | | }).then((res) => { |
| | | this.loading = true; |
| | | console.info(res) |
| | | res.data |
| | | console.info(res.data.code) |
| | | if (res.data.code === 0) { |
| | | console.info(res.data.data) |
| | | this.options=res.data.data |
| | | |
| | | } |
| | | }).catch((error) => { |
| | | console.error(error) |
| | |
| | | method:"post", |
| | | url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`, |
| | | data: this.form |
| | | }) |
| | | .then((res)=> { |
| | | }).then((res)=> { |
| | | if (res.data.code === 0) { |
| | | if (this.submitCallback)this.submitCallback(this.form) |
| | | }else { |
| | |
| | | password: this.newPassword |
| | | } |
| | | }).then((res)=> { |
| | | if (res.data === "success"){ |
| | | if (res.data.code === 0) { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: '修改成功,请重新登录', |
| | |
| | | userId: this.form.id, |
| | | } |
| | | }).then((res)=> { |
| | | if (res.data === "success"){ |
| | | if (res.data.code === 0) { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: '修改成功', |
| | |
| | | userId: this.form.id, |
| | | } |
| | | }).then((res)=> { |
| | | console.log(res.data) |
| | | if (res.data.msg === "success"){ |
| | | if (res.data.code === 0) { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: '修改成功', |
| | |
| | | channelReduces: that.chooseData |
| | | } |
| | | }).then((res)=>{ |
| | | if (res.data == true) { |
| | | if (res.data.code === 0) { |
| | | that.$message({ |
| | | showClose: true, |
| | | message: '保存成功,', |
| | |
| | | platformId: that.platformId, |
| | | parentId: parentId |
| | | } |
| | | }) |
| | | .then((res)=> { |
| | | }).then((res)=> { |
| | | if (res.data.code === 0) { |
| | | if (typeof(callback) === 'function') { |
| | | callback(res.data.data) |
| | |
| | | id: id, |
| | | platformId: this.platformId, |
| | | } |
| | | }) |
| | | .then((res) => { |
| | | }).then((res) => { |
| | | if (res.data.code === 0) { |
| | | console.log("移除成功") |
| | | node.parent.loaded = false |
| | |
| | | platformId: this.platformId, |
| | | catalogId: id, |
| | | } |
| | | }) |
| | | .then((res)=> { |
| | | }).then((res)=> { |
| | | if (res.data.code === 0) { |
| | | this.defaultCatalogIdSign = id; |
| | | } |
| | |
| | | } |
| | | }) |
| | | .then(function (res) { |
| | | that.total = res.data.total; |
| | | that.gbStreams = res.data.list; |
| | | that.gbChoosechannel = {}; |
| | | // 防止出现表格错位 |
| | | that.$nextTick(() => { |
| | | if (res.data.code === 0) { |
| | | that.total = res.data.data.total; |
| | | that.gbStreams = res.data.data.list; |
| | | that.gbChoosechannel = {}; |
| | | // 防止出现表格错位 |
| | | that.$nextTick(() => { |
| | | that.$refs.gbStreamsTable.doLayout(); |
| | | // 默认选中 |
| | | that.eventEnable = true; |
| | | }) |
| | | that.eventEnable = true; |
| | | }) |
| | | } |
| | | }) |
| | | .catch(function (error) { |
| | | console.log(error); |
| | |
| | | params: this.form |
| | | }).then((res) => { |
| | | console.log(res.data) |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | this.listChangeCallback() |
| | | }else { |
| | | this.$message({ |
| | |
| | | this.playFromStreamInfo(false, streamInfo) |
| | | }, |
| | | getUrlByStreamInfo(){ |
| | | console.log(this.streamInfo) |
| | | if (location.protocol === "https:") { |
| | | this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]] |
| | | }else { |
| | |
| | | this.$refs[this.activePlayer].pause() |
| | | that.$axios({ |
| | | method: 'post', |
| | | url: '/api/gb_record/convert/' + that.streamId |
| | | url: '/api/play/convert/' + that.streamId |
| | | }).then(function (res) { |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | that.convertKey = res.data.key; |
| | | setTimeout(()=>{ |
| | | that.isLoging = false; |
| | |
| | | } |
| | | }).then((res) => { |
| | | console.log(res.data) |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | if (res.data.data != null) { |
| | | this.listChangeCallback(res.data.data) |
| | | }else { |
| | |
| | | url:`/api/push/save_to_gb`, |
| | | data: this.proxyParam |
| | | }).then( (res) => { |
| | | if (res.data == "success") { |
| | | if (res.data.code === 0) { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: "保存成功", |
| | |
| | | method: 'get', |
| | | url: `/api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}` |
| | | }).then((res)=> { |
| | | console.log(res) |
| | | console.log(res.data.progress) |
| | | this.streamInfo = res.data; |
| | | if (parseFloat(res.data.progress) == 1) { |
| | | this.percentage = 100; |
| | | }else { |
| | | this.percentage = (res.data.progress*100).toFixed(1); |
| | | if (res.data.code === 0) { |
| | | this.streamInfo = res.data.data; |
| | | if (parseFloat(res.data.progress) == 1) { |
| | | this.percentage = 100; |
| | | }else { |
| | | this.percentage = (res.data.progress*100).toFixed(1); |
| | | } |
| | | if (callback)callback(); |
| | | } |
| | | if (callback)callback(); |
| | | |
| | | }).catch((e) =>{ |
| | | |
| | | }); |
| | |
| | | endTime: null, |
| | | } |
| | | }).then((res) =>{ |
| | | if (res.data.code === 0 && res.data.msg === "success") { |
| | | if (res.data.code === 0 ) { |
| | | // 查询进度 |
| | | this.title = "录像文件处理中..." |
| | | this.taskId = res.data.data; |
| | |
| | | } |
| | | }).then((res) => { |
| | | console.log(res) |
| | | if (res.data.code == 0) { |
| | | if (res.data.code === 0) { |
| | | this.percentage = parseFloat(res.data.data.percentage)*100 |
| | | if (res.data.data[0].percentage === '1') { |
| | | this.getProgressForFileRun = false; |
| | |
| | | method: 'get', |
| | | url: '/api/play/start/' + deviceId + '/' + channelId |
| | | }).then(function (res) { |
| | | // that.isLoging = false; |
| | | console.log('=====----=====') |
| | | console.log(res) |
| | | if (res.data.code === 0 && res.data.data) { |
| | | itemData.playUrl = res.data.data.httpsFlv |
| | | that.setPlayUrl(res.data.data.ws_flv, idxTmp) |
| | |
| | | }).then(function (res) { |
| | | that.isLoging = false; |
| | | if (res.data.code === 0) { |
| | | |
| | | that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { |
| | | streamInfo: res.data.data, |
| | | hasAudio: channel.hasAudio |
| | |
| | | |
| | | getAllDeviceListIteration(deviceList, currentPage, count, callback, endCallback, errorCallback) { |
| | | this.getDeviceList(currentPage, count, (data) => { |
| | | if (data.list) { |
| | | if (typeof (callback) == "function") callback(data.list) |
| | | deviceList = deviceList.concat(data.list); |
| | | if (deviceList.length < data.total) { |
| | | if (data.code === 0 && data.data.list) { |
| | | if (typeof (callback) == "function") callback(data.data.list) |
| | | deviceList = deviceList.concat(data.data.list); |
| | | if (deviceList.length < data.data.total) { |
| | | currentPage ++ |
| | | this.getAllDeviceListIteration(deviceList, currentPage, count, callback, endCallback, errorCallback) |
| | | }else { |
| | |
| | | }).catch(errorCallback); |
| | | } |
| | | |
| | | getTree(deviceId, id, param3, param4) { |
| | | |
| | | } |
| | | |
| | | getTree(deviceId, parentId, onlyCatalog, callback, endCallback, errorCallback) { |
| | | let currentPage = 1; |
| | | let count = 100; |
| | |
| | | |
| | | getTreeIteration(deviceId, parentId, onlyCatalog, catalogList, currentPage, count, callback, endCallback, errorCallback) { |
| | | this.getTreeInfo(deviceId, parentId, onlyCatalog, currentPage, count, (data) => { |
| | | if (data.list) { |
| | | if (typeof (callback) == "function") callback(data.list) |
| | | catalogList = catalogList.concat(data.list); |
| | | if (catalogList.length < data.total) { |
| | | if (data.code === 0 && data.data.list) { |
| | | if (typeof (callback) == "function") callback(data.data.list) |
| | | catalogList = catalogList.concat(data.data.list); |
| | | if (catalogList.length < data.data.total) { |
| | | currentPage ++ |
| | | this.getTreeIteration(deviceId, parentId, onlyCatalog, catalogList, currentPage, count, callback, endCallback, errorCallback) |
| | | }else { |