diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java index 39e121fdf..4d302fec4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java @@ -150,6 +150,9 @@ public class CommonGBChannel { @Schema(description = "更新时间") private String updateTime; + @Schema(description = "流唯一编号,存在表示正在直播") + private String streamId; + public String encode(String serverDeviceId) { return encode(null, serverDeviceId); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java index 699d18d50..94010da63 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java @@ -179,9 +179,6 @@ public class DeviceChannel extends CommonGBChannel { @Schema(description = "子设备数") private int subCount; - @Schema(description = "流唯一编号,存在表示正在直播") - private String streamId; - @Schema(description = "是否含有音频") private boolean hasAudio; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/ChannelController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/ChannelController.java index 8a6692235..f72278f5f 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/ChannelController.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/ChannelController.java @@ -276,7 +276,7 @@ public class ChannelController { @Operation(summary = "播放通道", security = @SecurityRequirement(name = JwtUtils.HEADER)) @GetMapping("/play") - public DeferredResult> deleteChannelToGroupByGbDevice(HttpServletRequest request, Integer channelId){ + public DeferredResult> play(HttpServletRequest request, Integer channelId){ Assert.notNull(channelId,"参数异常"); CommonGBChannel channel = channelService.getOne(channelId); Assert.notNull(channel, "通道不存在"); @@ -316,4 +316,13 @@ public class ChannelController { channelPlayService.play(channel, null, userSetting.getRecordSip(), callback); return result; } + + @Operation(summary = "停止播放通道", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @GetMapping("/play/stop") + public void stopPlay(Integer channelId){ + Assert.notNull(channelId,"参数异常"); + CommonGBChannel channel = channelService.getOne(channelId); + Assert.notNull(channel, "通道不存在"); + channelPlayService.stopPlay(channel, channel.getStreamId()); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java index f8e09f2a4..05873fa53 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java @@ -580,4 +580,7 @@ public interface CommonGBChannelMapper { @SelectProvider(type = ChannelProvider.class, method = "queryOnlineListsByGbDeviceId") List queryOnlineListsByGbDeviceId(@Param("deviceId") int deviceId); + + @Update("UPDATE wvp_device_channel SET stream_id = #{stream} where id = #{gbId}") + void updateStream(int gbId, String stream); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java index 6259ee978..4f0340eb9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java @@ -16,6 +16,7 @@ public class ChannelProvider { " data_device_id,\n" + " create_time,\n" + " update_time,\n" + + " stream_id,\n" + " record_plan_id,\n" + " coalesce(gb_device_id, device_id) as gb_device_id,\n" + " coalesce(gb_name, name) as gb_name,\n" + @@ -60,6 +61,7 @@ public class ChannelProvider { " wdc.data_device_id,\n" + " wdc.create_time,\n" + " wdc.update_time,\n" + + " wdc.stream_id,\n" + " wdc.record_plan_id,\n" + " coalesce(wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" + " coalesce(wdc.gb_name, wdc.name) as gb_name,\n" + diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java index 10321911f..b510ff391 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java @@ -8,8 +8,10 @@ import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel; import com.genersoft.iot.vmp.gb28181.bean.InviteMessageInfo; import com.genersoft.iot.vmp.gb28181.bean.Platform; import com.genersoft.iot.vmp.gb28181.bean.PlayException; +import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper; import com.genersoft.iot.vmp.gb28181.service.*; import com.genersoft.iot.vmp.service.bean.ErrorCallback; +import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -24,6 +26,9 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { @Autowired private UserSetting userSetting; + @Autowired + private CommonGBChannelMapper channelMapper; + @Autowired private Map sourcePlayServiceMap; @@ -86,7 +91,15 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { log.error("[点播通用通道] 类型编号: {} 不支持实时流预览", dataType); throw new PlayException(Response.BUSY_HERE, "channel not support"); } - sourceChannelPlayService.play(channel, platform, record, callback); + sourceChannelPlayService.play(channel, platform, record, (code, msg, data) -> { + if (code == InviteErrorCode.SUCCESS.getCode()) { + // 将流ID记录到数据库 + if (channel.getDataType() != ChannelDataType.GB28181) { + channelMapper.updateStream(channel.getGbId(), data.getStream()); + } + } + callback.run(code, msg, data); + }); } @Override public void playback(CommonGBChannel channel, Long startTime, Long stopTime, ErrorCallback callback) { diff --git a/web/src/api/commonChannel.js b/web/src/api/commonChannel.js index 6d8a8e436..c76aa22c4 100644 --- a/web/src/api/commonChannel.js +++ b/web/src/api/commonChannel.js @@ -260,6 +260,15 @@ export function playChannel(channelId) { } }) } +export function stopPlayChannel(channelId) { + return request({ + method: 'get', + url: '/api/common/channel/play/stop', + params: { + channelId: channelId + } + }) +} // 前端控制 diff --git a/web/src/router/index.js b/web/src/router/index.js index dcdbc78cf..3a77cea7e 100644 --- a/web/src/router/index.js +++ b/web/src/router/index.js @@ -70,12 +70,19 @@ export const constantRoutes = [ path: '/channel', component: Layout, redirect: '/channel', + onlyIndex: 0, children: [{ - path: '', + path: '/channel', name: 'Channel', component: () => import('@/views/channel/index'), meta: {title: '通道列表', icon: 'channelManger'} - }] + }, + { + path: '/channel/record/:channelId', + name: 'CommonRecord', + component: () => import('@/views/channel/record') + } + ] }, { path: '/device', diff --git a/web/src/store/modules/commonChanel.js b/web/src/store/modules/commonChanel.js index faa730328..4d5ea9fca 100644 --- a/web/src/store/modules/commonChanel.js +++ b/web/src/store/modules/commonChanel.js @@ -30,7 +30,7 @@ import { startCruise, startScan, stopCruise, - stopScan, wiper, getAllForMap + stopScan, wiper, getAllForMap, stopPlayChannel } from '@/api/commonChannel' const actions = { @@ -254,6 +254,16 @@ const actions = { }) }) }, + stopPlayChannel({ commit }, channelId) { + return new Promise((resolve, reject) => { + stopPlayChannel(channelId).then(response => { + const { data } = response + resolve(data) + }).catch(error => { + reject(error) + }) + }) + }, getList({ commit }, param) { return new Promise((resolve, reject) => { getList(param).then(response => { diff --git a/web/src/views/channel/index.vue b/web/src/views/channel/index.vue index 525f33c86..095df07c4 100755 --- a/web/src/views/channel/index.vue +++ b/web/src/views/channel/index.vue @@ -92,7 +92,6 @@ 编辑 + + + + 更多 + + + + 设备录像 + + 云端录像 + + + @@ -184,14 +196,14 @@ export default { updateLooper: 0, // 数据刷新轮训标志 searchStr: '', channelType: '', - online: '', + online: 'true', subStream: '', winHeight: window.innerHeight - 200, currentPage: this.defaultPage | 1, count: this.defaultCount | 15, total: 0, beforeUrl: '/device', - editId: null, + editId: null } }, mounted() { @@ -256,10 +268,8 @@ export default { }) }, queryRecords: function(itemData) { - const deviceId = this.deviceId const channelId = itemData.deviceId - - this.$router.push(`/device/record/${deviceId}/${channelId}`) + this.$router.push(`/channel/record/${channelId}`) }, queryCloudRecords: function(itemData) { const deviceId = this.deviceId @@ -267,42 +277,8 @@ export default { this.$router.push(`/cloudRecord/detail/rtp/${deviceId}_${channelId}`) }, - startRecord: function(itemData) { - this.$store.dispatch('device/deviceRecord', { - deviceId: this.deviceId, - channelId: itemData.deviceId, - recordCmdStr: 'Record' - }).then(data => { - this.$message.success({ - showClose: true, - message: '开始录像成功' - }) - }).catch((error) => { - this.$message.error({ - showClose: true, - message: error.message - }) - }) - }, - stopRecord: function(itemData) { - this.$store.dispatch('device/deviceRecord', { - deviceId: this.deviceId, - channelId: itemData.deviceId, - recordCmdStr: 'StopRecord' - }).then(data => { - this.$message.success({ - showClose: true, - message: '停止录像成功' - }) - }).catch((error) => { - this.$message.error({ - showClose: true, - message: error.message - }) - }) - }, stopDevicePush: function(itemData) { - this.$store.dispatch('play/stop', [itemData.deviceId]).then(data => { + this.$store.dispatch('commonChanel/stopPlayChannel', itemData.gbId).then(data => { this.initData() }).catch((error) => { if (error.response.status === 402) { // 已经停止过 @@ -333,93 +309,11 @@ export default { }, 1000) } }, - showDevice: function() { - // this.$router.push(this.beforeUrl).then(() => { - // this.initParam() - // this.initData() - // }) - this.$emit('show-device') - }, - changeSubchannel(itemData) { - this.beforeUrl = this.$router.currentRoute.path - - var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.deviceId}` - this.$router.push(url).then(() => { - this.searchStr = '' - this.channelType = '' - this.online = '' - this.initParam() - this.initData() - }) - }, - showSubChannels: function() { - this.$store.dispatch('device/querySubChannels', [ - { - page: this.currentPage, - count: this.count, - query: this.searchStr, - online: this.online, - channelType: this.channelType - }, - this.deviceId, - this.parentChannelId - ]) - .then(data => { - this.total = data.total - this.channelList = data.list - this.channelList.forEach(e => { - e.ptzType = e.ptzType + '' - }) - // 防止出现表格错位 - this.$nextTick(() => { - this.$refs.channelListTable.doLayout() - }) - }) - }, search: function() { this.currentPage = 1 this.total = 0 this.initData() }, - updateChannel: function(row) { - this.$store.dispatch('device/changeChannelAudio', { - channelId: row.gbId, - audio: row.hasAudio - }) - }, - subStreamChange: function() { - this.$confirm('确定重置所有通道的码流类型?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(() => { - this.$store.dispatch('device/updateChannelStreamIdentification', { - deviceDbId: this.device.id, - streamIdentification: this.subStream - }) - .then(data => { - this.initData() - }) - .finally(() => { - this.subStream = '' - }) - }).catch(() => { - this.subStream = '' - }) - }, - channelSubStreamChange: function(row) { - this.$store.dispatch('device/updateChannelStreamIdentification', { - deviceDbId: row.deviceDbId, - id: row.id, - streamIdentification: row.streamIdentification - }) - .then(data => { - this.initData() - }) - .finally(() => { - this.subStream = '' - }) - }, refresh: function() { this.initData() }, @@ -432,8 +326,14 @@ export default { closeEdit: function() { this.editId = null this.getChannelList() + }, + moreClick: function(command, itemData) { + if (command === 'records') { + this.queryRecords(itemData) + } else if (command === 'cloudRecords') { + this.queryCloudRecords(itemData) + } } - } } diff --git a/web/src/views/channel/record.vue b/web/src/views/channel/record.vue new file mode 100755 index 000000000..f07b99bdd --- /dev/null +++ b/web/src/views/channel/record.vue @@ -0,0 +1,624 @@ + + + + +