mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-05-25 06:27:50 +08:00
Compare commits
5 Commits
bfc2a71ecc
...
a8a8e70f7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8a8e70f7c | ||
|
|
f396f5f29e | ||
|
|
bca77f79cc | ||
|
|
8c54895c47 | ||
|
|
34d1dbb399 |
91
bootstrap.sh
91
bootstrap.sh
@ -1,91 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
######################################################
|
|
||||||
# Copyright 2019 Pham Ngoc Hoai
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
# Repo: https://github.com/tyrion9/spring-boot-startup-script
|
|
||||||
#
|
|
||||||
######### PARAM ######################################
|
|
||||||
|
|
||||||
JAVA_OPT=-Xmx1024m
|
|
||||||
JARFILE=`ls -1r *.jar 2>/dev/null | head -n 1`
|
|
||||||
PID_FILE=pid.file
|
|
||||||
RUNNING=N
|
|
||||||
PWD=`pwd`
|
|
||||||
|
|
||||||
######### DO NOT MODIFY ########
|
|
||||||
|
|
||||||
if [ -f $PID_FILE ]; then
|
|
||||||
PID=`cat $PID_FILE`
|
|
||||||
if [ ! -z "$PID" ] && kill -0 $PID 2>/dev/null; then
|
|
||||||
RUNNING=Y
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
start()
|
|
||||||
{
|
|
||||||
if [ $RUNNING == "Y" ]; then
|
|
||||||
echo "Application already started"
|
|
||||||
else
|
|
||||||
if [ -z "$JARFILE" ]
|
|
||||||
then
|
|
||||||
echo "ERROR: jar file not found"
|
|
||||||
else
|
|
||||||
nohup java $JAVA_OPT -Djava.security.egd=file:/dev/./urandom -jar $PWD/$JARFILE > nohup.out 2>&1 &
|
|
||||||
echo $! > $PID_FILE
|
|
||||||
echo "Application $JARFILE starting..."
|
|
||||||
tail -f nohup.out
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
stop()
|
|
||||||
{
|
|
||||||
if [ $RUNNING == "Y" ]; then
|
|
||||||
kill -9 $PID
|
|
||||||
rm -f $PID_FILE
|
|
||||||
echo "Application stopped"
|
|
||||||
else
|
|
||||||
echo "Application not running"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
restart()
|
|
||||||
{
|
|
||||||
stop
|
|
||||||
start
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
|
|
||||||
'start')
|
|
||||||
start
|
|
||||||
;;
|
|
||||||
|
|
||||||
'stop')
|
|
||||||
stop
|
|
||||||
;;
|
|
||||||
|
|
||||||
'restart')
|
|
||||||
restart
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 { start | stop | restart }"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 获取当前日期并格式化为 YYYY-MM-DD 的形式
|
|
||||||
current_date=$(date +"%Y-%m-%d")
|
|
||||||
|
|
||||||
mkdir -p "$current_date"/数据库
|
|
||||||
|
|
||||||
cp -r ./数据库/2.7.3 "$current_date"/数据库
|
|
||||||
|
|
||||||
cp src/main/resources/配置详情.yml "$current_date"
|
|
||||||
cp src/main/resources/application-dev.yml "$current_date"/application.yml
|
|
||||||
|
|
||||||
cp ./target/wvp-pro-*.jar "$current_date"
|
|
||||||
|
|
||||||
zip -r "$current_date".zip "$current_date"
|
|
||||||
|
|
||||||
rm -rf "$current_date"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
Binary file not shown.
9
pom.xml
9
pom.xml
@ -213,17 +213,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springdoc</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
<version>2.8.6</version>
|
<version>2.8.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springdoc</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
|
||||||
<version>2.8.6</version>
|
<version>2.8.5</version>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springdoc</groupId>
|
|
||||||
<artifactId>springdoc-openapi-security</artifactId>
|
|
||||||
<version>1.8.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -7,12 +7,12 @@ import io.swagger.v3.oas.models.info.Contact;
|
|||||||
import io.swagger.v3.oas.models.info.Info;
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
import io.swagger.v3.oas.models.info.License;
|
import io.swagger.v3.oas.models.info.License;
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springdoc.core.models.GroupedOpenApi;
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springdoc.core.GroupedOpenApi;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lin
|
* @author lin
|
||||||
@ -39,7 +39,7 @@ public class SpringDocConfig {
|
|||||||
.info(new Info().title("WVP-PRO 接口文档")
|
.info(new Info().title("WVP-PRO 接口文档")
|
||||||
.contact(contact)
|
.contact(contact)
|
||||||
.description("开箱即用的28181协议视频平台。 <br/>" +
|
.description("开箱即用的28181协议视频平台。 <br/>" +
|
||||||
"1. 打开<a href='/doc.html#/1.%20全部/用户管理/login_1'>登录</a>接口" +
|
"1. 打开<a href='/doc.html#/1.%20全部/用户管理/login'>登录</a>接口" +
|
||||||
" 登录成功后返回AccessToken。 <br/>" +
|
" 登录成功后返回AccessToken。 <br/>" +
|
||||||
"2. 填写到AccessToken到参数值 <a href='/doc.html#/Authorize/1.%20全部'>Token配置</a> <br/>" +
|
"2. 填写到AccessToken到参数值 <a href='/doc.html#/Authorize/1.%20全部'>Token配置</a> <br/>" +
|
||||||
"后续接口就可以直接测试了")
|
"后续接口就可以直接测试了")
|
||||||
|
|||||||
@ -26,7 +26,7 @@ public interface IDeviceService {
|
|||||||
* 设备下线
|
* 设备下线
|
||||||
* @param deviceId 设备编号
|
* @param deviceId 设备编号
|
||||||
*/
|
*/
|
||||||
void offline(String deviceId, String reason);
|
void offline(String deviceId, String reason, boolean check);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加目录订阅
|
* 添加目录订阅
|
||||||
|
|||||||
@ -274,7 +274,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
|
|
||||||
private void deviceStatusExpire(String deviceId, SipTransactionInfo transactionInfo) {
|
private void deviceStatusExpire(String deviceId, SipTransactionInfo transactionInfo) {
|
||||||
log.info("[设备状态] 到期, 编号: {}", deviceId);
|
log.info("[设备状态] 到期, 编号: {}", deviceId);
|
||||||
offline(deviceId, "保活到期");
|
offline(deviceId, "保活到期", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -383,7 +383,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void offline(String deviceId, String reason) {
|
public void offline(String deviceId, String reason, boolean check) {
|
||||||
Device device = getDeviceByDeviceIdFromDb(deviceId);
|
Device device = getDeviceByDeviceIdFromDb(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
log.warn("[设备不存在] device:{}", deviceId);
|
log.warn("[设备不存在] device:{}", deviceId);
|
||||||
@ -391,7 +391,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 主动查询设备状态, 没有HostAddress无法发送请求,可能是手动添加的设备
|
// 主动查询设备状态, 没有HostAddress无法发送请求,可能是手动添加的设备
|
||||||
if (device.getHostAddress() != null) {
|
if (check && device.getHostAddress() != null) {
|
||||||
Boolean deviceStatus = getDeviceStatus(device);
|
Boolean deviceStatus = getDeviceStatus(device);
|
||||||
if (deviceStatus != null && deviceStatus) {
|
if (deviceStatus != null && deviceStatus) {
|
||||||
log.info("[设备离线] 主动探测发现设备在线,暂不处理 device:{}", deviceId);
|
log.info("[设备离线] 主动探测发现设备在线,暂不处理 device:{}", deviceId);
|
||||||
@ -471,7 +471,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
}
|
}
|
||||||
if (!deviceStatusTaskRunner.containsKey(device.getDeviceId())) {
|
if (!deviceStatusTaskRunner.containsKey(device.getDeviceId())) {
|
||||||
log.debug("[状态丢失] 执行设备离线, 编号: {},", device.getDeviceId());
|
log.debug("[状态丢失] 执行设备离线, 编号: {},", device.getDeviceId());
|
||||||
offline(device.getDeviceId(), "");
|
offline(device.getDeviceId(), "", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1202,7 +1202,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
if ("ONLINE".equalsIgnoreCase(data.trim())) {
|
if ("ONLINE".equalsIgnoreCase(data.trim())) {
|
||||||
online(device, null);
|
online(device, null);
|
||||||
}else {
|
}else {
|
||||||
offline(device.getDeviceId(), "设备状态查询结果:" + data.trim());
|
offline(device.getDeviceId(), "设备状态查询结果:" + data.trim(), true);
|
||||||
}
|
}
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.run(code, msg, data);
|
callback.run(code, msg, data);
|
||||||
|
|||||||
@ -82,7 +82,7 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param fromTag
|
* @param fromTag
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, boolean status) throws SipException, InvalidArgumentException, ParseException;
|
void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, Boolean status) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向上级回复移动位置订阅消息
|
* 向上级回复移动位置订阅消息
|
||||||
|
|||||||
@ -329,22 +329,29 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, boolean status) throws SipException, InvalidArgumentException, ParseException {
|
public void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, Boolean status) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
String statusStr = (status)?"ONLINE":"OFFLINE";
|
String statusStr = null;
|
||||||
|
if (status != null) {
|
||||||
|
statusStr = (status)?"ONLINE":"OFFLINE";
|
||||||
|
}
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||||
.append("<Response>\r\n")
|
.append("<Response>\r\n")
|
||||||
.append("<CmdType>DeviceStatus</CmdType>\r\n")
|
.append("<CmdType>DeviceStatus</CmdType>\r\n")
|
||||||
.append("<SN>" +sn + "</SN>\r\n")
|
.append("<SN>" +sn + "</SN>\r\n")
|
||||||
.append("<DeviceID>" + channelId + "</DeviceID>\r\n")
|
.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
||||||
.append("<Result>OK</Result>\r\n")
|
if (statusStr == null) {
|
||||||
.append("<Online>"+statusStr+"</Online>\r\n")
|
deviceStatusXml.append("<Result>ERROR</Result>\r\n");
|
||||||
.append("<Status>OK</Status>\r\n")
|
}else {
|
||||||
.append("</Response>\r\n");
|
deviceStatusXml.append("<Result>OK</Result>\r\n")
|
||||||
|
.append("<Online>"+statusStr+"</Online>\r\n")
|
||||||
|
.append("<Status>OK</Status>\r\n");
|
||||||
|
}
|
||||||
|
deviceStatusXml.append("</Response>\r\n");
|
||||||
|
|
||||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
|||||||
device.setRegisterTime(DateUtil.getNow());
|
device.setRegisterTime(DateUtil.getNow());
|
||||||
deviceService.online(device, null);
|
deviceService.online(device, null);
|
||||||
} else {
|
} else {
|
||||||
deviceService.offline(deviceId, "主动注销");
|
deviceService.offline(deviceId, "主动注销", false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}else {
|
}else {
|
||||||
@ -228,7 +228,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
|||||||
deviceService.online(device, sipTransactionInfo);
|
deviceService.online(device, sipTransactionInfo);
|
||||||
} else {
|
} else {
|
||||||
log.info("[注销成功] deviceId: {}->{}", deviceId, requestAddress);
|
log.info("[注销成功] deviceId: {}->{}", deviceId, requestAddress);
|
||||||
deviceService.offline(deviceId, "主动注销");
|
deviceService.offline(deviceId, "主动注销", false);
|
||||||
}
|
}
|
||||||
} catch (SipException | NoSuchAlgorithmException | ParseException e) {
|
} catch (SipException | NoSuchAlgorithmException | ParseException e) {
|
||||||
log.error("未处理的异常 ", e);
|
log.error("未处理的异常 ", e);
|
||||||
|
|||||||
@ -86,14 +86,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
|
|||||||
} else if (CmdType.CATALOG.equals(cmd)) {
|
} else if (CmdType.CATALOG.equals(cmd)) {
|
||||||
processNotifyCatalogList(request, rootElement);
|
processNotifyCatalogList(request, rootElement);
|
||||||
} else {
|
} else {
|
||||||
log.info("接收到消息:" + cmd);
|
log.info("接收到消息:{}", cmd);
|
||||||
|
|
||||||
Response response = getMessageFactory().createResponse(200, request);
|
Response response = getMessageFactory().createResponse(200, request);
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
|
ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
|
||||||
response.setExpires(expireHeader);
|
response.setExpires(expireHeader);
|
||||||
}
|
}
|
||||||
log.info("response : " + response);
|
log.info("response : {}", response);
|
||||||
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
|
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
|
||||||
}
|
}
|
||||||
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
||||||
@ -126,9 +126,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
|
|||||||
.append("<DeviceID>").append(deviceId).append("</DeviceID>\r\n")
|
.append("<DeviceID>").append(deviceId).append("</DeviceID>\r\n")
|
||||||
.append("<Result>OK</Result>\r\n")
|
.append("<Result>OK</Result>\r\n")
|
||||||
.append("</Response>\r\n");
|
.append("</Response>\r\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int expires = request.getExpires().getExpires();
|
int expires = request.getExpires().getExpires();
|
||||||
SIPResponse response = responseXmlAck(request, resultXml.toString(), platform, expires);
|
SIPResponse response = responseXmlAck(request, resultXml.toString(), platform, expires);
|
||||||
|
|||||||
@ -73,7 +73,13 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
|
|||||||
}
|
}
|
||||||
CommonGBChannel channel= channelService.queryOneWithPlatform(platform.getId(), channelId);
|
CommonGBChannel channel= channelService.queryOneWithPlatform(platform.getId(), channelId);
|
||||||
if (channel ==null){
|
if (channel ==null){
|
||||||
log.error("[平台没有该通道的使用权限]:platformId"+platform.getServerGBId()+" deviceID:"+channelId);
|
log.error("[平台没有该通道的使用权限]:platformId: {} deviceID:{}", platform.getServerGBId(), channelId);
|
||||||
|
// 上级平台查询本平台状态
|
||||||
|
try {
|
||||||
|
cmderFroPlatform.deviceStatusResponse(platform, channelId, sn, fromHeader.getTag(), null);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
log.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -13,10 +13,10 @@
|
|||||||
<div id="shared" style="margin-right: 20px;">
|
<div id="shared" style="margin-right: 20px;">
|
||||||
<el-form ref="passwordForm" :rules="rules" status-icon label-width="80px">
|
<el-form ref="passwordForm" :rules="rules" status-icon label-width="80px">
|
||||||
<el-form-item label="新密码" prop="newPassword">
|
<el-form-item label="新密码" prop="newPassword">
|
||||||
<el-input v-model="newPassword" autocomplete="off" />
|
<el-input v-model="newPassword" autocomplete="off" type="password" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="确认密码" prop="confirmPassword">
|
<el-form-item label="确认密码" prop="confirmPassword">
|
||||||
<el-input v-model="confirmPassword" autocomplete="off" />
|
<el-input v-model="confirmPassword" autocomplete="off" type="password" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@ -88,6 +88,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSubmit: function() {
|
onSubmit: function() {
|
||||||
|
if (this.newPassword !== this.confirmPassword) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '两次输入密码不一致!',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
this.$store.dispatch('user/changePasswordForAdmin', {
|
this.$store.dispatch('user/changePasswordForAdmin', {
|
||||||
password: this.newPassword,
|
password: this.newPassword,
|
||||||
userId: this.form.id
|
userId: this.form.id
|
||||||
|
|||||||
15
zlm.md
15
zlm.md
@ -1,15 +0,0 @@
|
|||||||
1. 增加接口:用来返回hook调用耗时。
|
|
||||||
参数: sn,
|
|
||||||
返回值: hook耗时
|
|
||||||
功能: zlm收到调用后立即调用心跳hook,hook中携带sn信息, zlm收到hook返回后计算此次hook的耗时,然后返回耗时
|
|
||||||
用途: 1. 可以用来检测hook配置是否正常
|
|
||||||
2. 检测wvp与zlm连接的健康程度
|
|
||||||
2. 增加接口:查询loadMP4File的录像播放位置
|
|
||||||
参数: app, steam,
|
|
||||||
返回: 当前播放的hook位置
|
|
||||||
功能: zlm收到请求后查询流的seek位置并返回
|
|
||||||
用途: 1. 获取当前播放位置,可以在页面同步显示时间
|
|
||||||
2. 用来时快进五秒 快退五秒类似的操作
|
|
||||||
3. loadMP4File扩展, 增加默认seek值和默认倍速,开始时直接从这个位置开始,并使用指定的倍速
|
|
||||||
4. 支持下载指定取件的mp4文件,这个区间可能包括多个文件和文件的一部分。
|
|
||||||
5. 希望seek接口和倍速接口可以去除schema的必选,作为可选项,不传则默认全部
|
|
||||||
Loading…
Reference in New Issue
Block a user