临时提交

pull/1642/head
panlinlin 2024-08-07 23:45:29 +08:00
parent fbbb4cb704
commit 3e220a2c1e
15 changed files with 302 additions and 79 deletions

View File

@ -97,9 +97,6 @@ public class ParentPlatform {
@Schema(description = "是否作为消息通道") @Schema(description = "是否作为消息通道")
private boolean asMessageChannel; private boolean asMessageChannel;
@Schema(description = "是否作为消息通道")
private boolean autoPushChannel;
@Schema(description = "点播回复200OK使用次IP") @Schema(description = "点播回复200OK使用次IP")
private String sendStreamIp; private String sendStreamIp;

View File

@ -32,6 +32,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
@ -90,9 +91,8 @@ public class PlayController {
@PathVariable String channelId) { @PathVariable String channelId) {
log.info("[开始点播] deviceId{}, channelId{}, ", deviceId, channelId); log.info("[开始点播] deviceId{}, channelId{}, ", deviceId, channelId);
if (ObjectUtils.isEmpty(deviceId) || ObjectUtils.isEmpty(channelId)) { Assert.notNull(deviceId, "设备国标编号不可为NULL");
throw new ControllerException(ErrorCode.ERROR400); Assert.notNull(channelId, "通道国标编号不可为NULL");
}
// 获取可用的zlm // 获取可用的zlm
Device device = deviceService.getDevice(deviceId); Device device = deviceService.getDevice(deviceId);
MediaServer newMediaServerItem = playService.getNewMediaServerItem(device); MediaServer newMediaServerItem = playService.getNewMediaServerItem(device);

View File

@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.Hook;
import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.event.hook.HookType;
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
@ -597,10 +598,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
sendRtpItem.setPlayType(InviteStreamType.PUSH); sendRtpItem.setPlayType(InviteStreamType.PUSH);
if (streamPushItem != null) { if (streamPushItem != null) {
// 从redis查询是否正在接收这个推流 // 从redis查询是否正在接收这个推流
OnStreamChangedHookParam pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream()); MediaArrivalEvent mediaArrivalEvent = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream());
if (pushListItem != null) { if (mediaArrivalEvent != null) {
sendRtpItem.setServerId(pushListItem.getSeverId()); sendRtpItem.setServerId(mediaArrivalEvent.getServerId());
sendRtpItem.setMediaServerId(pushListItem.getMediaServerId()); sendRtpItem.setMediaServerId(mediaArrivalEvent.getMediaServer().getId());
redisCatchStorage.updateSendRTPSever(sendRtpItem); redisCatchStorage.updateSendRTPSever(sendRtpItem);
// 开始推流 // 开始推流

View File

@ -4,12 +4,16 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.Map; import java.util.Map;
/** /**
* *
*/ */
public class MediaArrivalEvent extends MediaEvent { public class MediaArrivalEvent extends MediaEvent {
public MediaArrivalEvent(Object source) { public MediaArrivalEvent(Object source) {
super(source); super(source);
@ -28,55 +32,29 @@ public class MediaArrivalEvent extends MediaEvent {
return mediaArrivalEvent; return mediaArrivalEvent;
} }
@Getter
@Setter
private MediaInfo mediaInfo; private MediaInfo mediaInfo;
@Getter
@Setter
private String callId; private String callId;
@Getter
@Setter
private OnStreamChangedHookParam hookParam; private OnStreamChangedHookParam hookParam;
@Getter
@Setter
private StreamContent streamInfo; private StreamContent streamInfo;
@Getter
@Setter
private Map<String, String> paramMap; private Map<String, String> paramMap;
public MediaInfo getMediaInfo() { @Getter
return mediaInfo; @Setter
} private String serverId;
public void setMediaInfo(MediaInfo mediaInfo) {
this.mediaInfo = mediaInfo;
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public OnStreamChangedHookParam getHookParam() {
return hookParam;
}
public void setHookParam(OnStreamChangedHookParam hookParam) {
this.hookParam = hookParam;
}
public StreamContent getStreamInfo() {
return streamInfo;
}
public void setStreamInfo(StreamContent streamInfo) {
this.streamInfo = streamInfo;
}
public Map<String, String> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, String> paramMap) {
this.paramMap = paramMap;
}
} }

View File

@ -216,7 +216,7 @@ public interface IRedisCatchStorage {
void addPushListItem(String app, String stream, MediaArrivalEvent param); void addPushListItem(String app, String stream, MediaArrivalEvent param);
OnStreamChangedHookParam getPushListItem(String app, String stream); MediaArrivalEvent getPushListItem(String app, String stream);
void removePushListItem(String app, String stream, String mediaServerId); void removePushListItem(String app, String stream, String mediaServerId);

View File

@ -696,9 +696,9 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
} }
@Override @Override
public OnStreamChangedHookParam getPushListItem(String app, String stream) { public MediaArrivalEvent getPushListItem(String app, String stream) {
String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream; String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream;
return (OnStreamChangedHookParam)redisTemplate.opsForValue().get(key); return (MediaArrivalEvent)redisTemplate.opsForValue().get(key);
} }
@Override @Override

View File

@ -70,6 +70,12 @@ public class StreamPush extends CommonGBChannel implements Comparable<StreamPush
@Schema(description = "是否正在推流") @Schema(description = "是否正在推流")
private boolean pushing; private boolean pushing;
/**
* 线
*/
@Schema(description = "拉起离线推流")
private boolean autoPushChannel;
@Override @Override
public int compareTo(@NotNull StreamPush streamPushItem) { public int compareTo(@NotNull StreamPush streamPushItem) {
return Long.valueOf(DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(this.createTime) return Long.valueOf(DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(this.createTime)

View File

@ -14,8 +14,10 @@ import com.genersoft.iot.vmp.streamPush.bean.BatchRemoveParam;
import com.genersoft.iot.vmp.streamPush.bean.StreamPush; import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.streamPush.bean.StreamPushExcelDto; import com.genersoft.iot.vmp.streamPush.bean.StreamPushExcelDto;
import com.genersoft.iot.vmp.streamPush.enent.StreamPushUploadFileHandler; import com.genersoft.iot.vmp.streamPush.enent.StreamPushUploadFileHandler;
import com.genersoft.iot.vmp.streamPush.service.IStreamPushPlayService;
import com.genersoft.iot.vmp.streamPush.service.IStreamPushService; import com.genersoft.iot.vmp.streamPush.service.IStreamPushService;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -27,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
@ -48,6 +51,9 @@ public class StreamPushController {
@Autowired @Autowired
private IStreamPushService streamPushService; private IStreamPushService streamPushService;
@Autowired
private IStreamPushPlayService streamPushPlayService;
@Autowired @Autowired
private IMediaServerService mediaServerService; private IMediaServerService mediaServerService;
@ -234,4 +240,23 @@ public class StreamPushController {
} }
streamPushService.batchRemove(ids.getIds()); streamPushService.batchRemove(ids.getIds());
} }
@GetMapping(value = "/start")
@ResponseBody
@Operation(summary = "开始播放", security = @SecurityRequirement(name = JwtUtils.HEADER))
public DeferredResult<WVPResult<StreamContent>> batchStop(Integer id){
Assert.notNull(id, "推流ID不可为NULL");
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
result.onTimeout(()->{
WVPResult<StreamContent> fail = WVPResult.fail(ErrorCode.ERROR100.getCode(), "等待推流超时");
result.setResult(fail);
});
streamPushPlayService.start(id, streamInfo -> {
if (streamInfo != null) {
WVPResult<StreamContent> success = WVPResult.success(new StreamContent(streamInfo));
result.setResult(success);
}
});
return result;
}
} }

View File

@ -116,7 +116,7 @@ public interface StreamPushMapper {
Map<String, StreamPush> getAllGBId(); Map<String, StreamPush> getAllGBId();
@Select("SELECT st.*, st.id as stream_push_id, wdc.*, wdc.id as gb_id FROM wvp_stream_push st LEFT join wvp_device_channel wdc on st.id = wdc.stream_push_id WHERE st.id=#{id}") @Select("SELECT st.*, st.id as stream_push_id, wdc.*, wdc.id as gb_id FROM wvp_stream_push st LEFT join wvp_device_channel wdc on st.id = wdc.stream_push_id WHERE st.id=#{id}")
StreamPush select(@Param("id") int id); StreamPush queryOne(@Param("id") int id);
@Select("<script> "+ @Select("<script> "+
"SELECT st.*, st.id as stream_push_id, wdc.*, wdc.id as gb_id FROM wvp_stream_push st LEFT join wvp_device_channel wdc on st.id = wdc.stream_push_id " + "SELECT st.*, st.id as stream_push_id, wdc.*, wdc.id as gb_id FROM wvp_stream_push st LEFT join wvp_device_channel wdc on st.id = wdc.stream_push_id " +
@ -135,4 +135,5 @@ public interface StreamPushMapper {
"</foreach>" + "</foreach>" +
")</script>") ")</script>")
void batchDel(List<StreamPush> streamPushList); void batchDel(List<StreamPush> streamPushList);
} }

View File

@ -0,0 +1,8 @@
package com.genersoft.iot.vmp.streamPush.service;
import com.genersoft.iot.vmp.common.CommonCallback;
import com.genersoft.iot.vmp.common.StreamInfo;
public interface IStreamPushPlayService {
void start(Integer id, CommonCallback<StreamInfo> callback);
}

View File

@ -0,0 +1,206 @@
package com.genersoft.iot.vmp.streamPush.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.genersoft.iot.vmp.common.CommonCallback;
import com.genersoft.iot.vmp.common.InviteInfo;
import com.genersoft.iot.vmp.common.InviteSessionType;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.event.hook.Hook;
import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
import com.genersoft.iot.vmp.media.event.hook.HookType;
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.streamPush.dao.StreamPushMapper;
import com.genersoft.iot.vmp.streamPush.service.IStreamPushPlayService;
import gov.nist.javax.sip.message.SIPResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import javax.sip.message.Response;
import java.text.ParseException;
import java.util.UUID;
@Service
@Slf4j
@DS("master")
public class StreamPushPlayServiceImpl implements IStreamPushPlayService {
@Autowired
private StreamPushMapper streamPushMapper;
@Autowired
private IMediaServerService mediaServerService;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired
private UserSetting userSetting;
@Autowired
private DynamicTask dynamicTask;
@Autowired
private HookSubscribe subscribe;
@Override
public void start(Integer id, CommonCallback<StreamInfo> callback) {
StreamPush streamPush = streamPushMapper.queryOne(id);
Assert.notNull(streamPush, "推流信息未找到");
// if (streamPush.isPushing() && streamPush.getMediaServerId() != null) {
// // 检查流是否准备就绪
// MediaServer mediaServer = mediaServerService.getOne(streamPush.getMediaServerId());
// if (mediaServer != null) {
// Boolean streamReady = mediaServerService.isStreamReady(mediaServer, streamPush.getApp(), streamPush.getStream());
// if (streamReady != null && streamReady) {
// String callId = null;
// StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(streamPush.getApp(), streamPush.getStream());
// if (streamAuthorityInfo != null) {
// callId = streamAuthorityInfo.getCallId();
// }
// callback.run(mediaServerService.getStreamInfoByAppAndStream(mediaServer,
// streamPush.getApp(), streamPush.getStream(), null, callId));
// return;
// }
// }
// }
// Assert.isTrue(streamPush.isAutoPushChannel(), "通道未推流");
// // 发送redis消息通知流上线
// String timeOutTaskKey = UUID.randomUUID().toString();
// Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, streamPush.getApp(), streamPush.getStream(), null);
// // 开启流上线监听
// subscribe.addSubscribe(rtpHook, (hookData) -> {
// dynamicTask.stop(timeOutTaskKey);
// subscribe.removeSubscribe(rtpHook);
// if (hookData == null) {
// return;
// }
// String callId = null;
// StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(streamPush.getApp(), streamPush.getStream());
// if (streamAuthorityInfo != null) {
// callId = streamAuthorityInfo.getCallId();
// }
// callback.run(mediaServerService.getStreamInfoByAppAndStream(hookData.getMediaServer(),
// streamPush.getApp(), streamPush.getStream(), null, callId));
// });
// // 设置超时事件
// dynamicTask.startDelay(timeOutTaskKey, () -> {
// // 取消流监听
// subscribe.removeSubscribe(rtpHook);
// }, userSetting.getPlayTimeout());
// 发送redis消息 同时监听可能返回的拒绝消息
MediaArrivalEvent pushListItem = redisCatchStorage.getPushListItem(streamPush.getApp(), streamPush.getStream());
if (pushListItem != null) {
String callId = null;
StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(streamPush.getApp(), streamPush.getStream());
if (streamAuthorityInfo != null) {
callId = streamAuthorityInfo.getCallId();
}
callback.run(mediaServerService.getStreamInfoByAppAndStream(pushListItem.getMediaServer(),
streamPush.getApp(), streamPush.getStream(), null, callId));
return;
}
Assert.isTrue(streamPush.isAutoPushChannel(), "通道未推流");
// 发送redis消息以使设备上线流上线后被
log.info("[ app={}, stream={} ]通道未推流发送redis信息控制设备开始推流", streamPush.getApp(), streamPush.getStream());
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1,
streamPush.getApp(), streamPush.getStream(), sendRtpItem.getChannelId(), sendRtpItem.getPlatformId(),
platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId());
redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
// 设置超时
dynamicTask.startDelay(sendRtpItem.getCallId(), () -> {
redisRpcService.stopWaitePushStreamOnline(sendRtpItem);
log.info("[ app={}, stream={} ] 等待设备开始推流超时", streamPush.getApp(), streamPush.getStream());
try {
responseAck(request, Response.REQUEST_TIMEOUT); // 超时
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("未处理的异常 ", e);
}
}, userSetting.getPlatformPlayTimeout());
//
long key = redisRpcService.waitePushStreamOnline(sendRtpItem, (sendRtpItemKey) -> {
dynamicTask.stop(sendRtpItem.getCallId());
if (sendRtpItemKey == null) {
log.warn("[级联点播] 等待推流得到结果未空: {}/{}", streamPush.getApp(), streamPush.getStream());
try {
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("未处理的异常 ", e);
}
return;
}
SendRtpItem sendRtpItemFromRedis = (SendRtpItem)redisTemplate.opsForValue().get(sendRtpItemKey);
if (sendRtpItemFromRedis == null) {
log.warn("[级联点播] 等待推流, 未找到redis中缓存的发流信息 {}/{}", streamPush.getApp(), streamPush.getStream());
try {
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("未处理的异常 ", e);
}
return;
}
if (sendRtpItemFromRedis.getServerId().equals(userSetting.getServerId())) {
log.info("[级联点播] 等待的推流在本平台上线 {}/{}", streamPush.getApp(), streamPush.getStream());
int localPort = sendRtpPortManager.getNextPort(mediaServerItem);
if (localPort == 0) {
log.warn("上级点时创建sendRTPItem失败可能是服务器端口资源不足");
try {
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("未处理的异常 ", e);
}
return;
}
sendRtpItem.setLocalPort(localPort);
if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) {
sendRtpItem.setLocalIp(platform.getSendStreamIp());
}
// 写入redis 超时时回复
sendRtpItem.setStatus(1);
SIPResponse response = sendStreamAck(request, sendRtpItem, platform);
if (response != null) {
sendRtpItem.setToTag(response.getToTag());
}
redisCatchStorage.updateSendRTPSever(sendRtpItem);
} else {
// 其他平台内容
otherWvpPushStream(sendRtpItemFromRedis, request, platform);
}
});
// 添加回复的拒绝或者错误的通知
// redis消息例如 PUBLISH VM_MSG_STREAM_PUSH_RESPONSE '{"code":1,"msg":"失败","app":"1","stream":"2"}'
redisPushStreamResponseListener.addEvent(streamPush.getApp(), streamPush.getStream(), response -> {
if (response.getCode() != 0) {
dynamicTask.stop(sendRtpItem.getCallId());
redisRpcService.stopWaitePushStreamOnline(sendRtpItem);
redisRpcService.removeCallback(key);
try {
responseAck(request, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("[命令发送失败] 国标级联 点播回复: {}", e.getMessage());
}
}
});
}
}

View File

@ -251,7 +251,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
Assert.notNull(streamPush, "推流信息不可为NULL"); Assert.notNull(streamPush, "推流信息不可为NULL");
Assert.isTrue(streamPush.getId() > 0, "推流信息ID必须存在"); Assert.isTrue(streamPush.getId() > 0, "推流信息ID必须存在");
log.info("[更新推流]id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream()); log.info("[更新推流]id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream());
StreamPush streamPushInDb = streamPushMapper.select(streamPush.getId()); StreamPush streamPushInDb = streamPushMapper.queryOne(streamPush.getId());
if (!streamPushInDb.getApp().equals(streamPush.getApp()) || !streamPushInDb.getStream().equals(streamPush.getStream())) { if (!streamPushInDb.getApp().equals(streamPush.getApp()) || !streamPushInDb.getStream().equals(streamPush.getStream())) {
// app或者stream变化 // app或者stream变化
StreamPush streamPushInDbForAppAndStream = streamPushMapper.selectByAppAndStream(streamPush.getApp(), streamPush.getStream()); StreamPush streamPushInDbForAppAndStream = streamPushMapper.selectByAppAndStream(streamPush.getApp(), streamPush.getStream());
@ -538,7 +538,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Override @Override
public void updatePushStatus(Integer streamPushId, boolean pushIng) { public void updatePushStatus(Integer streamPushId, boolean pushIng) {
StreamPush streamPushInDb = streamPushMapper.select(streamPushId); StreamPush streamPushInDb = streamPushMapper.queryOne(streamPushId);
streamPushInDb.setPushing(pushIng); streamPushInDb.setPushing(pushIng);
if (userSetting.isUsePushingAsStatus()) { if (userSetting.isUsePushingAsStatus()) {
streamPushInDb.setGbStatus(pushIng?"ON":"OFF"); streamPushInDb.setGbStatus(pushIng?"ON":"OFF");
@ -576,7 +576,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Override @Override
@Transactional @Transactional
public int delete(int id) { public int delete(int id) {
StreamPush streamPush = streamPushMapper.select(id); StreamPush streamPush = streamPushMapper.queryOne(id);
if (streamPush == null) { if (streamPush == null) {
return 0; return 0;
} }

View File

@ -13,7 +13,8 @@
</div> </div>
</div> </div>
<el-tabs tab-position="left"> <el-tabs tab-position="left">
<el-tab-pane label="推流信息编辑" style="background-color: #FFFFFF"> <el-tab-pane label="推流信息编辑" style="background-color: #FFFFFF; padding: 1rem">
<el-divider content-position="center">基础信息</el-divider>
<el-form ref="streamPushForm" status-icon label-width="160px" class="channel-form" v-loading="locading"> <el-form ref="streamPushForm" status-icon label-width="160px" class="channel-form" v-loading="locading">
<el-form-item label="应用名" > <el-form-item label="应用名" >
<el-input v-model="streamPush.app" placeholder="请输入应用名"></el-input> <el-input v-model="streamPush.app" placeholder="请输入应用名"></el-input>
@ -21,10 +22,14 @@
<el-form-item label="流ID" > <el-form-item label="流ID" >
<el-input v-model="streamPush.stream" placeholder="请输入流ID"></el-input> <el-input v-model="streamPush.stream" placeholder="请输入流ID"></el-input>
</el-form-item> </el-form-item>
</el-form>
<el-divider content-position="center">策略</el-divider>
<el-form ref="streamPushForm" status-icon label-width="160px" v-loading="locading">
<el-form-item style="text-align: left">
<el-checkbox v-model="streamPush.autoPushChannel">线</el-checkbox>
</el-form-item>
</el-form> </el-form>
<el-divider content-position="left">少年包青天</el-divider>
<el-form style="text-align: right"> <el-form style="text-align: right">
<el-form-item > <el-form-item >
<el-button type="primary" @click="onSubmit"></el-button> <el-button type="primary" @click="onSubmit"></el-button>

View File

@ -71,9 +71,7 @@
<el-table-column label="操作" min-width="360" fixed="right"> <el-table-column label="操作" min-width="360" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="medium" icon="el-icon-video-play" <el-button size="medium" icon="el-icon-video-play"@click="playPush(scope.row)" type="text">播放
v-if="scope.row.pushIng === true"
@click="playPush(scope.row)" type="text">播放
</el-button> </el-button>
<el-divider direction="vertical"></el-divider> <el-divider direction="vertical"></el-divider>
<el-button size="medium" icon="el-icon-delete" type="text" @click="deletePush(scope.row.id)" style="color: #f56c6c" >删除</el-button> <el-button size="medium" icon="el-icon-delete" type="text" @click="deletePush(scope.row.id)" style="color: #f56c6c" >删除</el-button>
@ -197,11 +195,9 @@ export default {
this.getListLoading = true; this.getListLoading = true;
this.$axios({ this.$axios({
method: 'get', method: 'get',
url: '/api/media/getPlayUrl', url: '/api/push/start',
params: { params: {
app: row.app, id: id
stream: row.stream,
mediaServerId: row.mediaServerId
} }
}).then(function (res) { }).then(function (res) {
that.getListLoading = false; that.getListLoading = false;

View File

@ -270,7 +270,6 @@ create table wvp_platform
update_time character varying(50), update_time character varying(50),
as_message_channel bool default false, as_message_channel bool default false,
custom_catalog bool default false, custom_catalog bool default false,
auto_push_channel bool default false,
send_stream_ip character varying(50), send_stream_ip character varying(50),
constraint uk_platform_unique_server_gb_id unique (server_gb_id) constraint uk_platform_unique_server_gb_id unique (server_gb_id)
); );
@ -317,17 +316,18 @@ create table wvp_stream_proxy
create table wvp_stream_push create table wvp_stream_push
( (
id serial primary key, id serial primary key,
app character varying(255), app character varying(255),
stream character varying(255), stream character varying(255),
create_time character varying(50), create_time character varying(50),
media_server_id character varying(50), media_server_id character varying(50),
server_id character varying(50), server_id character varying(50),
push_time character varying(50), push_time character varying(50),
status bool default false, status bool default false,
update_time character varying(50), update_time character varying(50),
pushing bool default false, pushing bool default false,
self bool default false, self bool default false,
auto_push_channel bool default true,
constraint uk_stream_push_app_stream unique (app, stream) constraint uk_stream_push_app_stream unique (app, stream)
); );
create table wvp_cloud_record create table wvp_cloud_record
@ -406,7 +406,7 @@ CREATE TABLE wvp_common_group
device_id varchar(50) NOT NULL, device_id varchar(50) NOT NULL,
name varchar(255) NOT NULL, name varchar(255) NOT NULL,
parent_device_id varchar(50) DEFAULT NULL, parent_device_id varchar(50) DEFAULT NULL,
business_group varchar(50) NOT NULL, business_group varchar(50) NOT NULL,
platform_id int, platform_id int,
create_time varchar(50) NOT NULL, create_time varchar(50) NOT NULL,
update_time varchar(50) NOT NULL, update_time varchar(50) NOT NULL,