├── web ├── src │ ├── boot │ │ ├── .gitkeep │ │ ├── i18n.js │ │ └── axios.js │ ├── i18n │ │ ├── index.js │ │ └── en-us │ │ │ └── index.js │ ├── App.vue │ ├── pages │ │ ├── Index.vue │ │ ├── api │ │ │ └── ApiDocumentView.vue │ │ ├── Error404.vue │ │ ├── stream │ │ │ └── StreamViewer2.vue │ │ ├── device │ │ │ └── DeviceRemoveConfirm.vue │ │ ├── schedule │ │ │ ├── SchedulePauseConfirm.vue │ │ │ ├── ScheduleResumeConfirm.vue │ │ │ └── ScheduleRemoveConfirm.vue │ │ ├── videoqualitydetect │ │ │ └── arithmetic │ │ │ │ ├── VideoQualityDetectArithmeticRemoveConfirm.vue │ │ │ │ ├── VideoQualityDetectArithmeticPauseConfirm.vue │ │ │ │ └── VideoQualityDetectArithmeticResumeConfirm.vue │ │ └── channel │ │ │ ├── StreamViewer.vue │ │ │ └── ChannelRemoveConfirm.vue │ ├── css │ │ ├── app.scss │ │ └── quasar.variables.scss │ ├── layouts │ │ └── MenuTree.vue │ ├── components │ │ ├── EssentialLink.vue │ │ └── FlvPlayer.vue │ ├── router │ │ ├── index.js │ │ └── routes.js │ └── index.template.html ├── public │ ├── logo.jpg │ ├── favicon.ico │ └── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ └── favicon-128x128.png ├── babel.config.js ├── .eslintignore ├── .editorconfig ├── .postcssrc.js ├── README.md ├── .gitignore ├── jsconfig.json ├── package.json └── .eslintrc.js ├── logo.jpg ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── doc ├── resources │ └── images │ │ ├── blueberry-jar.png │ │ └── blueberry-package.png └── 部署文档.md ├── start.bat ├── m-server └── src │ └── main │ ├── resources │ ├── banner.txt │ ├── application-pro.yml │ ├── application-dev.yml │ └── application.yml │ └── java │ └── fun │ └── bookish │ └── blueberry │ └── server │ ├── device │ ├── mapper │ │ ├── xml │ │ │ └── DeviceMapper.xml │ │ └── DeviceMapper.java │ ├── entity │ │ ├── DeviceType.java │ │ └── DeviceParamVO.java │ └── service │ │ └── IDeviceService.java │ ├── videostream │ ├── mapper │ │ ├── xml │ │ │ └── VideoStreamMapper.xml │ │ └── VideoStreamMapper.java │ └── entity │ │ ├── VideoStreamStopResponse.java │ │ ├── VideoStreamVO.java │ │ ├── VideoStreamSnapshot.java │ │ └── VideoStreamPlayResponse.java │ ├── videoqualitydetect │ ├── record │ │ ├── mapper │ │ │ ├── xml │ │ │ │ └── VideoQualityDetectRecordMapper.xml │ │ │ └── VideoQualityDetectRecordMapper.java │ │ ├── service │ │ │ └── IVideoQualityDetectRecordService.java │ │ └── entity │ │ │ └── VideoQualityDetectRecordQueryParamVO.java │ ├── arithmetic │ │ ├── mapper │ │ │ ├── xml │ │ │ │ └── VideoQualityDetectArithmeticMapper.xml │ │ │ └── VideoQualityDetectArithmeticMapper.java │ │ ├── entity │ │ │ ├── VideoQualityDetectArithmeticApplicableDeviceVO.java │ │ │ ├── VideoQualityDetectArithmeticQueryParamVO.java │ │ │ └── VideoQualityDetectArithmeticApplyDeviceVO.java │ │ └── service │ │ │ └── IVideoQualityDetectArithmeticService.java │ ├── arithmeticapplydevice │ │ ├── mapper │ │ │ ├── xml │ │ │ │ └── VideoQualityDetectArithmeticApplyDeviceMapper.xml │ │ │ └── VideoQualityDetectArithmeticApplyDeviceMapper.java │ │ ├── service │ │ │ ├── IVideoQualityDetectArithmeticApplyDeviceService.java │ │ │ └── impl │ │ │ │ └── VideoQualityDetectArithmeticApplyDeviceServiceImpl.java │ │ └── entity │ │ │ └── VideoQualityDetectArithmeticApplyDevicePO.java │ ├── manual │ │ ├── service │ │ │ └── IVideoQualityDetectManualService.java │ │ ├── controller │ │ │ └── VideoQualityDetectManualController.java │ │ └── entity │ │ │ └── VideoQualityDetectManualVO.java │ └── detect │ │ └── entity │ │ └── VideoStreamQualityDetectResult.java │ ├── schedule │ ├── lock │ │ └── ScheduleLockManager.java │ └── conf │ │ ├── VideoNoReaderCheckProperties.java │ │ └── VideoQualityDetectProperties.java │ ├── openapi │ ├── entity │ │ └── OpenDeviceStatusVO.java │ ├── service │ │ └── IOpenApiService.java │ └── controller │ │ └── OpenApiController.java │ ├── sip │ └── SipServerConfiguration.java │ ├── channel │ ├── mapper │ │ ├── xml │ │ │ └── ChannelMapper.xml │ │ └── ChannelMapper.java │ ├── entity │ │ ├── ChannelStatusSync.java │ │ └── ChannelQueryParamVO.java │ └── service │ │ └── IChannelService.java │ ├── permission │ └── PermissionProperties.java │ ├── zlmedia │ ├── model │ │ ├── ZLStreamAddStreamProxyResponse.java │ │ └── ZLStreamCloseResponse.java │ └── conf │ │ └── MediaProperties.java │ ├── BlueberryApplication.java │ └── dev │ ├── DevController.java │ └── service │ └── DevService.java ├── m-core └── src │ └── main │ └── java │ └── fun │ └── bookish │ └── blueberry │ └── core │ ├── utils │ ├── ObjectUtils.java │ ├── SystemUtils.java │ ├── Base64Utils.java │ └── HexUtils.java │ ├── annotation │ ├── EnableResponseBodyJsonWrap.java │ └── DisableResponseBodyJsonWrap.java │ ├── exception │ ├── ParameterValidateException.java │ └── ManualRollbackException.java │ ├── page │ ├── PageResult.java │ └── PageInterceptorConfiguration.java │ ├── mvc │ └── WebMvcConfiguration.java │ ├── cors │ └── CorsFilterConfiguration.java │ ├── swagger2 │ └── Swagger2Configuration.java │ ├── advice │ └── ControllerResponseBodyAdvice.java │ ├── aop │ └── ParameterValidateExtAop.java │ └── json │ └── JsonResult.java ├── README.md ├── m-sip ├── src │ └── main │ │ └── java │ │ └── fun │ │ └── bookish │ │ └── blueberry │ │ └── sip │ │ ├── utils │ │ ├── SipTagUtils.java │ │ ├── SipSNUtils.java │ │ ├── MessageDigestUtils.java │ │ └── SipHeaderUtils.java │ │ ├── digest │ │ └── MessageDigestTypeEnum.java │ │ ├── constant │ │ ├── SipOnlineEnum.java │ │ ├── SipStatusTypeEnum.java │ │ ├── SipResultTypeEnum.java │ │ ├── SipMessageType.java │ │ ├── SipCommandType.java │ │ └── SipTraceLevel.java │ │ ├── command │ │ ├── executor │ │ │ ├── media │ │ │ │ ├── AbstractSipMediaCommandExecutor.java │ │ │ │ ├── SipMediaCommandExecutor.java │ │ │ │ └── param │ │ │ │ │ ├── SipMediaPlayParam.java │ │ │ │ │ └── SipMediaStopParam.java │ │ │ ├── query │ │ │ │ ├── param │ │ │ │ │ ├── SipQueryDeviceInfoParam.java │ │ │ │ │ ├── SipQueryDeviceStatusParam.java │ │ │ │ │ └── SipQueryCatalogParam.java │ │ │ │ ├── AbstractSipQueryCommandExecutor.java │ │ │ │ └── SipQueryCommandExecutor.java │ │ │ ├── param │ │ │ │ └── SipCommandParam.java │ │ │ └── SipCommandExecutor.java │ │ └── manager │ │ │ ├── SipCommandExecutorManager.java │ │ │ └── impl │ │ │ └── SipCommandExecutorManagerImpl.java │ │ ├── exception │ │ ├── SipDeviceRegisterException.java │ │ ├── SipCommandExecuteException.java │ │ ├── SipRequestCreationException.java │ │ ├── SipCatalogResponseCreationException.java │ │ ├── SipKeepaliveResponseCreationException.java │ │ ├── SipClientTransactionCreationException.java │ │ ├── SipDeviceInfoResponseCreationException.java │ │ └── SipDeviceStatusResponseCreationException.java │ │ ├── event │ │ ├── SipEventTypeEnum.java │ │ ├── SipEventContext.java │ │ └── listener │ │ │ ├── manager │ │ │ └── SipEventListenerManager.java │ │ │ └── SipEventListener.java │ │ ├── request │ │ ├── handler │ │ │ ├── impl │ │ │ │ ├── SipSubscribeRequestHandler.java │ │ │ │ ├── SipUnknownRequestHandler.java │ │ │ │ ├── SipByeRequestHandler.java │ │ │ │ ├── SipInfoRequestHandler.java │ │ │ │ ├── SipPrackRequestHandler.java │ │ │ │ ├── SipReferRequestHandler.java │ │ │ │ ├── SipCancelRequestHandler.java │ │ │ │ ├── SipInviteRequestHandler.java │ │ │ │ ├── SipNotifyRequestHandler.java │ │ │ │ ├── SipUpdateRequestHandler.java │ │ │ │ ├── SipOptionsRequestHandler.java │ │ │ │ ├── SipPublishRequestHandler.java │ │ │ │ └── SipAckRequestHandler.java │ │ │ └── SipRequestHandler.java │ │ ├── model │ │ │ └── SipRequestWrapper.java │ │ └── producer │ │ │ └── SipRequestProducer.java │ │ ├── entity │ │ ├── SipDeviceAlarmStatusDesc.java │ │ ├── SipCatalogDesc.java │ │ ├── SipKeepaliveDesc.java │ │ ├── SipDeviceRegisterDesc.java │ │ ├── SipMediaInviteDesc.java │ │ ├── SipDeviceDesc.java │ │ └── SipDeviceInfoDesc.java │ │ ├── response │ │ ├── handler │ │ │ ├── AbstractSipResponseHandler.java │ │ │ ├── SipResponseHandler.java │ │ │ └── impl │ │ │ │ ├── SipByeResponseHandler.java │ │ │ │ └── SipUnknownResponseHandler.java │ │ └── model │ │ │ └── SipResponseWrapper.java │ │ └── ssrc │ │ └── SipSSRCManager.java └── pom.xml ├── .gitignore ├── m-opencv ├── pom.xml └── src │ └── main │ └── java │ └── fun │ └── bookish │ └── blueberry │ └── opencv │ ├── utils │ └── ImageUtils.java │ └── detector │ └── SharpnessDetector.java ├── m-quartz ├── src │ └── main │ │ └── java │ │ └── fun │ │ └── bookish │ │ └── blueberry │ │ └── quartz │ │ ├── entity │ │ └── MisfireInstruction.java │ │ ├── listener │ │ ├── QuartzAutoStartListener.java │ │ ├── GeneralTriggerListener.java │ │ └── QuartzSchedulerListener.java │ │ └── service │ │ └── IQuartzService.java └── pom.xml └── LICENSE /web/src/boot/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/logo.jpg -------------------------------------------------------------------------------- /web/public/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/web/public/logo.jpg -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/web/public/favicon.ico -------------------------------------------------------------------------------- /web/src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import enUS from './en-us' 2 | 3 | export default { 4 | 'en-us': enUS 5 | } 6 | -------------------------------------------------------------------------------- /web/babel.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | presets: [ 4 | '@quasar/babel-preset-app' 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /web/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /src-bex/www 3 | /src-capacitor 4 | /src-cordova 5 | /.quasar 6 | /node_modules 7 | 8 | .eslintrc.js -------------------------------------------------------------------------------- /web/public/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/web/public/icons/favicon-16x16.png -------------------------------------------------------------------------------- /web/public/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/web/public/icons/favicon-32x32.png -------------------------------------------------------------------------------- /web/public/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/web/public/icons/favicon-96x96.png -------------------------------------------------------------------------------- /web/public/icons/favicon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/web/public/icons/favicon-128x128.png -------------------------------------------------------------------------------- /doc/resources/images/blueberry-jar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/doc/resources/images/blueberry-jar.png -------------------------------------------------------------------------------- /doc/resources/images/blueberry-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RabbitNoTeeth/blueberry/HEAD/doc/resources/images/blueberry-package.png -------------------------------------------------------------------------------- /start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title blueberry-1.0.0 3 | java -Xloggc:gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -server -jar blueberry-1.0.0.jar -------------------------------------------------------------------------------- /web/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | -------------------------------------------------------------------------------- /web/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /web/src/i18n/en-us/index.js: -------------------------------------------------------------------------------- 1 | // This is just an example, 2 | // so you can safely delete all default props below 3 | 4 | export default { 5 | failed: 'Action failed', 6 | success: 'Action was successful' 7 | } 8 | -------------------------------------------------------------------------------- /m-server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ************************************************** 4 | 项目: SIP信令服务器 (基于GB/T28181协议实现) 5 | 作者: 刘新冬 (https://github.com/RabbitNoTeeth) 6 | ************************************************** 7 | 8 | -------------------------------------------------------------------------------- /web/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | plugins: [ 5 | // to edit target browsers: use "browserslist" field in package.json 6 | require('autoprefixer') 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /web/src/pages/Index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/device/mapper/xml/DeviceMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/utils/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.utils; 2 | 3 | import java.util.Map; 4 | 5 | public class ObjectUtils { 6 | 7 | private ObjectUtils() {} 8 | 9 | public static Map toMap(Object obj) { 10 | return null; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videostream/mapper/xml/VideoStreamMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blueberry 2 | 3 | 4 | 5 | 监控设备管理平台。 6 | 7 | 8 | 9 | **功能列表** 10 | 11 | - [x] 设备管理 12 | - [x] 实时视频播放(媒体服务器使用 [ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) ) 13 | 14 | 15 | 16 | **设备类型支持** 17 | 18 | - [x] GB28181国标设备 19 | - [x] 支持RTSP推流的监控设备(如海康、大华等品牌的摄像头) 20 | 21 | 22 | 23 | **构建部署** 24 | 25 | 参考 `/doc/部署文档.md` 26 | 27 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/utils/SipTagUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.utils; 2 | 3 | public class SipTagUtils { 4 | 5 | private SipTagUtils() {} 6 | 7 | /** 8 | * 生成SN 9 | * @return 10 | */ 11 | public static String random() { 12 | return System.nanoTime() + ""; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/annotation/EnableResponseBodyJsonWrap.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Documented 6 | @Inherited 7 | @Target({ElementType.TYPE, ElementType.METHOD}) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | public @interface EnableResponseBodyJsonWrap { 10 | } 11 | -------------------------------------------------------------------------------- /web/src/css/app.scss: -------------------------------------------------------------------------------- 1 | // app global css in SCSS form 2 | 3 | .main_content { 4 | width: calc(100%); 5 | height: calc(100% - 10px); 6 | padding: 10px; 7 | background-color: #f5f5f5; 8 | overflow: auto; 9 | } 10 | 11 | .table_full { 12 | width: calc(100%); 13 | height: calc(100%); 14 | } 15 | 16 | .table_top_title { 17 | font-size: 20px; 18 | } 19 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/annotation/DisableResponseBodyJsonWrap.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Documented 6 | @Inherited 7 | @Target({ElementType.TYPE, ElementType.METHOD}) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | public @interface DisableResponseBodyJsonWrap { 10 | } 11 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/device/entity/DeviceType.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.device.entity; 2 | 3 | public class DeviceType { 4 | 5 | /** 6 | * 国标设备 7 | */ 8 | public static final String GB = "GB"; 9 | /** 10 | * RTSP直连设备 11 | */ 12 | public static final String RTSP = "RTSP"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /web/src/boot/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import messages from 'src/i18n' 4 | 5 | Vue.use(VueI18n) 6 | 7 | const i18n = new VueI18n({ 8 | locale: 'en-us', 9 | fallbackLocale: 'en-us', 10 | messages 11 | }) 12 | 13 | export default ({ app }) => { 14 | // Set i18n instance on app 15 | app.i18n = i18n 16 | } 17 | 18 | export { i18n } 19 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/record/mapper/xml/VideoQualityDetectRecordMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/utils/SipSNUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.utils; 2 | 3 | /** 4 | * SN序列号工具类 5 | */ 6 | public class SipSNUtils { 7 | 8 | private SipSNUtils() {} 9 | 10 | /** 11 | * 生成SN 12 | * @return 13 | */ 14 | public static int generateSN() { 15 | return (int) ((Math.random() * 9 + 1) * 100000); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmetic/mapper/xml/VideoQualityDetectArithmeticMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/digest/MessageDigestTypeEnum.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.digest; 2 | 3 | /** 4 | * 身份认证中数字加密方式 5 | */ 6 | public enum MessageDigestTypeEnum { 7 | 8 | MD5("MD5"); 9 | 10 | private final String desc; 11 | 12 | MessageDigestTypeEnum(String desc) { 13 | this.desc = desc; 14 | } 15 | 16 | public String getDesc() { 17 | return desc; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/constant/SipOnlineEnum.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.constant; 2 | 3 | /** 4 | * online枚举 5 | */ 6 | public enum SipOnlineEnum { 7 | 8 | ONLINE("ONLINE"), 9 | OFFLINE("OFFLINE"); 10 | 11 | private final String code; 12 | 13 | SipOnlineEnum(String code) { 14 | this.code = code; 15 | } 16 | 17 | public String getCode() { 18 | return code; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/constant/SipStatusTypeEnum.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.constant; 2 | 3 | /** 4 | * statusType枚举 5 | */ 6 | public enum SipStatusTypeEnum { 7 | 8 | ON("ON"), 9 | OFF("OFF"); 10 | 11 | private final String code; 12 | 13 | SipStatusTypeEnum(String code) { 14 | this.code = code; 15 | } 16 | 17 | public String getCode() { 18 | return code; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/exception/ParameterValidateException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.exception; 2 | 3 | /** 4 | * 参数校验失败异常 5 | * @author LIUXINDONG 6 | */ 7 | public class ParameterValidateException extends RuntimeException { 8 | private static final long serialVersionUID = -2453286880148054962L; 9 | 10 | public ParameterValidateException(String message){ 11 | super(message); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmeticapplydevice/mapper/xml/VideoQualityDetectArithmeticApplyDeviceMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/constant/SipResultTypeEnum.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.constant; 2 | 3 | /** 4 | * resultType枚举 5 | */ 6 | public enum SipResultTypeEnum { 7 | 8 | OK("OK"), 9 | ERROR("ERROR"); 10 | 11 | private final String code; 12 | 13 | SipResultTypeEnum(String code) { 14 | this.code = code; 15 | } 16 | 17 | public String getCode() { 18 | return code; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videostream/entity/VideoStreamStopResponse.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videostream.entity; 2 | 3 | /** 4 | * 媒体播放实体 5 | */ 6 | public class VideoStreamStopResponse { 7 | 8 | private String streamId; 9 | 10 | public String getStreamId() { 11 | return streamId; 12 | } 13 | 14 | public void setStreamId(String streamId) { 15 | this.streamId = streamId; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web/src/pages/api/ApiDocumentView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/constant/SipMessageType.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.constant; 2 | 3 | /** 4 | * sip消息类型 5 | */ 6 | public class SipMessageType { 7 | 8 | /** 9 | * 查询消息 10 | */ 11 | public static final String QUERY = "Query"; 12 | /** 13 | * 响应消息 14 | */ 15 | public static final String RESPONSE = "Response"; 16 | /** 17 | * 通知消息 18 | */ 19 | public static final String NOTIFY = "Notify"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/schedule/lock/ScheduleLockManager.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.schedule.lock; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | @Component 9 | public class ScheduleLockManager { 10 | 11 | private final Lock STREAM_LOCK = new ReentrantLock(); 12 | 13 | public Lock getStreamLock() { 14 | return STREAM_LOCK; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/device/mapper/DeviceMapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.device.mapper; 2 | 3 | import fun.bookish.blueberry.server.device.entity.DevicePO; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 设备表 Mapper 接口 10 | *

11 | * 12 | * @author RabbitNoTeeth 13 | * @since 2021-06-11 14 | */ 15 | @Mapper 16 | public interface DeviceMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/utils/SystemUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.utils; 2 | 3 | public class SystemUtils { 4 | 5 | private SystemUtils() {} 6 | 7 | public static String osName() { 8 | return System.getProperty("os.name"); 9 | } 10 | 11 | public static boolean isWin() { 12 | return osName().toUpperCase().contains("WIN"); 13 | } 14 | 15 | public static boolean isLinux() { 16 | return osName().toUpperCase().contains("LINUX"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /web/src/boot/axios.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import axios from 'axios' 3 | import qs from 'qs' 4 | 5 | const baseUrl = process.env.API; 6 | 7 | const axiosConfig = { 8 | withCredentials: true, 9 | headers: { 10 | 'Content-Type': 'application/x-www-form-urlencoded', 11 | }, 12 | transformRequest: [(data) => qs.stringify(data, {skipNulls: true})] 13 | } 14 | 15 | const instance = axios.create({ 16 | baseURL: baseUrl, 17 | ...axiosConfig 18 | }) 19 | 20 | Vue.prototype.$axios = instance 21 | Vue.prototype.$baseUrl = baseUrl 22 | 23 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # blueberry-page (blueberry-page) 2 | 3 | page of blueberry 4 | 5 | ## Install the dependencies 6 | ```bash 7 | npm install 8 | ``` 9 | 10 | ### Start the app in development mode (hot-code reloading, error reporting, etc.) 11 | ```bash 12 | quasar dev 13 | ``` 14 | 15 | ### Lint the files 16 | ```bash 17 | npm run lint 18 | ``` 19 | 20 | ### Build the app for production 21 | ```bash 22 | quasar build 23 | ``` 24 | 25 | ### Customize the configuration 26 | See [Configuring quasar.conf.js](https://v1.quasar.dev/quasar-cli/quasar-conf-js). 27 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videostream/mapper/VideoStreamMapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videostream.mapper; 2 | 3 | import fun.bookish.blueberry.server.videostream.entity.VideoStreamPO; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 视频流表 Mapper 接口 10 | *

11 | * 12 | * @author RabbitNoTeeth 13 | * @since 2021-06-11 14 | */ 15 | @Mapper 16 | public interface VideoStreamMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/exception/ManualRollbackException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.exception; 2 | 3 | /** 4 | * 手动回滚事务异常类,用于手动回滚事务 5 | * @author LIUXINDONG 6 | */ 7 | public class ManualRollbackException extends RuntimeException{ 8 | private static final long serialVersionUID = 1294595729299207352L; 9 | 10 | public ManualRollbackException(String message) { 11 | super(message); 12 | } 13 | 14 | public ManualRollbackException(String message, Throwable e) { 15 | super(message, e); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/openapi/entity/OpenDeviceStatusVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.openapi.entity; 2 | 3 | public class OpenDeviceStatusVO { 4 | 5 | private String id; 6 | 7 | private String online; 8 | 9 | public String getId() { 10 | return id; 11 | } 12 | 13 | public void setId(String id) { 14 | this.id = id; 15 | } 16 | 17 | public String getOnline() { 18 | return online; 19 | } 20 | 21 | public void setOnline(String online) { 22 | this.online = online; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/media/AbstractSipMediaCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.media; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | 5 | public abstract class AbstractSipMediaCommandExecutor implements SipMediaCommandExecutor { 6 | 7 | protected final SipServer sipServer; 8 | 9 | protected AbstractSipMediaCommandExecutor(SipServer sipServer) { 10 | this.sipServer = sipServer; 11 | } 12 | 13 | public final SipServer getSipServer() { 14 | return this.sipServer; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | image 7 | dist 8 | fileUpload 9 | 10 | ### STS ### 11 | .apt_generated 12 | .classpath 13 | .factorypath 14 | .project 15 | .settings 16 | .springBeans 17 | .sts4-cache 18 | 19 | ### IntelliJ IDEA ### 20 | .idea 21 | *.iws 22 | *.iml 23 | *.ipr 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /m-manage/dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | build/ 32 | !**/src/main/**/build/ 33 | !**/src/test/**/build/ 34 | 35 | ### VS Code ### 36 | .vscode/ 37 | /logs 38 | *.log 39 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/constant/SipCommandType.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.constant; 2 | 3 | /** 4 | * sip命令类型 5 | */ 6 | public class SipCommandType { 7 | 8 | /** 9 | * 设备信息 10 | */ 11 | public static final String DEVICE_INFO = "DeviceInfo"; 12 | /** 13 | * 设备状态 14 | */ 15 | public static final String DEVICE_STATUS = "DeviceStatus"; 16 | /** 17 | * 设备目录 18 | */ 19 | public static final String CATALOG = "Catalog"; 20 | /** 21 | * 设备状态信息报送 22 | */ 23 | public static final String KEEPALIVE = "Keepalive"; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipDeviceRegisterException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * 设备注册异常 5 | */ 6 | public class SipDeviceRegisterException extends Exception { 7 | 8 | public SipDeviceRegisterException() { 9 | 10 | } 11 | 12 | public SipDeviceRegisterException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipDeviceRegisterException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipDeviceRegisterException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipCommandExecuteException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip请求创建异常 5 | */ 6 | public class SipCommandExecuteException extends Exception { 7 | 8 | public SipCommandExecuteException() { 9 | 10 | } 11 | 12 | public SipCommandExecuteException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipCommandExecuteException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipCommandExecuteException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipRequestCreationException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip请求创建异常 5 | */ 6 | public class SipRequestCreationException extends Exception { 7 | 8 | public SipRequestCreationException() { 9 | 10 | } 11 | 12 | public SipRequestCreationException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipRequestCreationException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipRequestCreationException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | node_modules 4 | 5 | # Quasar core related directories 6 | .quasar 7 | /dist 8 | 9 | # Cordova related directories and files 10 | /src-cordova/node_modules 11 | /src-cordova/platforms 12 | /src-cordova/plugins 13 | /src-cordova/www 14 | 15 | # Capacitor related directories and files 16 | /src-capacitor/www 17 | /src-capacitor/node_modules 18 | 19 | # BEX related directories and files 20 | /src-bex/www 21 | /src-bex/js/core 22 | 23 | # Log files 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # Editor directories and files 29 | .idea 30 | *.suo 31 | *.ntvs* 32 | *.njsproj 33 | *.sln 34 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/record/mapper/VideoQualityDetectRecordMapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.record.mapper; 2 | 3 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordPO; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 视频质量检测记录表 Mapper 接口 10 | *

11 | * 12 | * @author RabbitNoTeeth 13 | * @since 2021-06-11 14 | */ 15 | @Mapper 16 | public interface VideoQualityDetectRecordMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /web/src/pages/Error404.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/openapi/service/IOpenApiService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.openapi.service; 2 | 3 | import fun.bookish.blueberry.server.openapi.entity.OpenDeviceStatusVO; 4 | import fun.bookish.blueberry.server.openapi.entity.OpenDeviceVO; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * open api 服务类 11 | *

12 | * 13 | * @author RabbitNoTeeth 14 | * @since 2021-06-11 15 | */ 16 | public interface IOpenApiService { 17 | 18 | List queryDeviceStatusList(); 19 | 20 | OpenDeviceStatusVO queryDeviceStatus(String id); 21 | 22 | List queryDeviceList(); 23 | } 24 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/event/SipEventTypeEnum.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.event; 2 | 3 | public enum SipEventTypeEnum { 4 | 5 | /** 6 | * 设备注册 7 | */ 8 | DEVICE_REGISTER, 9 | /** 10 | * 设备注销 11 | */ 12 | DEVICE_LOGOUT, 13 | /** 14 | * 设备信息响应 15 | */ 16 | DEVICE_INFO_RESPONSE, 17 | /** 18 | * 设备状态响应 19 | */ 20 | DEVICE_STATUS_RESPONSE, 21 | /** 22 | * 设备目录响应 23 | */ 24 | CATALOG_RESPONSE, 25 | /** 26 | * 设备状态信息报送通知 27 | */ 28 | KEEPALIVE_NOTIFY, 29 | /** 30 | * 媒体流点播成功 31 | */ 32 | MEDIA_INVITE_SUCCESS; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmetic/mapper/VideoQualityDetectArithmeticMapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmetic.mapper; 2 | 3 | import fun.bookish.blueberry.server.videoqualitydetect.arithmetic.entity.VideoQualityDetectArithmeticPO; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 视频质量检测算法 Mapper 接口 10 | *

11 | * 12 | * @author RabbitNoTeeth 13 | * @since 2021-06-10 14 | */ 15 | @Mapper 16 | public interface VideoQualityDetectArithmeticMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipCatalogResponseCreationException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip请求创建异常 5 | */ 6 | public class SipCatalogResponseCreationException extends Exception { 7 | 8 | public SipCatalogResponseCreationException() { 9 | 10 | } 11 | 12 | public SipCatalogResponseCreationException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipCatalogResponseCreationException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipCatalogResponseCreationException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipKeepaliveResponseCreationException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip请求创建异常 5 | */ 6 | public class SipKeepaliveResponseCreationException extends Exception { 7 | 8 | public SipKeepaliveResponseCreationException() { 9 | 10 | } 11 | 12 | public SipKeepaliveResponseCreationException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipKeepaliveResponseCreationException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipKeepaliveResponseCreationException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipClientTransactionCreationException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip客户端会话事务创建异常 5 | */ 6 | public class SipClientTransactionCreationException extends Exception { 7 | 8 | public SipClientTransactionCreationException() { 9 | 10 | } 11 | 12 | public SipClientTransactionCreationException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipClientTransactionCreationException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipClientTransactionCreationException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipDeviceInfoResponseCreationException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip请求创建异常 5 | */ 6 | public class SipDeviceInfoResponseCreationException extends Exception { 7 | 8 | public SipDeviceInfoResponseCreationException() { 9 | 10 | } 11 | 12 | public SipDeviceInfoResponseCreationException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipDeviceInfoResponseCreationException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipDeviceInfoResponseCreationException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /web/src/layouts/MenuTree.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 32 | 33 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmeticapplydevice/service/IVideoQualityDetectArithmeticApplyDeviceService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.service; 2 | 3 | import fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.entity.VideoQualityDetectArithmeticApplyDevicePO; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 视频质量检测算法应用设备表 服务类 9 | *

10 | * 11 | * @author RabbitNoTeeth 12 | * @since 2021-06-15 13 | */ 14 | public interface IVideoQualityDetectArithmeticApplyDeviceService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/sip/SipServerConfiguration.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.sip; 2 | 3 | import fun.bookish.blueberry.server.sip.conf.SipProperties; 4 | import fun.bookish.blueberry.sip.SipServer; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | public class SipServerConfiguration { 10 | 11 | @Bean 12 | public SipServer sipServer(SipProperties sipProperties) { 13 | SipServer sipServer = new SipServer.Builder(sipProperties.mapToSipServerConf()) 14 | .build(); 15 | sipServer.start(); 16 | return sipServer; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/exception/SipDeviceStatusResponseCreationException.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.exception; 2 | 3 | /** 4 | * sip请求创建异常 5 | */ 6 | public class SipDeviceStatusResponseCreationException extends Exception { 7 | 8 | public SipDeviceStatusResponseCreationException() { 9 | 10 | } 11 | 12 | public SipDeviceStatusResponseCreationException(String message) { 13 | super(message); 14 | } 15 | 16 | public SipDeviceStatusResponseCreationException(String message, Throwable e) { 17 | super(message, e); 18 | } 19 | 20 | public SipDeviceStatusResponseCreationException(Throwable e) { 21 | super(e); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /web/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "src/*": [ 6 | "src/*" 7 | ], 8 | "app/*": [ 9 | "*" 10 | ], 11 | "components/*": [ 12 | "src/components/*" 13 | ], 14 | "layouts/*": [ 15 | "src/layouts/*" 16 | ], 17 | "pages/*": [ 18 | "src/pages/*" 19 | ], 20 | "assets/*": [ 21 | "src/assets/*" 22 | ], 23 | "boot/*": [ 24 | "src/boot/*" 25 | ], 26 | "vue$": [ 27 | "node_modules/vue/dist/vue.esm.js" 28 | ] 29 | } 30 | }, 31 | "exclude": [ 32 | "dist", 33 | ".quasar", 34 | "node_modules" 35 | ] 36 | } -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/schedule/conf/VideoNoReaderCheckProperties.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.schedule.conf; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties(prefix = "video-no-reader-check") 8 | public class VideoNoReaderCheckProperties { 9 | 10 | /** 11 | * 无人观看状态的视频流存活时间 12 | */ 13 | private int aliveSeconds = 180; 14 | 15 | public int getAliveSeconds() { 16 | return aliveSeconds; 17 | } 18 | 19 | public void setAliveSeconds(int aliveSeconds) { 20 | this.aliveSeconds = aliveSeconds; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipSubscribeRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | 6 | /** 7 | * SUBSCRIBE请求处理器 8 | */ 9 | public class SipSubscribeRequestHandler extends AbstractSipRequestHandler { 10 | 11 | @Override 12 | public void beforeHandle(SipRequestWrapper requestWrapper) { 13 | 14 | } 15 | 16 | @Override 17 | public void doHandle(SipRequestWrapper requestWrapper) { 18 | 19 | } 20 | 21 | @Override 22 | public void afterHandle(SipRequestWrapper requestWrapper) { 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/query/param/SipQueryDeviceInfoParam.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.query.param; 2 | 3 | import fun.bookish.blueberry.sip.command.executor.param.SipCommandParam; 4 | 5 | /** 6 | * 设备信息查询参数 7 | */ 8 | public class SipQueryDeviceInfoParam extends SipCommandParam { 9 | 10 | private final String queryDeviceId; 11 | 12 | public SipQueryDeviceInfoParam(String deviceId, String deviceAddress, String queryDeviceId, String protocolType) { 13 | super(deviceId, deviceAddress, protocolType); 14 | this.queryDeviceId = queryDeviceId; 15 | } 16 | 17 | public String getQueryDeviceId() { 18 | return queryDeviceId; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/query/param/SipQueryDeviceStatusParam.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.query.param; 2 | 3 | import fun.bookish.blueberry.sip.command.executor.param.SipCommandParam; 4 | 5 | /** 6 | * 设备状态查询参数 7 | */ 8 | public class SipQueryDeviceStatusParam extends SipCommandParam { 9 | 10 | private final String queryDeviceId; 11 | 12 | public SipQueryDeviceStatusParam(String deviceId, String deviceAddress, String queryDeviceId, String protocolType) { 13 | super(deviceId, deviceAddress, protocolType); 14 | this.queryDeviceId = queryDeviceId; 15 | } 16 | 17 | public String getQueryDeviceId() { 18 | return queryDeviceId; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/page/PageResult.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.page; 2 | 3 | import java.util.List; 4 | 5 | public class PageResult { 6 | 7 | private long total; 8 | 9 | private List data; 10 | 11 | public PageResult() { 12 | } 13 | 14 | public PageResult(long total, List data) { 15 | this.total = total; 16 | this.data = data; 17 | } 18 | 19 | public long getTotal() { 20 | return total; 21 | } 22 | 23 | public void setTotal(long total) { 24 | this.total = total; 25 | } 26 | 27 | public List getData() { 28 | return data; 29 | } 30 | 31 | public void setData(List data) { 32 | this.data = data; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmeticapplydevice/mapper/VideoQualityDetectArithmeticApplyDeviceMapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.mapper; 2 | 3 | import fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.entity.VideoQualityDetectArithmeticApplyDevicePO; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 视频质量检测算法应用设备表 Mapper 接口 10 | *

11 | * 12 | * @author RabbitNoTeeth 13 | * @since 2021-06-15 14 | */ 15 | @Mapper 16 | public interface VideoQualityDetectArithmeticApplyDeviceMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videostream/entity/VideoStreamVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videostream.entity; 2 | 3 | public class VideoStreamVO { 4 | 5 | private String id; 6 | private String flvUrl; 7 | private String snap; 8 | 9 | public String getId() { 10 | return id; 11 | } 12 | 13 | public void setId(String id) { 14 | this.id = id; 15 | } 16 | 17 | public String getFlvUrl() { 18 | return flvUrl; 19 | } 20 | 21 | public void setFlvUrl(String flvUrl) { 22 | this.flvUrl = flvUrl; 23 | } 24 | 25 | public String getSnap() { 26 | return snap; 27 | } 28 | 29 | public void setSnap(String snap) { 30 | this.snap = snap; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/channel/mapper/xml/ChannelMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/query/AbstractSipQueryCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.query; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | import fun.bookish.blueberry.sip.exception.SipClientTransactionCreationException; 5 | 6 | import javax.sip.ClientTransaction; 7 | import javax.sip.SipProvider; 8 | import javax.sip.message.Request; 9 | 10 | public abstract class AbstractSipQueryCommandExecutor implements SipQueryCommandExecutor{ 11 | 12 | protected final SipServer sipServer; 13 | 14 | protected AbstractSipQueryCommandExecutor(SipServer sipServer) { 15 | this.sipServer = sipServer; 16 | } 17 | 18 | public final SipServer getSipServer() { 19 | return this.sipServer; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/permission/PermissionProperties.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.permission; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties(prefix = "permission") 8 | public class PermissionProperties { 9 | 10 | private Boolean check = true; 11 | 12 | private String code; 13 | 14 | public Boolean getCheck() { 15 | return check; 16 | } 17 | 18 | public void setCheck(Boolean check) { 19 | this.check = check; 20 | } 21 | 22 | public String getCode() { 23 | return code; 24 | } 25 | 26 | public void setCode(String code) { 27 | this.code = code; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipDeviceAlarmStatusDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | /** 4 | * 设备报警状态描述 5 | */ 6 | public class SipDeviceAlarmStatusDesc { 7 | 8 | /** 9 | * 报警设备编码(必选) 10 | */ 11 | private final String deviceId; 12 | /** 13 | * 报警设备状态(必选) 14 | * ONDUTY 15 | * OFFDUTY 16 | * ALARM 17 | */ 18 | private final String dutyStatus; 19 | 20 | public SipDeviceAlarmStatusDesc(String deviceId, String dutyStatus) { 21 | this.deviceId = deviceId; 22 | this.dutyStatus = dutyStatus; 23 | } 24 | 25 | public String getDeviceId() { 26 | return deviceId; 27 | } 28 | 29 | public String getDutyStatus() { 30 | return dutyStatus; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/schedule/conf/VideoQualityDetectProperties.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.schedule.conf; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.List; 7 | 8 | @Component 9 | @ConfigurationProperties(prefix = "video-quality-detect") 10 | public class VideoQualityDetectProperties { 11 | 12 | /** 13 | * 支持的算法列表 14 | */ 15 | private List supportedArithmetics; 16 | 17 | public List getSupportedArithmetics() { 18 | return supportedArithmetics; 19 | } 20 | 21 | public void setSupportedArithmetics(List supportedArithmetics) { 22 | this.supportedArithmetics = supportedArithmetics; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/response/handler/AbstractSipResponseHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.response.handler; 2 | 3 | import fun.bookish.blueberry.sip.response.model.SipResponseWrapper; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | /** 8 | * sip响应处理器接口 9 | */ 10 | public abstract class AbstractSipResponseHandler implements SipResponseHandler { 11 | 12 | private static final Logger LOGGER_ = LoggerFactory.getLogger(AbstractSipResponseHandler.class); 13 | 14 | /** 15 | * 进行响应处理 16 | * 17 | * @param responseWrapper 18 | */ 19 | public final void handle(SipResponseWrapper responseWrapper){ 20 | beforeHandle(responseWrapper); 21 | doHandle(responseWrapper); 22 | afterHandle(responseWrapper); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/page/PageInterceptorConfiguration.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.page; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class PageInterceptorConfiguration { 11 | 12 | @Bean 13 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 14 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 15 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 16 | return interceptor; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /m-opencv/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blueberry 7 | fun.bookish 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | m-opencv 13 | 14 | 15 | 1.8 16 | 17 | 18 | 19 | 20 | org.bytedeco 21 | opencv-platform 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipCatalogDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | import fun.bookish.blueberry.sip.event.SipEventTypeEnum; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * catalog描述 9 | */ 10 | public class SipCatalogDesc extends SipDeviceDesc{ 11 | 12 | private List channelList; 13 | 14 | public SipCatalogDesc(String requestDeviceID, String requestDeviceAddress,String deviceId, String registerServer, SipEventTypeEnum eventType) { 15 | super(requestDeviceID, requestDeviceAddress, deviceId, registerServer, eventType); 16 | } 17 | 18 | public List getChannelList() { 19 | return channelList; 20 | } 21 | 22 | public void setChannelList(List channelList) { 23 | this.channelList = channelList; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/zlmedia/model/ZLStreamAddStreamProxyResponse.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.zlmedia.model; 2 | 3 | public class ZLStreamAddStreamProxyResponse { 4 | 5 | private Integer code; 6 | private Data data; 7 | 8 | public Integer getCode() { 9 | return code; 10 | } 11 | 12 | public void setCode(Integer code) { 13 | this.code = code; 14 | } 15 | 16 | public Data getData() { 17 | return data; 18 | } 19 | 20 | public void setData(Data data) { 21 | this.data = data; 22 | } 23 | 24 | public static class Data { 25 | private String key; 26 | 27 | public String getKey() { 28 | return key; 29 | } 30 | 31 | public void setKey(String key) { 32 | this.key = key; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/manager/SipCommandExecutorManager.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.manager; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | import fun.bookish.blueberry.sip.command.executor.media.SipMediaCommandExecutor; 5 | import fun.bookish.blueberry.sip.command.executor.query.SipQueryCommandExecutor; 6 | import fun.bookish.blueberry.sip.command.manager.impl.SipCommandExecutorManagerImpl; 7 | 8 | /** 9 | * sip命令执行器管理器 10 | */ 11 | public interface SipCommandExecutorManager { 12 | 13 | static SipCommandExecutorManager create(SipServer sipServer) { 14 | return new SipCommandExecutorManagerImpl(sipServer); 15 | } 16 | 17 | SipServer getSipServer(); 18 | 19 | SipQueryCommandExecutor getSipQueryCommandExecutor(); 20 | 21 | SipMediaCommandExecutor getSipMediaCommandExecutor(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /web/src/css/quasar.variables.scss: -------------------------------------------------------------------------------- 1 | // Quasar SCSS (& Sass) Variables 2 | // -------------------------------------------------- 3 | // To customize the look and feel of this app, you can override 4 | // the Sass/SCSS variables found in Quasar's source Sass/SCSS files. 5 | 6 | // Check documentation for full list of Quasar variables 7 | 8 | // Your own variables (that are declared here) and Quasar's own 9 | // ones will be available out of the box in your .vue/.scss/.sass files 10 | 11 | // It's highly recommended to change the default colors 12 | // to match your app's branding. 13 | // Tip: Use the "Theme Builder" on Quasar's documentation website. 14 | 15 | $primary : #1976D2; 16 | $secondary : #26A69A; 17 | $accent : #9C27B0; 18 | 19 | $dark : #1D1D1D; 20 | 21 | $positive : #21BA45; 22 | $negative : #C10015; 23 | $info : #31CCEC; 24 | $warning : #F2C037; 25 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/utils/Base64Utils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.utils; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.util.Base64; 5 | 6 | public class Base64Utils { 7 | 8 | private Base64Utils() {} 9 | 10 | public static String encode(byte[] bytes) { 11 | return Base64.getEncoder().encodeToString(bytes); 12 | } 13 | 14 | public static String encode(String str) { 15 | return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8)); 16 | } 17 | 18 | public static byte[] decode2bytes(String str) { 19 | return Base64.getDecoder().decode(str); 20 | } 21 | 22 | public static String decode2string(String str) { 23 | return new String(Base64.getDecoder().decode(str.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/zlmedia/model/ZLStreamCloseResponse.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.zlmedia.model; 2 | 3 | public class ZLStreamCloseResponse { 4 | 5 | private Integer code; 6 | private Integer count_hit; 7 | private Integer count_closed; 8 | 9 | public Integer getCode() { 10 | return code; 11 | } 12 | 13 | public void setCode(Integer code) { 14 | this.code = code; 15 | } 16 | 17 | public Integer getCount_hit() { 18 | return count_hit; 19 | } 20 | 21 | public void setCount_hit(Integer count_hit) { 22 | this.count_hit = count_hit; 23 | } 24 | 25 | public Integer getCount_closed() { 26 | return count_closed; 27 | } 28 | 29 | public void setCount_closed(Integer count_closed) { 30 | this.count_closed = count_closed; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/response/handler/SipResponseHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.response.handler; 2 | 3 | import fun.bookish.blueberry.sip.response.model.SipResponseWrapper; 4 | 5 | /** 6 | * sip请求处理器接口 7 | */ 8 | public interface SipResponseHandler { 9 | 10 | /** 11 | * 请求预处理 12 | * @param responseWrapper 13 | */ 14 | void beforeHandle(SipResponseWrapper responseWrapper); 15 | 16 | /** 17 | * 进行请求处理 18 | * 19 | * @param responseWrapper 20 | */ 21 | void handle(SipResponseWrapper responseWrapper); 22 | 23 | /** 24 | * 处理请求 25 | * @param responseWrapper 26 | */ 27 | void doHandle(SipResponseWrapper responseWrapper); 28 | 29 | /** 30 | * 请求后置处理 31 | * @param responseWrapper 32 | */ 33 | void afterHandle(SipResponseWrapper responseWrapper); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/mvc/WebMvcConfiguration.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.mvc; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.http.converter.HttpMessageConverter; 5 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | import java.util.List; 9 | 10 | @Configuration 11 | public class WebMvcConfiguration implements WebMvcConfigurer { 12 | 13 | @Override 14 | public void configureMessageConverters(List> converters) { 15 | WebMvcConfigurer.super.configureMessageConverters(converters); 16 | // 解决 ControllerResponseBodyAdvice 对接口响应进行统一包装时,String类型发生强转异常的问题 17 | converters.add(0, new MappingJackson2HttpMessageConverter()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/response/handler/impl/SipByeResponseHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.response.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.response.handler.AbstractSipResponseHandler; 4 | import fun.bookish.blueberry.sip.response.model.SipResponseWrapper; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * BYE响应处理器 10 | */ 11 | public class SipByeResponseHandler extends AbstractSipResponseHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipByeResponseHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipResponseWrapper responseWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipResponseWrapper responseWrapper) { 22 | // todo 触发相关事件,以便客户端能知道关流是否成功 23 | } 24 | 25 | @Override 26 | public void afterHandle(SipResponseWrapper responseWrapper) { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/response/handler/impl/SipUnknownResponseHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.response.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.response.handler.AbstractSipResponseHandler; 4 | import fun.bookish.blueberry.sip.response.model.SipResponseWrapper; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * 未知请求处理器 10 | */ 11 | public class SipUnknownResponseHandler extends AbstractSipResponseHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipUnknownResponseHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipResponseWrapper responseWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipResponseWrapper responseWrapper) { 22 | LOGGER.warn("暂不支持未知类型消息处理..."); 23 | } 24 | 25 | @Override 26 | public void afterHandle(SipResponseWrapper responseWrapper) { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /web/src/components/EssentialLink.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 50 | -------------------------------------------------------------------------------- /m-quartz/src/main/java/fun/bookish/blueberry/quartz/entity/MisfireInstruction.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.quartz.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 补偿策略实体类 7 | * 8 | * @author Don9 9 | */ 10 | public class MisfireInstruction implements Serializable { 11 | private static final long serialVersionUID = 5320773166527619894L; 12 | 13 | private String name; 14 | 15 | private Integer value; 16 | 17 | public MisfireInstruction() { 18 | } 19 | 20 | public MisfireInstruction(String name, Integer value) { 21 | this.name = name; 22 | this.value = value; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public Integer getValue() { 34 | return value; 35 | } 36 | 37 | public void setValue(Integer value) { 38 | this.value = value; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/model/SipRequestWrapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.model; 2 | 3 | 4 | import fun.bookish.blueberry.sip.SipServer; 5 | 6 | import javax.sip.*; 7 | 8 | /** 9 | * sip请求包装类 10 | */ 11 | public class SipRequestWrapper { 12 | 13 | private final SipServer sipServer; 14 | 15 | private final RequestEvent requestEvent; 16 | 17 | private Object data; 18 | 19 | public SipRequestWrapper(SipServer sipServer, RequestEvent requestEvent) { 20 | this.sipServer = sipServer; 21 | this.requestEvent = requestEvent; 22 | } 23 | 24 | public SipServer getSipServer() { 25 | return sipServer; 26 | } 27 | 28 | public RequestEvent getRequestEvent() { 29 | return requestEvent; 30 | } 31 | 32 | public void setData(Object data) { 33 | this.data = data; 34 | } 35 | 36 | public Object getData() { 37 | return this.data; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipUnknownRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * 未知请求处理器 10 | */ 11 | public class SipUnknownRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipUnknownRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | LOGGER.warn("暂不支持{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 23 | } 24 | 25 | @Override 26 | public void afterHandle(SipRequestWrapper requestWrapper) { 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipByeRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * BYE请求处理器 10 | */ 11 | public class SipByeRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipByeRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现BYE类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipInfoRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * INFO请求处理器 10 | */ 11 | public class SipInfoRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipInfoRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现INFO类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipPrackRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * PRACK请求处理器 10 | */ 11 | public class SipPrackRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipPrackRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现PRACK类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipReferRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * REFER请求处理器 10 | */ 11 | public class SipReferRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipReferRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现REFER类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /web/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | import ElementUI from 'element-ui'; 4 | import 'element-ui/lib/theme-chalk/index.css'; 5 | 6 | import routes from './routes'; 7 | 8 | Vue.use(VueRouter); 9 | Vue.use(ElementUI); 10 | 11 | /* 12 | * If not building with SSR mode, you can 13 | * directly export the Router instantiation; 14 | * 15 | * The function below can be async too; either use 16 | * async/await or return a Promise which resolves 17 | * with the Router instance. 18 | */ 19 | 20 | export default function (/* { store, ssrContext } */) { 21 | const Router = new VueRouter({ 22 | scrollBehavior: () => ({ x: 0, y: 0 }), 23 | routes, 24 | 25 | // Leave these as they are and change in quasar.conf.js instead! 26 | // quasar.conf.js -> build -> vueRouterMode 27 | // quasar.conf.js -> build -> publicPath 28 | mode: process.env.VUE_ROUTER_MODE, 29 | base: process.env.VUE_ROUTER_BASE 30 | }) 31 | 32 | return Router 33 | } 34 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/event/SipEventContext.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.event; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | 5 | /** 6 | * sip事件上下文 7 | */ 8 | public class SipEventContext { 9 | 10 | /** 11 | * 事件类型 12 | */ 13 | private final SipEventTypeEnum sipEventTypeEnum; 14 | /** 15 | * sip服务 16 | */ 17 | private final SipServer sipServer; 18 | /** 19 | * 数据 20 | */ 21 | private final T data; 22 | 23 | public SipEventContext(SipEventTypeEnum sipEventTypeEnum, SipServer sipServer, T data) { 24 | this.sipEventTypeEnum = sipEventTypeEnum; 25 | this.sipServer = sipServer; 26 | this.data = data; 27 | } 28 | 29 | public SipEventTypeEnum getSipEventTypeEnum() { 30 | return sipEventTypeEnum; 31 | } 32 | 33 | public SipServer getSipServer() { 34 | return sipServer; 35 | } 36 | 37 | public T getData() { 38 | return data; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipCancelRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * CANCEL请求处理器 10 | */ 11 | public class SipCancelRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipCancelRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现CANCEL类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipInviteRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * INVITE请求处理器 10 | */ 11 | public class SipInviteRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipInviteRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现INVITE类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipNotifyRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * NOTIFY请求处理器 10 | */ 11 | public class SipNotifyRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipNotifyRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现NOTIFY类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipUpdateRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * UPDATE请求处理器 10 | */ 11 | public class SipUpdateRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipUpdateRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现UPDATE类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipOptionsRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * OPTIONS请求处理器 10 | */ 11 | public class SipOptionsRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipOptionsRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现OPTIONS类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipPublishRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * PUBLISH请求处理器 10 | */ 11 | public class SipPublishRequestHandler extends AbstractSipRequestHandler { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SipPublishRequestHandler.class); 14 | 15 | @Override 16 | public void beforeHandle(SipRequestWrapper requestWrapper) { 17 | 18 | } 19 | 20 | @Override 21 | public void doHandle(SipRequestWrapper requestWrapper) { 22 | // todo 实现PUBLISH类型消息处理 23 | LOGGER.warn("暂未实现{}类型消息处理...", requestWrapper.getRequestEvent().getRequest().getMethod()); 24 | } 25 | 26 | @Override 27 | public void afterHandle(SipRequestWrapper requestWrapper) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/channel/entity/ChannelStatusSync.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.channel.entity; 2 | 3 | public class ChannelStatusSync { 4 | 5 | private String id; 6 | private String deviceId; 7 | private String address; 8 | private String transport; 9 | 10 | public String getId() { 11 | return id; 12 | } 13 | 14 | public void setId(String id) { 15 | this.id = id; 16 | } 17 | 18 | public String getDeviceId() { 19 | return deviceId; 20 | } 21 | 22 | public void setDeviceId(String deviceId) { 23 | this.deviceId = deviceId; 24 | } 25 | 26 | public String getAddress() { 27 | return address; 28 | } 29 | 30 | public void setAddress(String address) { 31 | this.address = address; 32 | } 33 | 34 | public String getTransport() { 35 | return transport; 36 | } 37 | 38 | public void setTransport(String transport) { 39 | this.transport = transport; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/response/model/SipResponseWrapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.response.model; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | 5 | import javax.sip.RequestEvent; 6 | import javax.sip.ResponseEvent; 7 | 8 | /** 9 | * sip响应包装类 10 | */ 11 | public class SipResponseWrapper { 12 | 13 | private final SipServer sipServer; 14 | 15 | private final ResponseEvent responseEvent; 16 | 17 | private Object data; 18 | 19 | public SipResponseWrapper(SipServer sipServer, ResponseEvent responseEvent) { 20 | this.sipServer = sipServer; 21 | this.responseEvent = responseEvent; 22 | } 23 | 24 | public SipServer getSipServer() { 25 | return sipServer; 26 | } 27 | 28 | public ResponseEvent getResponseEvent() { 29 | return responseEvent; 30 | } 31 | 32 | public void setData(Object data) { 33 | this.data = data; 34 | } 35 | 36 | public Object getData() { 37 | return this.data; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videostream/entity/VideoStreamSnapshot.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videostream.entity; 2 | 3 | public class VideoStreamSnapshot { 4 | 5 | private byte[] data; 6 | private String savePath; 7 | private String dirPath; 8 | private String fileName; 9 | 10 | public byte[] getData() { 11 | return data; 12 | } 13 | 14 | public void setData(byte[] data) { 15 | this.data = data; 16 | } 17 | 18 | public String getSavePath() { 19 | return savePath; 20 | } 21 | 22 | public void setSavePath(String savePath) { 23 | this.savePath = savePath; 24 | } 25 | 26 | public String getDirPath() { 27 | return dirPath; 28 | } 29 | 30 | public void setDirPath(String dirPath) { 31 | this.dirPath = dirPath; 32 | } 33 | 34 | public String getFileName() { 35 | return fileName; 36 | } 37 | 38 | public void setFileName(String fileName) { 39 | this.fileName = fileName; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmetic/entity/VideoQualityDetectArithmeticApplicableDeviceVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmetic.entity; 2 | 3 | import java.util.List; 4 | 5 | public class VideoQualityDetectArithmeticApplicableDeviceVO { 6 | 7 | private String code; 8 | private String name; 9 | private List children; 10 | 11 | public String getCode() { 12 | return code; 13 | } 14 | 15 | public void setCode(String code) { 16 | this.code = code; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public List getChildren() { 28 | return children; 29 | } 30 | 31 | public void setChildren(List children) { 32 | this.children = children; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /m-quartz/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blueberry 7 | fun.bookish 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | m-quartz 13 | 14 | 15 | 1.8 16 | 17 | 18 | 19 | 20 | fun.bookish 21 | m-core 22 | ${project.version} 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-quartz 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/event/listener/manager/SipEventListenerManager.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.event.listener.manager; 2 | 3 | 4 | import fun.bookish.blueberry.sip.SipServer; 5 | import fun.bookish.blueberry.sip.event.listener.SipEventListener; 6 | import fun.bookish.blueberry.sip.event.listener.manager.impl.SipEventListenerManagerImpl; 7 | import fun.bookish.blueberry.sip.event.SipEventContext; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * sip事件管理器接口 13 | */ 14 | public interface SipEventListenerManager { 15 | 16 | static SipEventListenerManager create(SipServer sipServer){ 17 | return new SipEventListenerManagerImpl(sipServer); 18 | } 19 | 20 | /** 21 | * 添加事件监听 22 | * @param listener 23 | */ 24 | void add(SipEventListener listener); 25 | 26 | /** 27 | * 添加事件监听 28 | * @param listeners 29 | */ 30 | void addAll(List listeners); 31 | 32 | /** 33 | * 触发回调 34 | * @return 35 | */ 36 | void fire(SipEventContext sipEventContext); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /web/src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= productName %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videostream/entity/VideoStreamPlayResponse.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videostream.entity; 2 | 3 | /** 4 | * 媒体播放实体 5 | */ 6 | public class VideoStreamPlayResponse { 7 | 8 | private String deviceId; 9 | private String channelId; 10 | private String streamId; 11 | private String flv; 12 | 13 | public String getDeviceId() { 14 | return deviceId; 15 | } 16 | 17 | public void setDeviceId(String deviceId) { 18 | this.deviceId = deviceId; 19 | } 20 | 21 | public String getChannelId() { 22 | return channelId; 23 | } 24 | 25 | public void setChannelId(String channelId) { 26 | this.channelId = channelId; 27 | } 28 | 29 | public String getFlv() { 30 | return flv; 31 | } 32 | 33 | public void setFlv(String flv) { 34 | this.flv = flv; 35 | } 36 | 37 | public String getStreamId() { 38 | return streamId; 39 | } 40 | 41 | public void setStreamId(String streamId) { 42 | this.streamId = streamId; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 刘新冬 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipKeepaliveDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | 4 | import fun.bookish.blueberry.sip.event.SipEventTypeEnum; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 设备状态信息报送描述 10 | */ 11 | public class SipKeepaliveDesc extends SipDeviceDesc{ 12 | 13 | /** 14 | * 是否正常工作(必选): 15 | * OK 16 | * ERROR 17 | */ 18 | private String status; 19 | /** 20 | * 故障设备列表(可选) 21 | */ 22 | private List info; 23 | 24 | public SipKeepaliveDesc(String requestDeviceID, String requestDeviceAddress,String deviceId, String registerServer, SipEventTypeEnum eventType) { 25 | super(requestDeviceID, requestDeviceAddress, deviceId, registerServer, eventType); 26 | } 27 | 28 | public String getStatus() { 29 | return status; 30 | } 31 | 32 | public void setStatus(String status) { 33 | this.status = status; 34 | } 35 | 36 | public List getInfo() { 37 | return info; 38 | } 39 | 40 | public void setInfo(List info) { 41 | this.info = info; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /web/src/pages/stream/StreamViewer2.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 44 | 45 | 48 | -------------------------------------------------------------------------------- /doc/部署文档.md: -------------------------------------------------------------------------------- 1 | # 1 ZLMediaKit 安装 2 | 3 | ## 1.1 windows 4 | 5 | ### 1.1.1 安装依赖库 6 | 7 | #### 1.1.1.1 ffmpeg 8 | 9 | 1. [官网下载](https://ffmpeg.en.softonic.com/download)或者[网盘下载(提取码:1234)](https://pan.baidu.com/s/1CoF6KzcB2oETtXsWK7gE-g)项目中提供的安装程序。 10 | 2. 解压安装文件,配置环境变量,指向ffmpeg.exe所在目录。 11 | 12 | ### 1.1.2 安装 ZLMediaKit 13 | 14 | 1. 可拉取ZLMediaKit[源代码](https://github.com/ZLMediaKit/ZLMediaKit)进行构建,参考[官方构建指南](https://github.com/ZLMediaKit/ZLMediaKit/wiki/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B)。 15 | 2. 也可[网盘下载(提取码:1234)](https://pan.baidu.com/s/1-BF6f5e3TbH1whuwclNsCA)已构建好的可执行程序。 16 | 17 | ### 1.1.3 启动 ZLMediaKit 18 | 19 | 1. 如果使用1.1.2中1方式构建安装,进入ZLMediaKit构建目录,运行 **release/windows/Debug** 目录下的可执行程序 **MediaServer.exe** 20 | 2. 如果使用1.1.2中2方式,解压已构建好的程序,执行解压目录下的可执行程序 **MediaServer.exe** 21 | 22 | # 2 数据库安装 23 | 1. 安装mysql数据库(推荐5.7版本) 24 | 2. 创建blueberry数据库,执行blueberry项目中database目录下 blueberry.sql 进行数据库表初始化 25 | 26 | # 3 Blueberry 部署 27 | 28 | 1. 更新项目代码。 29 | 30 | 2. 进入项目目录,执行maven命令进行打包。 31 | 32 | ![](./resources/images/blueberry-package.png) 33 | 34 | 3. 打包完成后,在 **m-manage/target** 目录下可找到jar文件。 35 | 36 | ![](./resources/images/blueberry-jar.png) 37 | 38 | 4. 运行jar包。 39 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmeticapplydevice/service/impl/VideoQualityDetectArithmeticApplyDeviceServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.service.impl; 2 | 3 | import fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.entity.VideoQualityDetectArithmeticApplyDevicePO; 4 | import fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.mapper.VideoQualityDetectArithmeticApplyDeviceMapper; 5 | import fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.service.IVideoQualityDetectArithmeticApplyDeviceService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 视频质量检测算法应用设备表 服务实现类 12 | *

13 | * 14 | * @author RabbitNoTeeth 15 | * @since 2021-06-15 16 | */ 17 | @Service 18 | public class VideoQualityDetectArithmeticApplyDeviceServiceImpl extends ServiceImpl implements IVideoQualityDetectArithmeticApplyDeviceService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/query/param/SipQueryCatalogParam.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.query.param; 2 | 3 | import fun.bookish.blueberry.sip.command.executor.param.SipCommandParam; 4 | 5 | /** 6 | * 设备目录查询参数 7 | */ 8 | public class SipQueryCatalogParam extends SipCommandParam { 9 | 10 | private final String queryDeviceId; 11 | 12 | private String startTime; 13 | 14 | private String endTime; 15 | 16 | public SipQueryCatalogParam(String deviceId, String deviceAddress, String queryDeviceId, String transport) { 17 | super(deviceId, deviceAddress, transport); 18 | this.queryDeviceId = queryDeviceId; 19 | } 20 | 21 | public String getStartTime() { 22 | return startTime; 23 | } 24 | 25 | public void setStartTime(String startTime) { 26 | this.startTime = startTime; 27 | } 28 | 29 | public String getEndTime() { 30 | return endTime; 31 | } 32 | 33 | public void setEndTime(String endTime) { 34 | this.endTime = endTime; 35 | } 36 | 37 | public String getQueryDeviceId() { 38 | return queryDeviceId; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/media/SipMediaCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.media; 2 | 3 | 4 | import fun.bookish.blueberry.sip.SipServer; 5 | import fun.bookish.blueberry.sip.command.executor.SipCommandExecutor; 6 | import fun.bookish.blueberry.sip.command.executor.media.impl.SipMediaCommandExecutorImpl; 7 | import fun.bookish.blueberry.sip.command.executor.media.param.SipMediaPlayParam; 8 | import fun.bookish.blueberry.sip.command.executor.media.param.SipMediaStopParam; 9 | import fun.bookish.blueberry.sip.exception.SipCommandExecuteException; 10 | 11 | /** 12 | * sip查询命令执行器接口 13 | */ 14 | public interface SipMediaCommandExecutor extends SipCommandExecutor { 15 | 16 | static SipMediaCommandExecutor create(SipServer sipServer){ 17 | return new SipMediaCommandExecutorImpl(sipServer); 18 | } 19 | 20 | /** 21 | * 点播实时媒体流 22 | * @param param 23 | * @return 24 | */ 25 | void playStart(SipMediaPlayParam param) throws SipCommandExecuteException; 26 | 27 | /** 28 | * 停止实时媒体流 29 | * @param param 30 | * @return 31 | */ 32 | void playStop(SipMediaStopParam param) throws SipCommandExecuteException; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/param/SipCommandParam.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.param; 2 | 3 | /** 4 | * 设备目录查询参数 5 | */ 6 | public class SipCommandParam { 7 | 8 | /** 9 | * 目标设备ID 10 | * 如果当前服务作为上级与其他sip服务平台进行对接时,请求发送目标可能是平台,此时就需要使用平台ID; 11 | * 否则使用要查询的设备ID,直接发送请求到被查询设备 12 | */ 13 | protected final String deviceId; 14 | /** 15 | * 目标设备地址 16 | * 如果当前服务作为上级与其他sip服务平台进行对接时,请求发送目标可能是平台,此时就需要使用平台地址; 17 | * 否则使用要查询的设备地址,直接发送请求到被查询设备 18 | */ 19 | protected final String deviceAddress; 20 | /** 21 | * 通信协议 22 | */ 23 | protected final String transport; 24 | 25 | public SipCommandParam(String deviceId, String deviceAddress, String transport) { 26 | this.deviceId = deviceId; 27 | this.deviceAddress = deviceAddress; 28 | this.transport = transport; 29 | } 30 | 31 | public String getDeviceId() { 32 | return deviceId; 33 | } 34 | 35 | public String getDeviceAddress() { 36 | return deviceAddress; 37 | } 38 | 39 | public String getTransport() { 40 | return transport; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/SipRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.sip.*; 8 | 9 | /** 10 | * sip请求处理器接口 11 | */ 12 | public interface SipRequestHandler { 13 | 14 | /** 15 | * 请求预处理 16 | * @param requestWrapper 17 | */ 18 | void beforeHandle(SipRequestWrapper requestWrapper) throws Exception; 19 | 20 | /** 21 | * 进行请求处理 22 | * 23 | * @param requestWrapper 24 | */ 25 | void handle(SipRequestWrapper requestWrapper); 26 | 27 | /** 28 | * 处理请求 29 | * @param requestWrapper 30 | */ 31 | void doHandle(SipRequestWrapper requestWrapper) throws Exception; 32 | 33 | /** 34 | * 请求后置处理 35 | * @param requestWrapper 36 | */ 37 | void afterHandle(SipRequestWrapper requestWrapper) throws Exception; 38 | 39 | /** 40 | * 获取请求的会话事务 41 | * 42 | * @param requestWrapper 43 | * @return 44 | */ 45 | ServerTransaction getServerTransaction(SipRequestWrapper requestWrapper); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/ssrc/SipSSRCManager.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.ssrc; 2 | 3 | import fun.bookish.blueberry.sip.conf.SipServerConf; 4 | import fun.bookish.blueberry.sip.ssrc.impl.SipSSRCManagerImpl; 5 | 6 | import javax.sip.Dialog; 7 | import javax.sip.SipException; 8 | 9 | /** 10 | * SRRC管理器接口 11 | */ 12 | public interface SipSSRCManager { 13 | 14 | static SipSSRCManager create(SipServerConf sipServerConf){ 15 | return new SipSSRCManagerImpl(sipServerConf); 16 | } 17 | 18 | /** 19 | * 生成实时视频点播SSRC 20 | * 21 | * @return 22 | */ 23 | String generatePlaySSRC() throws SipException; 24 | 25 | /** 26 | * 生成历史视频点播SSRC 27 | * 28 | * @return 29 | */ 30 | String generatePlayBackSSRC() throws SipException; 31 | 32 | /** 33 | * 释放ssrc 34 | * @param ssrc 35 | */ 36 | void releaseSSRC(String ssrc); 37 | 38 | /** 39 | * 通过fromTag释放ssrc 40 | * @param fromTag 41 | */ 42 | void releaseSSRCByFromTag(String fromTag); 43 | 44 | /** 45 | * 添加ssrc对应的请求tag 46 | * @param ssrc 47 | * @param fromTag 48 | */ 49 | void addFromTag(String ssrc, String fromTag); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/manual/service/IVideoQualityDetectManualService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.manual.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import fun.bookish.blueberry.core.page.PageResult; 5 | import fun.bookish.blueberry.server.videoqualitydetect.manual.entity.VideoQualityDetectManualVO; 6 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordPO; 7 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordQueryParamVO; 8 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordVO; 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import java.io.IOException; 12 | import java.util.List; 13 | 14 | /** 15 | *

16 | * 视频质量检测记录表 服务类 17 | *

18 | * 19 | * @author RabbitNoTeeth 20 | * @since 2021-06-11 21 | */ 22 | public interface IVideoQualityDetectManualService { 23 | 24 | /** 25 | * 图片上传 26 | * 27 | * @return 28 | * @param file 29 | */ 30 | VideoQualityDetectManualVO upload(MultipartFile file) throws IOException, Exception; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/constant/SipTraceLevel.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.constant; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * sip日志级别 10 | */ 11 | public class SipTraceLevel { 12 | 13 | private static final Map LEVEL_VALUE_MAP; 14 | 15 | /** 16 | * 默认的日志级别 17 | */ 18 | private static final String DEFAULT_LEVEL_VALUE = "0"; 19 | 20 | static { 21 | LEVEL_VALUE_MAP = new HashMap<>(); 22 | LEVEL_VALUE_MAP.put("NONE", "0"); 23 | LEVEL_VALUE_MAP.put("MESSAGE", "16"); 24 | LEVEL_VALUE_MAP.put("EXCEPTION", "17"); 25 | LEVEL_VALUE_MAP.put("DEBUG", "32"); 26 | } 27 | 28 | private SipTraceLevel() {} 29 | 30 | /** 31 | * 将日志级别转换为sip api中识别的值 32 | * @param level 33 | * @return 34 | */ 35 | public static String transformLevel(String level) { 36 | if (StringUtils.isBlank(level)) { 37 | return DEFAULT_LEVEL_VALUE; 38 | } 39 | String value = LEVEL_VALUE_MAP.get(level); 40 | if (StringUtils.isBlank(value)) { 41 | return DEFAULT_LEVEL_VALUE; 42 | } 43 | return value; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/channel/mapper/ChannelMapper.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.channel.mapper; 2 | 3 | import fun.bookish.blueberry.server.channel.entity.ChannelPO; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import fun.bookish.blueberry.server.channel.entity.ChannelStatusSync; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Select; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *

14 | * 设备通道表 Mapper 接口 15 | *

16 | * 17 | * @author RabbitNoTeeth 18 | * @since 2021-06-11 19 | */ 20 | @Component 21 | @Mapper 22 | public interface ChannelMapper extends BaseMapper { 23 | 24 | @Select("select\n" + 25 | " a.id as id,\n" + 26 | " a.device_id as device_id,\n" + 27 | " concat(b.remote_ip,':',b.remote_port) as address,\n" + 28 | " b.command_transport as transport\n" + 29 | " from\n" + 30 | " t_channel a\n" + 31 | " left join\n" + 32 | " t_device b on b.id = a.device_id") 33 | List queryChannelStatusSyncList(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/media/param/SipMediaPlayParam.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.media.param; 2 | 3 | import fun.bookish.blueberry.sip.command.executor.param.SipCommandParam; 4 | 5 | /** 6 | * 媒体流点播参数 7 | */ 8 | public class SipMediaPlayParam extends SipCommandParam { 9 | 10 | private final String channelId; 11 | 12 | private final String ssrc; 13 | 14 | private final String mediaServerIp; 15 | 16 | private final Integer mediaServerPort; 17 | 18 | public SipMediaPlayParam(String deviceId, String deviceAddress, String channelId, String protocolType, String ssrc, String mediaServerIp, Integer mediaServerPort) { 19 | super(deviceId, deviceAddress, protocolType); 20 | this.channelId = channelId; 21 | this.ssrc = ssrc; 22 | this.mediaServerIp = mediaServerIp; 23 | this.mediaServerPort = mediaServerPort; 24 | } 25 | 26 | public String getMediaServerIp() { 27 | return mediaServerIp; 28 | } 29 | 30 | public Integer getMediaServerPort() { 31 | return mediaServerPort; 32 | } 33 | 34 | public String getSsrc() { 35 | return ssrc; 36 | } 37 | 38 | public String getChannelId() { 39 | return channelId; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /web/src/components/FlvPlayer.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 53 | -------------------------------------------------------------------------------- /m-server/src/main/resources/application-pro.yml: -------------------------------------------------------------------------------- 1 | # http 2 | server: 3 | port: 10001 4 | 5 | # 数据库 6 | spring: 7 | datasource: 8 | driver-class-name: com.mysql.cj.jdbc.Driver 9 | url: jdbc:mysql://localhost:3306/blueberry?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&nullCatalogMeansCurrent=true 10 | username: root 11 | password: 123456 12 | 13 | # sip 14 | sip: 15 | name: GB28181-server 16 | host: 192.168.3.81 17 | port: 5060 18 | id: 13020000002000912345 19 | domain: 1302000000 20 | password: admin123 21 | traceLevel: NONE 22 | logMessageContent: false 23 | deviceExpires: 300 24 | 25 | # 媒体服务器 26 | media: 27 | ip: 192.168.3.81 28 | httpPort: 80 29 | rtpPort: 10086 30 | secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc 31 | snapshotSavaPath: ./image/snapshots 32 | 33 | # 视频质量检测 34 | video-quality-detect: 35 | supportedArithmetics: 36 | - NOISE:噪声检测 37 | - STRIPE:条纹检测 38 | - COLOR_CAST:偏色检测 39 | - BRIGHTNESS:亮度检测 40 | - SHARPNESS:清晰度检测 41 | - ANGLE_CHANGE:角度变化检测 42 | 43 | # 视频无人观看检测 44 | video-no-reader-check: 45 | # 无人观看状态下视频存活时间 46 | aliveSeconds: 180 47 | 48 | # 授权码 49 | permission: 50 | code: E6pAkretV+PcRSXdwoLqA28j8/YjT2gUkOqwBR7YBV53KLuKQxyNZQs9tWSoK+7k5reST+shdwA= 51 | 52 | # 日志配置 53 | logging: 54 | config: classpath:logback-pro.xml -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/cors/CorsFilterConfiguration.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.cors; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 7 | import org.springframework.web.filter.CorsFilter; 8 | 9 | /** 10 | * 跨域过滤器 11 | * @author LIUXINDONG 12 | */ 13 | @Configuration 14 | public class CorsFilterConfiguration { 15 | 16 | @Bean 17 | public CorsFilter corsFilter() { 18 | final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 19 | final CorsConfiguration config = new CorsConfiguration(); 20 | // 允许cookies跨域 21 | config.setAllowCredentials(true); 22 | // 允许向该服务器提交请求的URI,*表示全部允许。。这里尽量限制来源域,比如http://xxxx:8080 ,以降低安全风险。。 23 | config.addAllowedOriginPattern("*"); 24 | // 允许访问的头信息,*表示全部 25 | config.addAllowedHeader("*"); 26 | // 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 27 | config.setMaxAge(18000L); 28 | // 允许提交请求的方法,*表示全部允许,也可以单独设置GET、PUT等 29 | config.addAllowedMethod("*"); 30 | source.registerCorsConfiguration("/**", config); 31 | return new CorsFilter(source); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /m-server/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # http 2 | server: 3 | port: 10001 4 | 5 | # 数据库 6 | spring: 7 | datasource: 8 | driver-class-name: com.mysql.cj.jdbc.Driver 9 | url: jdbc:mysql://localhost:3306/blueberry?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&nullCatalogMeansCurrent=true 10 | username: root 11 | password: 123456 12 | 13 | # sip 14 | sip: 15 | name: GB28181-server 16 | host: 192.168.3.65 17 | port: 5060 18 | id: 13020000002000912345 19 | domain: 1302000000 20 | password: admin123 21 | traceLevel: NONE 22 | logMessageContent: false 23 | deviceExpires: 300 24 | 25 | # 媒体服务器 26 | media: 27 | ip: 192.168.3.65 28 | httpPort: 80 29 | rtpPort: 10086 30 | secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc 31 | snapshotSavaPath: ./image/snapshots 32 | 33 | # 视频质量检测 34 | video-quality-detect: 35 | supportedArithmetics: 36 | - COVER:遮挡检测 37 | - NOISE:噪声检测 38 | - STRIPE:条纹检测 39 | - COLOR_CAST:偏色检测 40 | - BRIGHTNESS:亮度检测 41 | - SHARPNESS:清晰度检测 42 | - ANGLE_CHANGE:角度变化检测 43 | 44 | # 视频无人观看检测 45 | video-no-reader-check: 46 | # 无人观看状态下视频存活时间 47 | aliveSeconds: 180 48 | 49 | permission: 50 | check: false 51 | code: E6pAkretV+PcRSXdwoLqA28j8/YjT2gUkOqwBR7YBV53KLuKQxyNZca19OsTPY8wZt/3R1bhyDw= 52 | 53 | # 日志配置 54 | logging: 55 | config: classpath:logback-dev.xml -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/channel/entity/ChannelQueryParamVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.channel.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import io.swagger.annotations.ApiModelProperty; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | *

10 | * 设备通道表 11 | *

12 | * 13 | * @author RabbitNoTeeth 14 | * @since 2021-06-11 15 | */ 16 | @TableName("t_channel") 17 | public class ChannelQueryParamVO implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @ApiModelProperty(value = "通道ID", required = true) 22 | private String id; 23 | 24 | @ApiModelProperty(value = "设备编码", required = true) 25 | private String deviceId; 26 | 27 | @ApiModelProperty(value = "通道名称", required = true) 28 | private String name; 29 | 30 | public String getId() { 31 | return id; 32 | } 33 | 34 | public void setId(String id) { 35 | this.id = id; 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public String getDeviceId() { 47 | return deviceId; 48 | } 49 | 50 | public void setDeviceId(String deviceId) { 51 | this.deviceId = deviceId; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/BlueberryApplication.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server; 2 | 3 | import fun.bookish.blueberry.core.utils.SpringUtils; 4 | import fun.bookish.blueberry.server.permission.PermissionCodeUtils; 5 | import fun.bookish.blueberry.server.permission.PermissionProperties; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.mybatis.spring.annotation.MapperScan; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | @SpringBootApplication(scanBasePackages = "fun.bookish.blueberry") 12 | @MapperScan(basePackages = "fun.bookish.blueberry", annotationClass = Mapper.class) 13 | public class BlueberryApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(BlueberryApplication.class, args); 17 | // 检测序列号是否有效 18 | checkPermissionCode(); 19 | } 20 | 21 | /** 22 | * 检查序列号是否有效 23 | */ 24 | private static void checkPermissionCode() { 25 | PermissionProperties permissionProperties = SpringUtils.getBeanByClass(PermissionProperties.class); 26 | Boolean check = permissionProperties.getCheck(); 27 | if (!check) { 28 | return; 29 | } 30 | PermissionCodeUtils.check(permissionProperties.getCode()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/media/param/SipMediaStopParam.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.media.param; 2 | 3 | import fun.bookish.blueberry.sip.command.executor.param.SipCommandParam; 4 | 5 | /** 6 | * 媒体流点播参数 7 | */ 8 | public class SipMediaStopParam extends SipCommandParam { 9 | 10 | private final String channelId; 11 | 12 | private final String ssrc; 13 | 14 | private final String fromTag; 15 | 16 | private final String toTag; 17 | 18 | private final String callId; 19 | 20 | public SipMediaStopParam(String deviceId, String deviceAddress, String channelId, String protocolType, String ssrc, String fromTag, String toTag, String callId) { 21 | super(deviceId, deviceAddress, protocolType); 22 | this.channelId = channelId; 23 | this.ssrc = ssrc; 24 | this.fromTag = fromTag; 25 | this.toTag = toTag; 26 | this.callId = callId; 27 | } 28 | 29 | public String getSsrc() { 30 | return ssrc; 31 | } 32 | 33 | public String getChannelId() { 34 | return channelId; 35 | } 36 | 37 | public String getFromTag() { 38 | return fromTag; 39 | } 40 | 41 | public String getToTag() { 42 | return toTag; 43 | } 44 | 45 | public String getCallId() { 46 | return callId; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueberry-page", 3 | "version": "0.0.1", 4 | "description": "page of blueberry", 5 | "productName": "blueberry-page", 6 | "author": "刘新冬 <864426487@qq.com>", 7 | "private": true, 8 | "scripts": { 9 | "lint": "eslint --ext .js,.vue ./", 10 | "test": "echo \"No test specified\" && exit 0" 11 | }, 12 | "dependencies": { 13 | "@quasar/extras": "^1.0.0", 14 | "axios": "^0.21.1", 15 | "core-js": "^3.6.5", 16 | "element-ui": "^2.15.2", 17 | "flv.js": "^1.5.0", 18 | "qs": "^6.10.1", 19 | "quasar": "^1.0.0", 20 | "vue-i18n": "^8.0.0" 21 | }, 22 | "devDependencies": { 23 | "@quasar/app": "^2.0.0", 24 | "babel-eslint": "^10.0.1", 25 | "eslint": "^7.21.0", 26 | "eslint-config-prettier": "^8.1.0", 27 | "eslint-plugin-vue": "^7.7.0", 28 | "eslint-webpack-plugin": "^2.4.0" 29 | }, 30 | "browserslist": [ 31 | "ie >= 11", 32 | "last 10 Chrome versions", 33 | "last 10 Firefox versions", 34 | "last 4 Edge versions", 35 | "last 7 Safari versions", 36 | "last 8 Android versions", 37 | "last 8 ChromeAndroid versions", 38 | "last 8 FirefoxAndroid versions", 39 | "last 10 iOS versions", 40 | "last 5 Opera versions" 41 | ], 42 | "engines": { 43 | "node": ">= 10.18.1", 44 | "npm": ">= 6.13.4", 45 | "yarn": ">= 1.21.1" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/SipCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | import fun.bookish.blueberry.sip.exception.SipClientTransactionCreationException; 5 | 6 | import javax.sip.ClientTransaction; 7 | import javax.sip.SipProvider; 8 | import javax.sip.header.ViaHeader; 9 | import javax.sip.message.Request; 10 | 11 | /** 12 | * sip命令执行器接口 13 | */ 14 | public interface SipCommandExecutor { 15 | 16 | /** 17 | * 获取会话事务 18 | * @param protocolType 19 | * @param request 20 | * @return 21 | * @throws SipClientTransactionCreationException 22 | */ 23 | default ClientTransaction getClientTransaction(String protocolType, Request request) throws SipClientTransactionCreationException { 24 | try { 25 | SipServer sipServer = getSipServer(); 26 | SipProvider tcpSipProvider = sipServer.getTcpSipProvider(); 27 | SipProvider udpSipProvider = sipServer.getUdpSipProvider(); 28 | return "TCP".equals(protocolType) ? tcpSipProvider.getNewClientTransaction(request) : udpSipProvider.getNewClientTransaction(request); 29 | } catch (Exception e) { 30 | throw new SipClientTransactionCreationException("(×) Failed to get client transaction", e); 31 | } 32 | } 33 | 34 | SipServer getSipServer(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipDeviceRegisterDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | import fun.bookish.blueberry.sip.event.SipEventTypeEnum; 4 | 5 | /** 6 | * 设备注册回调数据 7 | */ 8 | public class SipDeviceRegisterDesc extends SipDeviceDesc{ 9 | 10 | /** 11 | * 设备注册地址 12 | */ 13 | private String registerAddress; 14 | /** 15 | * 传输协议 16 | * UDP/TCP 17 | */ 18 | private String transport; 19 | /** 20 | * 设备过期时长 21 | */ 22 | private int expires; 23 | 24 | public SipDeviceRegisterDesc(String requestDeviceID, String requestDeviceAddress,String deviceId, String registerServer, SipEventTypeEnum eventType) { 25 | super(requestDeviceID, requestDeviceAddress, deviceId, registerServer, eventType); 26 | } 27 | 28 | public String getTransport() { 29 | return transport; 30 | } 31 | 32 | public void setTransport(String transport) { 33 | this.transport = transport; 34 | } 35 | 36 | public int getExpires() { 37 | return expires; 38 | } 39 | 40 | public void setExpires(int expires) { 41 | this.expires = expires; 42 | } 43 | 44 | public String getRegisterAddress() { 45 | return registerAddress; 46 | } 47 | 48 | public void setRegisterAddress(String registerAddress) { 49 | this.registerAddress = registerAddress; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /m-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | web: 3 | html: ./dist 4 | upload: ./fileUpload 5 | 6 | spring: 7 | application: 8 | name: Blueberry 9 | profiles: 10 | active: dev 11 | servlet: 12 | multipart: 13 | max-request-size: 1000MB 14 | max-file-size: 1000MB 15 | web: 16 | resources: 17 | static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.html},file:${web.upload} 18 | quartz: 19 | job-store-type: jdbc 20 | properties: 21 | org: 22 | quartz: 23 | scheduler: 24 | instanceName: clusteredScheduler 25 | instanceId: AUTO 26 | jobStore: 27 | class: org.quartz.impl.jdbcjobstore.JobStoreTX 28 | driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate 29 | tablePrefix: QRTZ_ 30 | isClustered: false 31 | clusterCheckinInterval: 10000 32 | useProperties: false 33 | misfireThreshold: 1000 34 | threadPool: 35 | class: org.quartz.simpl.SimpleThreadPool 36 | threadCount: 10 37 | threadPriority: 5 38 | threadsInheritContextClassLoaderOfInitializingThread: true 39 | 40 | mybatis: 41 | mapper-locations: classpath*:fun/bookish/blueberry/**/mapper/**/*.xml 42 | configuration: 43 | map-underscore-to-camel-case: true 44 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/manual/controller/VideoQualityDetectManualController.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.manual.controller; 2 | 3 | import fun.bookish.blueberry.core.annotation.EnableResponseBodyJsonWrap; 4 | import fun.bookish.blueberry.server.videoqualitydetect.manual.service.IVideoQualityDetectManualService; 5 | import fun.bookish.blueberry.server.videoqualitydetect.manual.entity.VideoQualityDetectManualVO; 6 | import io.swagger.annotations.Api; 7 | import io.swagger.annotations.ApiOperation; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.*; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | 13 | /** 14 | *

15 | * 视频质量检测记录表 前端控制器 16 | *

17 | * 18 | * @author RabbitNoTeeth 19 | * @since 2021-06-11 20 | */ 21 | @Api(tags = "手动图像检测管理") 22 | @EnableResponseBodyJsonWrap 23 | @RestController 24 | @RequestMapping("/api/v1/video-quality-detect/manual") 25 | public class VideoQualityDetectManualController { 26 | 27 | @Autowired 28 | private IVideoQualityDetectManualService videoQualityDetectManualService; 29 | 30 | @ApiOperation("上传图片") 31 | @PostMapping("/upload") 32 | public VideoQualityDetectManualVO upload(@RequestParam("file") MultipartFile file) throws Exception { 33 | return videoQualityDetectManualService.upload(file); 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/swagger2/Swagger2Configuration.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.swagger2; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.spi.DocumentationType; 11 | import springfox.documentation.spring.web.plugins.Docket; 12 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 13 | 14 | @Configuration 15 | @EnableSwagger2 16 | public class Swagger2Configuration { 17 | 18 | @Value("${spring.application.name}") 19 | private String applicationName; 20 | 21 | @Bean 22 | public Docket createRestApi() { 23 | return new Docket(DocumentationType.SWAGGER_2) 24 | .apiInfo(apiInfo()) 25 | .select() 26 | .apis(RequestHandlerSelectors.basePackage("fun.bookish.blueberry")) 27 | .paths(PathSelectors.any()) 28 | .build(); 29 | } 30 | 31 | private ApiInfo apiInfo() { 32 | return new ApiInfoBuilder() 33 | .title(applicationName + "接口文档") 34 | .build(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/dev/DevController.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.dev; 2 | 3 | import fun.bookish.blueberry.server.dev.service.DevService; 4 | import fun.bookish.blueberry.sip.command.executor.query.param.SipQueryCatalogParam; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | 12 | 13 | @RestController 14 | @RequestMapping("/api/v1/dev") 15 | public class DevController { 16 | 17 | @Autowired 18 | private DevService devService; 19 | 20 | /** 21 | * 发送sip命令,查新设备列表 22 | * @param param 23 | * @return 24 | * @throws Exception 25 | */ 26 | @PostMapping("/sip/catalog") 27 | public Object sipCatalog(SipQueryCatalogParam param) throws Exception { 28 | return devService.sipCatalog(param); 29 | } 30 | 31 | /** 32 | * 触发设备通道删除钩子 33 | * @param deviceId 34 | * @param channelId 35 | * @return 36 | */ 37 | @PostMapping("/stream/qualityDetect") 38 | public Object hookOnStreamQualityDetect(@NotBlank(message = "设备ID不能为空") String deviceId, @NotBlank(message = "通道ID不能为空") String channelId) { 39 | return devService.streamQualityDetect(deviceId, channelId); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/manager/impl/SipCommandExecutorManagerImpl.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.manager.impl; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | import fun.bookish.blueberry.sip.command.executor.media.SipMediaCommandExecutor; 5 | import fun.bookish.blueberry.sip.command.executor.query.SipQueryCommandExecutor; 6 | import fun.bookish.blueberry.sip.command.manager.SipCommandExecutorManager; 7 | 8 | /** 9 | * sip命令执行器管理器 10 | */ 11 | public class SipCommandExecutorManagerImpl implements SipCommandExecutorManager { 12 | 13 | private final SipServer sipServer; 14 | private final SipQueryCommandExecutor sipQueryCommandExecutor; 15 | private final SipMediaCommandExecutor sipMediaCommandExecutor; 16 | 17 | public SipCommandExecutorManagerImpl(SipServer sipServer) { 18 | this.sipServer = sipServer; 19 | this.sipQueryCommandExecutor = SipQueryCommandExecutor.create(sipServer); 20 | this.sipMediaCommandExecutor = SipMediaCommandExecutor.create(sipServer); 21 | } 22 | 23 | @Override 24 | public SipServer getSipServer() { 25 | return this.sipServer; 26 | } 27 | 28 | @Override 29 | public SipQueryCommandExecutor getSipQueryCommandExecutor() { 30 | return this.sipQueryCommandExecutor; 31 | } 32 | 33 | @Override 34 | public SipMediaCommandExecutor getSipMediaCommandExecutor() { 35 | return this.sipMediaCommandExecutor; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/channel/service/IChannelService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.channel.service; 2 | 3 | import fun.bookish.blueberry.core.page.PageResult; 4 | import fun.bookish.blueberry.server.channel.entity.ChannelPO; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import fun.bookish.blueberry.server.channel.entity.ChannelQueryParamVO; 7 | import fun.bookish.blueberry.server.channel.entity.ChannelStatusSync; 8 | import fun.bookish.blueberry.server.channel.entity.ChannelVO; 9 | import fun.bookish.blueberry.server.device.entity.DeviceVO; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | *

15 | * 设备通道表 服务类 16 | *

17 | * 18 | * @author RabbitNoTeeth 19 | * @since 2021-06-11 20 | */ 21 | public interface IChannelService extends IService { 22 | 23 | String add(ChannelVO channelVO); 24 | 25 | String update(ChannelVO channelVO); 26 | 27 | String deleteByIdAndDeviceId(String id, String deviceId); 28 | 29 | List queryList(ChannelQueryParamVO params); 30 | 31 | PageResult queryPage(Integer page, Integer pageSize, ChannelQueryParamVO params); 32 | 33 | ChannelPO queryByIdAndDeviceId(String id, String deviceId); 34 | 35 | String deleteByDeviceId(String deviceId); 36 | 37 | String addOrUpdate(ChannelPO channelPO); 38 | 39 | void addOrUpdate(List channels) throws Exception; 40 | 41 | List queryChannelStatusSyncList(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/command/executor/query/SipQueryCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.command.executor.query; 2 | 3 | 4 | import fun.bookish.blueberry.sip.SipServer; 5 | import fun.bookish.blueberry.sip.command.executor.query.param.SipQueryCatalogParam; 6 | import fun.bookish.blueberry.sip.command.executor.query.param.SipQueryDeviceInfoParam; 7 | import fun.bookish.blueberry.sip.command.executor.query.param.SipQueryDeviceStatusParam; 8 | import fun.bookish.blueberry.sip.command.executor.SipCommandExecutor; 9 | import fun.bookish.blueberry.sip.command.executor.query.impl.SipQueryCommandExecutorImpl; 10 | import fun.bookish.blueberry.sip.exception.SipCommandExecuteException; 11 | 12 | /** 13 | * sip查询命令执行器接口 14 | */ 15 | public interface SipQueryCommandExecutor extends SipCommandExecutor { 16 | 17 | static SipQueryCommandExecutor create(SipServer sipServer){ 18 | return new SipQueryCommandExecutorImpl(sipServer); 19 | } 20 | 21 | /** 22 | * 查询设备信息 23 | * @param sipQueryDeviceInfoParam 24 | */ 25 | void queryDeviceInfo(SipQueryDeviceInfoParam sipQueryDeviceInfoParam) throws SipCommandExecuteException; 26 | 27 | /** 28 | * 查询设备状态 29 | * @param sipQueryDeviceStatusParam 30 | */ 31 | void queryDeviceStatus(SipQueryDeviceStatusParam sipQueryDeviceStatusParam) throws SipCommandExecuteException; 32 | 33 | /** 34 | * 查询设备目录 35 | * @param sipQueryCatalogParam 36 | */ 37 | void queryCatalog(SipQueryCatalogParam sipQueryCatalogParam) throws SipCommandExecuteException; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /m-quartz/src/main/java/fun/bookish/blueberry/quartz/listener/QuartzAutoStartListener.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.quartz.listener; 2 | 3 | 4 | import org.quartz.Scheduler; 5 | import org.quartz.SchedulerException; 6 | import org.quartz.impl.matchers.EverythingMatcher; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.ApplicationListener; 9 | import org.springframework.context.event.ContextRefreshedEvent; 10 | import org.springframework.stereotype.Component; 11 | 12 | /** 13 | * quartz自动配置监听器 14 | * 程序启动完成后,自动加载数据库中的定时任务并启动 15 | * @author Don9 16 | */ 17 | @Component 18 | public class QuartzAutoStartListener implements ApplicationListener { 19 | 20 | @Autowired 21 | private Scheduler scheduler; 22 | 23 | @Autowired 24 | private GeneralTriggerListener generalTriggerListener; 25 | 26 | @Autowired 27 | private QuartzSchedulerListener quartzSchedulerListener; 28 | 29 | @Override 30 | public void onApplicationEvent(ContextRefreshedEvent event) { 31 | try { 32 | if(scheduler.isStarted()){ 33 | scheduler.getListenerManager().addSchedulerListener(quartzSchedulerListener); 34 | scheduler.getListenerManager().addTriggerListener(generalTriggerListener, EverythingMatcher.allTriggers()); 35 | scheduler.start(); 36 | } 37 | } catch (SchedulerException e) { 38 | throw new IllegalStateException("定时任务调度器启动失败", e); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/manual/entity/VideoQualityDetectManualVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.manual.entity; 2 | 3 | public class VideoQualityDetectManualVO { 4 | 5 | private Boolean hasError; 6 | private String error; 7 | private Boolean hasQualityError; 8 | private String qualityError; 9 | private String detail; 10 | private String snapshot; 11 | 12 | public Boolean getHasError() { 13 | return hasError; 14 | } 15 | 16 | public void setHasError(Boolean hasError) { 17 | this.hasError = hasError; 18 | } 19 | 20 | public Boolean getHasQualityError() { 21 | return hasQualityError; 22 | } 23 | 24 | public void setHasQualityError(Boolean hasQualityError) { 25 | this.hasQualityError = hasQualityError; 26 | } 27 | 28 | public String getQualityError() { 29 | return qualityError; 30 | } 31 | 32 | public void setQualityError(String qualityError) { 33 | this.qualityError = qualityError; 34 | } 35 | 36 | public String getError() { 37 | return error; 38 | } 39 | 40 | public void setError(String error) { 41 | this.error = error; 42 | } 43 | 44 | public String getDetail() { 45 | return detail; 46 | } 47 | 48 | public void setDetail(String detail) { 49 | this.detail = detail; 50 | } 51 | 52 | public String getSnapshot() { 53 | return snapshot; 54 | } 55 | 56 | public void setSnapshot(String snapshot) { 57 | this.snapshot = snapshot; 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/device/entity/DeviceParamVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.device.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import io.swagger.annotations.ApiModelProperty; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | *

10 | * 设备表 11 | *

12 | * 13 | * @author RabbitNoTeeth 14 | * @since 2021-06-11 15 | */ 16 | @TableName("t_device") 17 | public class DeviceParamVO implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @ApiModelProperty(value = "设备编码", required = true) 22 | private String id; 23 | 24 | @ApiModelProperty(value = "设备名称", required = true) 25 | private String name; 26 | 27 | @ApiModelProperty(value = "设备类型", required = true, example = "GB, RTSP") 28 | private String type; 29 | 30 | @ApiModelProperty(value = "是否在线(0:否,1:是)", required = true, example = "0") 31 | private Integer online; 32 | 33 | public String getId() { 34 | return id; 35 | } 36 | 37 | public void setId(String id) { 38 | this.id = id; 39 | } 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | public String getType() { 50 | return type; 51 | } 52 | 53 | public void setType(String type) { 54 | this.type = type; 55 | } 56 | 57 | public Integer getOnline() { 58 | return online; 59 | } 60 | 61 | public void setOnline(Integer online) { 62 | this.online = online; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmetic/entity/VideoQualityDetectArithmeticQueryParamVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmetic.entity; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | 6 | import javax.validation.constraints.NotBlank; 7 | import javax.validation.constraints.NotNull; 8 | import java.io.Serializable; 9 | 10 | /** 11 | *

12 | * 视频质量检测算法 13 | *

14 | * 15 | * @author RabbitNoTeeth 16 | * @since 2021-06-10 17 | */ 18 | @ApiModel(value = "VideoQualityDetectArithmetic实体对象", description = "视频质量检测算法实体") 19 | public class VideoQualityDetectArithmeticQueryParamVO implements Serializable { 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | @ApiModelProperty(value = "名称", required = true) 24 | private String name; 25 | 26 | @ApiModelProperty(value = "是否启用(0:否,1:是)", required = true, example = "1") 27 | private Integer enable; 28 | 29 | @ApiModelProperty(value = "是否应用到所有设备(0:否,1:是)", required = true, example = "1") 30 | private Integer applyAll; 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public Integer getEnable() { 41 | return enable; 42 | } 43 | 44 | public void setEnable(Integer enable) { 45 | this.enable = enable; 46 | } 47 | 48 | public Integer getApplyAll() { 49 | return applyAll; 50 | } 51 | 52 | public void setApplyAll(Integer applyAll) { 53 | this.applyAll = applyAll; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmetic/entity/VideoQualityDetectArithmeticApplyDeviceVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmetic.entity; 2 | 3 | import java.util.List; 4 | 5 | public class VideoQualityDetectArithmeticApplyDeviceVO { 6 | 7 | private List deviceTreeNodes; 8 | private List appliedDevices; 9 | 10 | public List getDeviceTreeNodes() { 11 | return deviceTreeNodes; 12 | } 13 | 14 | public void setDeviceTreeNodes(List deviceTreeNodes) { 15 | this.deviceTreeNodes = deviceTreeNodes; 16 | } 17 | 18 | public List getAppliedDevices() { 19 | return appliedDevices; 20 | } 21 | 22 | public void setAppliedDevices(List appliedDevices) { 23 | this.appliedDevices = appliedDevices; 24 | } 25 | 26 | public static class DeviceTreeNode { 27 | private String code; 28 | private String name; 29 | private List children; 30 | 31 | public String getCode() { 32 | return code; 33 | } 34 | 35 | public void setCode(String code) { 36 | this.code = code; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public List getChildren() { 48 | return children; 49 | } 50 | 51 | public void setChildren(List children) { 52 | this.children = children; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/record/service/IVideoQualityDetectRecordService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.record.service; 2 | 3 | import fun.bookish.blueberry.core.page.PageResult; 4 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordPO; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordQueryParamVO; 7 | import fun.bookish.blueberry.server.videoqualitydetect.record.entity.VideoQualityDetectRecordVO; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 视频质量检测记录表 服务类 14 | *

15 | * 16 | * @author RabbitNoTeeth 17 | * @since 2021-06-11 18 | */ 19 | public interface IVideoQualityDetectRecordService extends IService { 20 | 21 | /** 22 | * 查询列表 23 | * 24 | * @return 25 | * @param params 26 | */ 27 | List queryList(VideoQualityDetectRecordQueryParamVO params); 28 | 29 | /** 30 | * 查询视频快照 31 | * 32 | * @param id 33 | * @return 34 | */ 35 | byte[] querySnap(Integer id) throws Exception; 36 | 37 | /** 38 | * 查询视频快照 39 | * 40 | * @param path 41 | * @return 42 | */ 43 | byte[] querySnapByPath(String path) throws Exception; 44 | 45 | /** 46 | * 分页查询列表 47 | * 48 | * @param page 49 | * @param pageSize 50 | * @param params 51 | * @return 52 | */ 53 | PageResult queryPage(Integer page, Integer pageSize, VideoQualityDetectRecordQueryParamVO params); 54 | } 55 | -------------------------------------------------------------------------------- /m-opencv/src/main/java/fun/bookish/blueberry/opencv/utils/ImageUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.opencv.utils; 2 | 3 | 4 | import org.bytedeco.opencv.global.opencv_highgui; 5 | import org.bytedeco.opencv.global.opencv_imgcodecs; 6 | import org.bytedeco.opencv.global.opencv_imgproc; 7 | import org.bytedeco.opencv.opencv_core.Mat; 8 | import org.bytedeco.opencv.opencv_core.Point; 9 | import org.bytedeco.opencv.opencv_core.Scalar; 10 | 11 | import java.io.File; 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | public class ImageUtils { 17 | 18 | public static void show(String imagePath, String text) { 19 | Mat image = opencv_imgcodecs.imread(imagePath); 20 | opencv_imgproc.putText(image, text, new Point(5, 50), 0, 0.5, new Scalar(0, 255)); 21 | opencv_highgui.imshow(imagePath, image); 22 | opencv_highgui.waitKey(0); 23 | opencv_highgui.destroyWindow(imagePath); 24 | } 25 | 26 | public static List getImageList(String path) { 27 | List res = new ArrayList<>(); 28 | File file = new File(path); 29 | if (file.exists() && file.isDirectory()) { 30 | File[] subFiles = file.listFiles(); 31 | if (subFiles != null) 32 | Arrays.stream(subFiles).forEach(subFile -> { 33 | String name = subFile.getName(); 34 | if (name.toLowerCase().endsWith(".png") || name.toLowerCase().endsWith(".jpg") || name.toLowerCase().endsWith(".jpeg")) { 35 | res.add(subFile.getAbsolutePath()); 36 | } 37 | }); 38 | } 39 | return res; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/event/listener/SipEventListener.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.event.listener; 2 | 3 | import fun.bookish.blueberry.sip.event.SipEventContext; 4 | import fun.bookish.blueberry.sip.entity.*; 5 | 6 | /** 7 | * sip事件回调处理器接口,可根据需要重写感兴趣的事件处理逻辑 8 | */ 9 | public interface SipEventListener { 10 | 11 | /** 12 | * 设备注册 13 | * 14 | * @param sipEventContext 15 | */ 16 | default void deviceRegister(SipEventContext sipEventContext) { 17 | } 18 | 19 | 20 | /** 21 | * 设备注销 22 | * 23 | * @param sipEventContext 24 | */ 25 | default void deviceLogout(SipEventContext sipEventContext) { 26 | } 27 | 28 | 29 | /** 30 | * 设备信息响应 31 | * 32 | * @param sipEventContext 33 | */ 34 | default void deviceInfoResponse(SipEventContext sipEventContext) { 35 | } 36 | 37 | /** 38 | * 设备状态响应 39 | * 40 | * @param sipEventContext 41 | */ 42 | default void deviceStatusResponse(SipEventContext sipEventContext) { 43 | } 44 | 45 | /** 46 | * 设备目录响应 47 | * 48 | * @param sipEventContext 49 | */ 50 | default void catalogResponse(SipEventContext sipEventContext) { 51 | } 52 | 53 | /** 54 | * 设备状态信息报送通知 55 | * 56 | * @param sipEventContext 57 | */ 58 | default void keepaliveNotify(SipEventContext sipEventContext) { 59 | } 60 | 61 | /** 62 | * 媒体流点播成功 63 | * 64 | * @param sipEventContext 65 | */ 66 | default void mediaInviteSuccess(SipEventContext sipEventContext) { 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/advice/ControllerResponseBodyAdvice.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.advice; 2 | 3 | import fun.bookish.blueberry.core.annotation.DisableResponseBodyJsonWrap; 4 | import fun.bookish.blueberry.core.annotation.EnableResponseBodyJsonWrap; 5 | import fun.bookish.blueberry.core.json.JsonResult; 6 | import fun.bookish.blueberry.core.utils.JsonUtils; 7 | import org.springframework.core.MethodParameter; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.http.converter.HttpMessageConverter; 10 | import org.springframework.http.server.ServerHttpRequest; 11 | import org.springframework.http.server.ServerHttpResponse; 12 | import org.springframework.web.bind.annotation.ControllerAdvice; 13 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; 14 | 15 | @ControllerAdvice 16 | public class ControllerResponseBodyAdvice implements ResponseBodyAdvice { 17 | @Override 18 | public boolean supports(MethodParameter methodParameter, Class> aClass) { 19 | if (methodParameter.getMethodAnnotation(DisableResponseBodyJsonWrap.class) != null) { 20 | return false; 21 | } 22 | return methodParameter.getMethodAnnotation(EnableResponseBodyJsonWrap.class) != null || methodParameter.getContainingClass().getAnnotation(EnableResponseBodyJsonWrap.class) != null; 23 | } 24 | 25 | @Override 26 | public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { 27 | return JsonResult.success("请求成功", o); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/device/service/IDeviceService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.device.service; 2 | 3 | import fun.bookish.blueberry.core.page.PageResult; 4 | import fun.bookish.blueberry.server.device.entity.DevicePO; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import fun.bookish.blueberry.server.device.entity.DeviceParamVO; 7 | import fun.bookish.blueberry.server.device.entity.DeviceVO; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 设备表 服务类 14 | *

15 | * 16 | * @author RabbitNoTeeth 17 | * @since 2021-06-11 18 | */ 19 | public interface IDeviceService extends IService { 20 | 21 | /** 22 | * 添加 23 | * 24 | * @param deviceVO 25 | * @return 26 | */ 27 | String add(DeviceVO deviceVO); 28 | 29 | /** 30 | * 更新 31 | * 32 | * @param deviceVO 33 | * @return 34 | */ 35 | String update(DeviceVO deviceVO); 36 | 37 | /** 38 | * 删除 39 | * 40 | * @param id 41 | * @return 42 | */ 43 | String deleteById(String id); 44 | 45 | /** 46 | * 查询 47 | * 48 | * @return 49 | */ 50 | DevicePO queryById(String id); 51 | 52 | /** 53 | * 查询列表 54 | * 55 | * @return 56 | * @param params 57 | */ 58 | List queryList(DeviceParamVO params); 59 | 60 | /** 61 | * 新增或更新 62 | * 63 | * @return 64 | */ 65 | String addOrUpdate(DevicePO devicePO); 66 | 67 | /** 68 | * 分页查询 69 | * @param page 70 | * @param pageSize 71 | * @param params 72 | * @return 73 | */ 74 | PageResult queryPage(Integer page, Integer pageSize, DeviceParamVO params); 75 | } 76 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/utils/MessageDigestUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.utils; 2 | 3 | import fun.bookish.blueberry.sip.digest.MessageDigestTypeEnum; 4 | 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * 数字摘要工具类 12 | */ 13 | public class MessageDigestUtils { 14 | 15 | private static final Map MESSAGEDIGEST_MAP = new HashMap<>(); 16 | 17 | static { 18 | try { 19 | for (MessageDigestTypeEnum typeEnum : MessageDigestTypeEnum.values()) { 20 | MESSAGEDIGEST_MAP.put(typeEnum, MessageDigest.getInstance(typeEnum.getDesc())); 21 | } 22 | } catch (Exception e) { 23 | throw new RuntimeException("数字摘要工具类初始化失败", e); 24 | } 25 | } 26 | 27 | /** to hex converter */ 28 | private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6', 29 | '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 30 | 31 | 32 | public static MessageDigest getMessageDigest(MessageDigestTypeEnum typeEnum) { 33 | return MESSAGEDIGEST_MAP.get(typeEnum); 34 | } 35 | 36 | public static String toHexString(byte b[]) { 37 | int pos = 0; 38 | char[] c = new char[b.length * 2]; 39 | for (int i = 0; i < b.length; i++) { 40 | c[pos++] = toHex[(b[i] >> 4) & 0x0F]; 41 | c[pos++] = toHex[b[i] & 0x0f]; 42 | } 43 | return new String(c); 44 | } 45 | 46 | 47 | public static byte[] digest(MessageDigestTypeEnum digestTypeEnum, byte[] bytes) { 48 | return getMessageDigest(digestTypeEnum).digest(bytes); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/dev/service/DevService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.dev.service; 2 | 3 | import fun.bookish.blueberry.core.utils.DateUtils; 4 | import fun.bookish.blueberry.server.videoqualitydetect.detect.entity.VideoStreamQualityDetectResult; 5 | import fun.bookish.blueberry.server.videoqualitydetect.detect.VideoStreamDetectService; 6 | import fun.bookish.blueberry.sip.SipServer; 7 | import fun.bookish.blueberry.sip.command.executor.query.SipQueryCommandExecutor; 8 | import fun.bookish.blueberry.sip.command.executor.query.param.SipQueryCatalogParam; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | @Service 13 | public class DevService { 14 | 15 | @Autowired 16 | private SipServer sipServer; 17 | @Autowired 18 | private VideoStreamDetectService videoStreamDetectService; 19 | 20 | /** 21 | * 发送sip命令,查询设备列表 22 | * 23 | * @param param 24 | * @return 25 | * @throws Exception 26 | */ 27 | public Object sipCatalog(SipQueryCatalogParam param) throws Exception { 28 | SipQueryCommandExecutor sipQueryCommandExecutor = sipServer.getSipCommandExecutorManager().getSipQueryCommandExecutor(); 29 | sipQueryCommandExecutor.queryCatalog(param); 30 | return "success"; 31 | } 32 | 33 | /** 34 | * 触发设备图像质量检测钩子 35 | * 36 | * @param deviceId 37 | * @param channelId 38 | * @return 39 | */ 40 | public Object streamQualityDetect(String deviceId, String channelId) { 41 | VideoStreamQualityDetectResult data = videoStreamDetectService.detectStreamQuality(deviceId, channelId, DateUtils.getNowDateStr("yyyyMMddHHmmss")); 42 | return data; 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/zlmedia/conf/MediaProperties.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.zlmedia.conf; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties(prefix = "media") 8 | public class MediaProperties { 9 | 10 | private String ip; 11 | private Integer httpPort; 12 | private Integer rtpPort; 13 | private String secret; 14 | private Integer noReaderCheckInterval = 180; 15 | private String snapshotSavaPath = "./snapshots"; 16 | 17 | public String getIp() { 18 | return ip; 19 | } 20 | 21 | public void setIp(String ip) { 22 | this.ip = ip; 23 | } 24 | 25 | public Integer getRtpPort() { 26 | return rtpPort; 27 | } 28 | 29 | public void setRtpPort(Integer rtpPort) { 30 | this.rtpPort = rtpPort; 31 | } 32 | 33 | public Integer getHttpPort() { 34 | return httpPort; 35 | } 36 | 37 | public void setHttpPort(Integer httpPort) { 38 | this.httpPort = httpPort; 39 | } 40 | 41 | public String getSecret() { 42 | return secret; 43 | } 44 | 45 | public void setSecret(String secret) { 46 | this.secret = secret; 47 | } 48 | 49 | public Integer getNoReaderCheckInterval() { 50 | return noReaderCheckInterval; 51 | } 52 | 53 | public void setNoReaderCheckInterval(Integer noReaderCheckInterval) { 54 | this.noReaderCheckInterval = noReaderCheckInterval; 55 | } 56 | 57 | public String getSnapshotSavaPath() { 58 | return snapshotSavaPath; 59 | } 60 | 61 | public void setSnapshotSavaPath(String snapshotSavaPath) { 62 | this.snapshotSavaPath = snapshotSavaPath; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipMediaInviteDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | 4 | import fun.bookish.blueberry.sip.event.SipEventTypeEnum; 5 | 6 | /** 7 | * 设备媒体点播描述 8 | */ 9 | public class SipMediaInviteDesc extends SipDeviceDesc{ 10 | 11 | private String channelId; 12 | private String ssrc; 13 | private String fromTag; 14 | private String toTag; 15 | private String transport; 16 | private String callId; 17 | 18 | public SipMediaInviteDesc(String requestDeviceID, String requestDeviceAddress, String deviceId, String registerServer, SipEventTypeEnum eventType) { 19 | super(requestDeviceID, requestDeviceAddress, deviceId, registerServer, eventType); 20 | } 21 | 22 | public String getChannelId() { 23 | return channelId; 24 | } 25 | 26 | public void setChannelId(String channelId) { 27 | this.channelId = channelId; 28 | } 29 | 30 | public String getSsrc() { 31 | return ssrc; 32 | } 33 | 34 | public void setSsrc(String ssrc) { 35 | this.ssrc = ssrc; 36 | } 37 | 38 | public String getFromTag() { 39 | return fromTag; 40 | } 41 | 42 | public void setFromTag(String fromTag) { 43 | this.fromTag = fromTag; 44 | } 45 | 46 | public String getToTag() { 47 | return toTag; 48 | } 49 | 50 | public void setToTag(String toTag) { 51 | this.toTag = toTag; 52 | } 53 | 54 | public String getTransport() { 55 | return transport; 56 | } 57 | 58 | public void setTransport(String transport) { 59 | this.transport = transport; 60 | } 61 | 62 | public String getCallId() { 63 | return this.callId; 64 | } 65 | 66 | public void setCallId(String callId) { 67 | this.callId = callId; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipDeviceDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | import fun.bookish.blueberry.sip.event.SipEventTypeEnum; 4 | import fun.bookish.blueberry.sip.utils.DateUtils; 5 | 6 | /** 7 | * 设备描述基类 8 | */ 9 | public class SipDeviceDesc { 10 | 11 | /** 12 | * 请求来源设备id 13 | */ 14 | protected final String fromDeviceId; 15 | /** 16 | * 请求来源设备地址 17 | */ 18 | protected final String fromDeviceAddress; 19 | /** 20 | * 设备id(必选) 21 | */ 22 | protected final String deviceID; 23 | /** 24 | * 更新日期 25 | */ 26 | protected final String updateTime; 27 | /** 28 | * 注册服务器 29 | */ 30 | protected final String sipServerHost; 31 | /** 32 | * sip事件 33 | */ 34 | protected final SipEventTypeEnum eventType; 35 | 36 | public SipDeviceDesc(String fromDeviceId, String fromDeviceAddress, String deviceID, String sipServerHost, SipEventTypeEnum eventType) { 37 | this.fromDeviceId = fromDeviceId; 38 | this.fromDeviceAddress = fromDeviceAddress; 39 | this.deviceID = deviceID; 40 | this.eventType = eventType; 41 | this.updateTime = DateUtils.getNowDateTimeStr(); 42 | this.sipServerHost = sipServerHost; 43 | } 44 | 45 | public String getDeviceID() { 46 | return deviceID; 47 | } 48 | 49 | public String getUpdateTime() { 50 | return updateTime; 51 | } 52 | 53 | public String getSipServerHost() { 54 | return sipServerHost; 55 | } 56 | 57 | public SipEventTypeEnum getEventType() { 58 | return eventType; 59 | } 60 | 61 | public String getFromDeviceId() { 62 | return fromDeviceId; 63 | } 64 | 65 | public String getFromDeviceAddress() { 66 | return fromDeviceAddress; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/record/entity/VideoQualityDetectRecordQueryParamVO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.record.entity; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | *

10 | * 视频质量检测记录表 11 | *

12 | * 13 | * @author RabbitNoTeeth 14 | * @since 2021-06-11 15 | */ 16 | @ApiModel(value = "VideoQualityDetectRecord查询参数对象", description = "视频质量检测记录查询参数实体") 17 | public class VideoQualityDetectRecordQueryParamVO implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @ApiModelProperty(value = "算法名称") 22 | private String arithmeticName; 23 | 24 | @ApiModelProperty(value = "设备ID") 25 | private String deviceId; 26 | 27 | @ApiModelProperty(value = "通道ID") 28 | private String channelId; 29 | 30 | @ApiModelProperty(value = "是否异常", example = "0") 31 | private Integer hasQualityError; 32 | 33 | public String getArithmeticName() { 34 | return arithmeticName; 35 | } 36 | 37 | public void setArithmeticName(String arithmeticName) { 38 | this.arithmeticName = arithmeticName; 39 | } 40 | 41 | public String getDeviceId() { 42 | return deviceId; 43 | } 44 | 45 | public void setDeviceId(String deviceId) { 46 | this.deviceId = deviceId; 47 | } 48 | 49 | public String getChannelId() { 50 | return channelId; 51 | } 52 | 53 | public void setChannelId(String channelId) { 54 | this.channelId = channelId; 55 | } 56 | 57 | public Integer getHasQualityError() { 58 | return hasQualityError; 59 | } 60 | 61 | public void setHasQualityError(Integer hasQualityError) { 62 | this.hasQualityError = hasQualityError; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/handler/impl/SipAckRequestHandler.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.handler.impl; 2 | 3 | import fun.bookish.blueberry.sip.request.model.SipRequestWrapper; 4 | import fun.bookish.blueberry.sip.request.handler.AbstractSipRequestHandler; 5 | import fun.bookish.blueberry.sip.utils.SipRequestUtils; 6 | import gov.nist.javax.sip.header.CSeq; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import javax.sip.Dialog; 11 | import javax.sip.RequestEvent; 12 | import javax.sip.message.Request; 13 | 14 | /** 15 | * ACK请求处理器 16 | */ 17 | public class SipAckRequestHandler extends AbstractSipRequestHandler { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(SipAckRequestHandler.class); 20 | 21 | @Override 22 | public void beforeHandle(SipRequestWrapper requestWrapper) { 23 | String requestDesc = SipRequestUtils.getSimpleDesc(requestWrapper.getRequestEvent().getRequest()); 24 | if (LOGGER.isDebugEnabled()) { 25 | LOGGER.debug(" >>> Receive an ACK request. From:{}", requestDesc); 26 | } 27 | } 28 | 29 | @Override 30 | public void doHandle(SipRequestWrapper requestWrapper) { 31 | RequestEvent requestEvent = requestWrapper.getRequestEvent(); 32 | Request request = requestEvent.getRequest(); 33 | String requestDesc = SipRequestUtils.getSimpleDesc(request); 34 | Dialog dialog = requestEvent.getDialog(); 35 | try { 36 | CSeq csReq = (CSeq) request.getHeader(CSeq.NAME); 37 | Request ackRequest = dialog.createAck(csReq.getSeqNumber()); 38 | dialog.sendAck(ackRequest); 39 | LOGGER.info("<<< Response the ACK Request. To:{}", requestDesc); 40 | } catch (Exception e) { 41 | LOGGER.error("(×) Failed to handle the ACK request. From:{}", requestDesc, e); 42 | } 43 | } 44 | 45 | @Override 46 | public void afterHandle(SipRequestWrapper requestWrapper) { 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/utils/SipHeaderUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.utils; 2 | 3 | import fun.bookish.blueberry.sip.digest.MessageDigestTypeEnum; 4 | 5 | import javax.sip.SipFactory; 6 | import javax.sip.header.WWWAuthenticateHeader; 7 | import java.util.Date; 8 | import java.util.Random; 9 | 10 | /** 11 | * sip header工具类 12 | */ 13 | public class SipHeaderUtils { 14 | 15 | private SipHeaderUtils() { 16 | } 17 | 18 | public static WWWAuthenticateHeader createWWWAuthenticateHeader(SipFactory sipFactory, MessageDigestTypeEnum digestTypeEnum, String realm) { 19 | try { 20 | WWWAuthenticateHeader header = sipFactory.createHeaderFactory().createWWWAuthenticateHeader("Digest"); 21 | header.setParameter("realm", realm); 22 | header.setParameter("nonce", generateNonce(digestTypeEnum)); 23 | header.setParameter("opaque", ""); 24 | header.setParameter("stale", "FALSE"); 25 | header.setParameter("algorithm", digestTypeEnum.getDesc()); 26 | return header; 27 | } catch (Exception e) { 28 | throw new RuntimeException("(×) Failed to create a WWWAuthenticateHeader", e); 29 | } 30 | } 31 | 32 | /** 33 | * 生成nonce 34 | * 35 | * @param digestTypeEnum 36 | * @return 37 | */ 38 | private static String generateNonce(MessageDigestTypeEnum digestTypeEnum) { 39 | // Get the time of day and run MD5 over it. 40 | Date date = new Date(); 41 | long time = date.getTime(); 42 | Random rand = new Random(); 43 | long pad = rand.nextLong(); 44 | String nonceString = (new Long(time)).toString() 45 | + (new Long(pad)).toString(); 46 | byte mdbytes[] = MessageDigestUtils.digest(digestTypeEnum, nonceString.getBytes()); 47 | // Convert the mdbytes array into a hex string. 48 | return MessageDigestUtils.toHexString(mdbytes); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/utils/HexUtils.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.utils; 2 | 3 | 4 | public class HexUtils { 5 | 6 | private HexUtils() {} 7 | 8 | /** 9 | * int数字转十六进制 10 | * @param n 11 | * @return 12 | */ 13 | public static String int2Hex(int n) { 14 | String res = Integer.toHexString(n); 15 | if (res.length() % 2 == 1) { 16 | res = "0" + res; 17 | } 18 | return res.toUpperCase(); 19 | } 20 | 21 | /** 22 | * 十六进制转int数字 23 | * @param hex 24 | * @return 25 | */ 26 | public static int hex2Int(String hex) { 27 | return Integer.parseInt(hex, 16); 28 | } 29 | 30 | /** 31 | * long数字转十六进制 32 | * @param n 33 | * @return 34 | */ 35 | public static String long2Hex(long n) { 36 | String res = Long.toHexString(n); 37 | if (res.length() % 2 == 1) { 38 | res = "0" + res; 39 | } 40 | return res.toUpperCase(); 41 | } 42 | 43 | /** 44 | * 十六进制转long数字 45 | * @param hex 46 | * @return 47 | */ 48 | public static long hex2Long(String hex) { 49 | return Long.parseLong(hex, 16); 50 | } 51 | 52 | /** 53 | * double数字转十六进制 54 | * @param n 55 | * @return 56 | */ 57 | public static String double2Hex(double n) { 58 | String res = Double.toHexString(n); 59 | if (res.length() % 2 == 1) { 60 | res = "0" + res; 61 | } 62 | return res.toUpperCase(); 63 | } 64 | 65 | /** 66 | * 字符串转换为16进制字符串 67 | * 68 | * @param s 69 | * @return 70 | */ 71 | public static String stringToHex(String s) { 72 | StringBuilder str = new StringBuilder(); 73 | for (int i = 0; i < s.length(); i++) { 74 | int ch = s.charAt(i); 75 | String s4 = Integer.toHexString(ch); 76 | str.append(s4); 77 | } 78 | return str.toString().toUpperCase(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/detect/entity/VideoStreamQualityDetectResult.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.detect.entity; 2 | 3 | public class VideoStreamQualityDetectResult { 4 | 5 | private String deviceId; 6 | private String channelId; 7 | private Boolean hasError; 8 | private String error; 9 | private Boolean hasQualityError; 10 | private String qualityError; 11 | private String detail; 12 | private String snapshot; 13 | 14 | public Boolean getHasError() { 15 | return hasError; 16 | } 17 | 18 | public void setHasError(Boolean hasError) { 19 | this.hasError = hasError; 20 | } 21 | 22 | public Boolean getHasQualityError() { 23 | return hasQualityError; 24 | } 25 | 26 | public void setHasQualityError(Boolean hasQualityError) { 27 | this.hasQualityError = hasQualityError; 28 | } 29 | 30 | public String getQualityError() { 31 | return qualityError; 32 | } 33 | 34 | public void setQualityError(String qualityError) { 35 | this.qualityError = qualityError; 36 | } 37 | 38 | public String getError() { 39 | return error; 40 | } 41 | 42 | public void setError(String error) { 43 | this.error = error; 44 | } 45 | 46 | public String getDeviceId() { 47 | return deviceId; 48 | } 49 | 50 | public void setDeviceId(String deviceId) { 51 | this.deviceId = deviceId; 52 | } 53 | 54 | public String getChannelId() { 55 | return channelId; 56 | } 57 | 58 | public void setChannelId(String channelId) { 59 | this.channelId = channelId; 60 | } 61 | 62 | public String getDetail() { 63 | return detail; 64 | } 65 | 66 | public void setDetail(String detail) { 67 | this.detail = detail; 68 | } 69 | 70 | public String getSnapshot() { 71 | return snapshot; 72 | } 73 | 74 | public void setSnapshot(String snapshot) { 75 | this.snapshot = snapshot; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /web/src/pages/device/DeviceRemoveConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 75 | 76 | 79 | -------------------------------------------------------------------------------- /web/src/pages/schedule/SchedulePauseConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 76 | 77 | 80 | -------------------------------------------------------------------------------- /web/src/pages/schedule/ScheduleResumeConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 76 | 77 | 80 | -------------------------------------------------------------------------------- /web/src/pages/schedule/ScheduleRemoveConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 76 | 77 | 80 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/openapi/controller/OpenApiController.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.openapi.controller; 2 | 3 | 4 | import fun.bookish.blueberry.core.annotation.EnableResponseBodyJsonWrap; 5 | import fun.bookish.blueberry.server.openapi.entity.OpenDeviceStatusVO; 6 | import fun.bookish.blueberry.server.openapi.entity.OpenDeviceVO; 7 | import fun.bookish.blueberry.server.openapi.service.IOpenApiService; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiImplicitParam; 10 | import io.swagger.annotations.ApiImplicitParams; 11 | import io.swagger.annotations.ApiOperation; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.GetMapping; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import springfox.documentation.annotations.ApiIgnore; 17 | 18 | import javax.validation.constraints.NotBlank; 19 | import java.util.List; 20 | 21 | /** 22 | *

23 | * open api 前端控制器 24 | *

25 | * 26 | * @author RabbitNoTeeth 27 | * @since 2021-06-11 28 | */ 29 | @Api(tags = "OpenAPI管理") 30 | @RestController 31 | @EnableResponseBodyJsonWrap 32 | @RequestMapping("/api/v1/open") 33 | public class OpenApiController { 34 | 35 | @Autowired 36 | private IOpenApiService openApiService; 37 | 38 | @ApiOperation("查询设备列表") 39 | @GetMapping("/device/list") 40 | public List deviceList() { 41 | return openApiService.queryDeviceList(); 42 | } 43 | 44 | @ApiOperation("查询设备状态列表") 45 | @GetMapping("/device/status/list") 46 | public List deviceStatusList() { 47 | return openApiService.queryDeviceStatusList(); 48 | } 49 | 50 | @ApiOperation("查询设备状态") 51 | @ApiImplicitParams({ 52 | @ApiImplicitParam(name = "id", value = "设备id", required = true, type = "query") 53 | }) 54 | @GetMapping("/device/status") 55 | public OpenDeviceStatusVO deviceStatus(@ApiIgnore @NotBlank(message = "id不能为空") String id) { 56 | return openApiService.queryDeviceStatus(id); 57 | } 58 | 59 | } 60 | 61 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmetic/service/IVideoQualityDetectArithmeticService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmetic.service; 2 | 3 | import fun.bookish.blueberry.core.page.PageResult; 4 | import fun.bookish.blueberry.server.videoqualitydetect.arithmetic.entity.*; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 视频质量检测算法 服务类 12 | *

13 | * 14 | * @author RabbitNoTeeth 15 | * @since 2021-06-10 16 | */ 17 | public interface IVideoQualityDetectArithmeticService extends IService { 18 | 19 | /** 20 | * 添加 21 | * 22 | * @param videoQualityDetectArithmeticVO 23 | * @return 24 | */ 25 | Integer add(VideoQualityDetectArithmeticVO videoQualityDetectArithmeticVO); 26 | 27 | /** 28 | * 更新 29 | * 30 | * @param videoQualityDetectArithmeticVO 31 | * @return 32 | */ 33 | Integer update(VideoQualityDetectArithmeticVO videoQualityDetectArithmeticVO); 34 | 35 | /** 36 | * 删除 37 | * 38 | * @param id 39 | * @return 40 | */ 41 | Integer deleteById(Integer id); 42 | 43 | /** 44 | * 查询列表 45 | * 46 | * @return 47 | * @param params 48 | */ 49 | List queryList(VideoQualityDetectArithmeticQueryParamVO params); 50 | 51 | /** 52 | * 分页查询 53 | * @param page 54 | * @param pageSize 55 | * @param params 56 | * @return 57 | */ 58 | PageResult queryPage(Integer page, Integer pageSize, VideoQualityDetectArithmeticQueryParamVO params); 59 | 60 | /** 61 | * 查询支持的算法列表 62 | * 63 | * @return 64 | */ 65 | List querySupportedArithmeticList(); 66 | 67 | /** 68 | * 查询可应用的设备列表 69 | * 70 | * @return 71 | */ 72 | List queryApplicableDeviceList(); 73 | 74 | /** 75 | * 查询已应用的设备列表 76 | * 77 | * @param id 78 | * @return 79 | */ 80 | List queryAppliedDeviceList(Integer id); 81 | 82 | } 83 | -------------------------------------------------------------------------------- /web/src/pages/videoqualitydetect/arithmetic/VideoQualityDetectArithmeticRemoveConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 75 | 76 | 79 | -------------------------------------------------------------------------------- /m-quartz/src/main/java/fun/bookish/blueberry/quartz/service/IQuartzService.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.quartz.service; 2 | 3 | 4 | 5 | import fun.bookish.blueberry.quartz.entity.MisfireInstruction; 6 | import fun.bookish.blueberry.quartz.entity.QuartzJobEntity; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author LIUXINDONG 12 | */ 13 | public interface IQuartzService { 14 | 15 | /** 16 | * 查询job类名 17 | * 18 | * @return 19 | */ 20 | List findJobClassNames(); 21 | 22 | /** 23 | * 新建任务 24 | * 25 | * @param entity 26 | * @return 27 | */ 28 | void addJob(QuartzJobEntity entity); 29 | 30 | /** 31 | * 更新任务 32 | * 33 | * @param entity 34 | */ 35 | void updateJob(QuartzJobEntity entity); 36 | 37 | /** 38 | * 暂停任务 39 | * 40 | * @param name 41 | * @param group 42 | */ 43 | void pauseJob(String name, String group); 44 | 45 | /** 46 | * 恢复任务 47 | * 48 | * @param name 49 | * @param group 50 | */ 51 | void resumeJob(String name, String group); 52 | 53 | /** 54 | * 删除任务 55 | * 56 | * @param name 57 | * @param group 58 | */ 59 | void deleteJob(String name, String group); 60 | 61 | /** 62 | * 查询所有任务 63 | * 64 | * @return 65 | * @param name 66 | * @param group 67 | * @param state 68 | */ 69 | List allJobs(String name, String group, String description, String state); 70 | 71 | /** 72 | * 启动所有任务 73 | */ 74 | void resumeAllJobs(); 75 | 76 | /** 77 | * 暂停所有任务 78 | */ 79 | void pauseAllJobs(); 80 | 81 | /** 82 | * 启动任务调度器 83 | */ 84 | void startScheduler(); 85 | 86 | /** 87 | * 暂停任务调度器 88 | */ 89 | void standbyScheduler(); 90 | 91 | /** 92 | * 关闭任务调度器 93 | */ 94 | void shutdownScheduler(); 95 | 96 | /** 97 | * 查询任务调度器状态 98 | */ 99 | String schedulerState(); 100 | 101 | /** 102 | * 查询补偿策略列表 103 | * @return 104 | */ 105 | List findMisfireInstructions(); 106 | } 107 | -------------------------------------------------------------------------------- /web/src/pages/videoqualitydetect/arithmetic/VideoQualityDetectArithmeticPauseConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 76 | 77 | 80 | -------------------------------------------------------------------------------- /web/src/pages/videoqualitydetect/arithmetic/VideoQualityDetectArithmeticResumeConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 76 | 77 | 80 | -------------------------------------------------------------------------------- /web/src/pages/channel/StreamViewer.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 81 | 82 | 85 | -------------------------------------------------------------------------------- /web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy 3 | // This option interrupts the configuration hierarchy at this file 4 | // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) 5 | root: true, 6 | 7 | parserOptions: { 8 | parser: 'babel-eslint', 9 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features 10 | sourceType: 'module' // Allows for the use of imports 11 | }, 12 | 13 | env: { 14 | browser: true 15 | }, 16 | 17 | // Rules order is important, please avoid shuffling them 18 | extends: [ 19 | // Base ESLint recommended rules 20 | // 'eslint:recommended', 21 | 22 | 23 | // Uncomment any of the lines below to choose desired strictness, 24 | // but leave only one uncommented! 25 | // See https://eslint.vuejs.org/rules/#available-rules 26 | 'plugin:vue/essential', // Priority A: Essential (Error Prevention) 27 | // 'plugin:vue/strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) 28 | // 'plugin:vue/recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead) 29 | 30 | // https://github.com/prettier/eslint-config-prettier#installation 31 | // usage with Prettier, provided by 'eslint-config-prettier'. 32 | 'prettier' 33 | ], 34 | 35 | plugins: [ 36 | // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file 37 | // required to lint *.vue files 38 | 'vue', 39 | 40 | // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674 41 | // Prettier has not been included as plugin to avoid performance impact 42 | // add it as an extension for your IDE 43 | ], 44 | 45 | globals: { 46 | ga: 'readonly', // Google Analytics 47 | cordova: 'readonly', 48 | __statics: 'readonly', 49 | process: 'readonly', 50 | Capacitor: 'readonly', 51 | chrome: 'readonly' 52 | }, 53 | 54 | // add your custom rules here 55 | rules: { 56 | 'prefer-promise-reject-errors': 'off', 57 | 58 | 59 | // allow debugger during development only 60 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/aop/ParameterValidateExtAop.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.aop; 2 | 3 | import fun.bookish.blueberry.core.exception.ParameterValidateException; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Before; 7 | import org.aspectj.lang.annotation.Pointcut; 8 | import org.aspectj.lang.reflect.MethodSignature; 9 | import org.springframework.core.annotation.Order; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.validation.BindException; 12 | 13 | import javax.validation.ConstraintViolation; 14 | import javax.validation.Validation; 15 | import javax.validation.executable.ExecutableValidator; 16 | import java.lang.reflect.Method; 17 | import java.util.Set; 18 | 19 | /** 20 | * 参数校验拓展aop,用于校验基本数据类型 21 | * @author LiuXinDong 22 | */ 23 | @Component 24 | @Aspect 25 | @Order(1) 26 | public class ParameterValidateExtAop { 27 | 28 | private final ExecutableValidator validator = Validation.buildDefaultValidatorFactory().getValidator().forExecutables(); 29 | 30 | @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || " + 31 | "@annotation(org.springframework.web.bind.annotation.GetMapping) || " + 32 | "@annotation(org.springframework.web.bind.annotation.PostMapping) || " + 33 | "@annotation(org.springframework.web.bind.annotation.PutMapping) || " + 34 | "@annotation(org.springframework.web.bind.annotation.DeleteMapping)") 35 | public void intercept(){ 36 | 37 | } 38 | 39 | @Before("intercept()") 40 | public void beforeInvoke(JoinPoint joinPoint) throws BindException { 41 | Object target = joinPoint.getTarget(); 42 | Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); 43 | Set> violationSet = validator.validateParameters(target, method, joinPoint.getArgs()); 44 | if(violationSet.size() > 0){ 45 | String message = violationSet.stream().map(ConstraintViolation::getMessage).reduce("", (x, y) -> x + y + "; "); 46 | // 抛出校验失败异常,该异常会在 GlobalExceptionAdvice 中统一被处理 47 | throw new ParameterValidateException(message); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /m-opencv/src/main/java/fun/bookish/blueberry/opencv/detector/SharpnessDetector.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.opencv.detector; 2 | 3 | import org.bytedeco.javacpp.indexer.DoubleRawIndexer; 4 | import org.bytedeco.opencv.global.opencv_core; 5 | import org.bytedeco.opencv.global.opencv_imgcodecs; 6 | import org.bytedeco.opencv.global.opencv_imgproc; 7 | import org.bytedeco.opencv.opencv_core.Mat; 8 | 9 | /** 10 | * 清晰度检测器 11 | */ 12 | public class SharpnessDetector { 13 | 14 | private float threshold = 10.0f; 15 | 16 | public SharpnessDetector() { 17 | } 18 | 19 | public SharpnessDetector(float threshold) { 20 | this.threshold = threshold; 21 | } 22 | 23 | private Result doDetect(Mat image) { 24 | Mat gray = new Mat(); 25 | opencv_imgproc.cvtColor(image, gray, opencv_imgproc.COLOR_BGR2GRAY); 26 | Mat laplaci = new Mat(); 27 | opencv_imgproc.Laplacian(gray, laplaci, opencv_core.CV_64F); 28 | Mat means = new Mat(); 29 | Mat stddev = new Mat(); 30 | opencv_core.meanStdDev(laplaci, means, stddev); 31 | DoubleRawIndexer meansIndexer = means.createIndexer(); 32 | DoubleRawIndexer stddevIndexer = stddev.createIndexer(); 33 | double men = meansIndexer.get(0); 34 | double dev = stddevIndexer.get(0); 35 | return new Result(threshold, (float) dev, dev < threshold); 36 | } 37 | 38 | public Result detect(Mat image) { 39 | return doDetect(image); 40 | } 41 | 42 | public Result detect(String imagePath) { 43 | Mat image = opencv_imgcodecs.imread(imagePath); 44 | return doDetect(image); 45 | } 46 | 47 | public static class Result { 48 | private final float threshold; 49 | private final float result; 50 | private final boolean hasError; 51 | 52 | Result(float threshold, float result, boolean hasError) { 53 | this.threshold = threshold; 54 | this.result = result; 55 | this.hasError = hasError; 56 | } 57 | 58 | public boolean isHasError() { 59 | return hasError; 60 | } 61 | 62 | public float getThreshold() { 63 | return threshold; 64 | } 65 | 66 | public float getResult() { 67 | return result; 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /m-core/src/main/java/fun/bookish/blueberry/core/json/JsonResult.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.core.json; 2 | 3 | /** 4 | * http json 响应实体 5 | * 6 | * @author LiuXinDong 7 | */ 8 | public class JsonResult { 9 | 10 | /** 11 | * 是否成功 12 | */ 13 | private Boolean success; 14 | /** 15 | * 信息 16 | */ 17 | private String message; 18 | /** 19 | * 数据 20 | */ 21 | private Object data; 22 | 23 | private JsonResult() { 24 | } 25 | 26 | public static JsonResult of(boolean success, String successMessage, String failMessage) { 27 | JsonResult res = new JsonResult(); 28 | res.setSuccess(success); 29 | res.setMessage(success ? successMessage : failMessage); 30 | return res; 31 | } 32 | 33 | public static JsonResult success(String message) { 34 | JsonResult res = new JsonResult(); 35 | res.setSuccess(true); 36 | res.setMessage(message); 37 | return res; 38 | } 39 | 40 | public static JsonResult success(String message, Object data) { 41 | JsonResult res = new JsonResult(); 42 | res.setSuccess(true); 43 | res.setMessage(message); 44 | res.setData(data); 45 | return res; 46 | } 47 | 48 | public static JsonResult fail(String message) { 49 | JsonResult res = new JsonResult(); 50 | res.setSuccess(false); 51 | res.setMessage(message); 52 | return res; 53 | } 54 | 55 | public static JsonResult fail(String message, Object data) { 56 | JsonResult res = new JsonResult(); 57 | res.setSuccess(false); 58 | res.setMessage(message); 59 | res.setData(data); 60 | return res; 61 | } 62 | 63 | public Boolean getSuccess() { 64 | return success; 65 | } 66 | 67 | public String getMessage() { 68 | return message; 69 | } 70 | 71 | public JsonResult setMessage(String message) { 72 | this.message = message; 73 | return this; 74 | } 75 | 76 | public Object getData() { 77 | return data; 78 | } 79 | 80 | public JsonResult setData(Object data) { 81 | this.data = data; 82 | return this; 83 | } 84 | 85 | public JsonResult setSuccess(Boolean success) { 86 | this.success = success; 87 | return this; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /m-sip/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blueberry 7 | fun.bookish 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | m-sip 13 | 14 | 15 | 1.8 16 | 17 | 18 | 19 | 20 | javax.sip 21 | jain-sip-ri 22 | 23 | 24 | org.apache.commons 25 | commons-lang3 26 | 27 | 28 | org.yaml 29 | snakeyaml 30 | 31 | 32 | org.slf4j 33 | slf4j-api 34 | 35 | 36 | ch.qos.logback 37 | logback-classic 38 | 39 | 40 | ch.qos.logback 41 | logback-core 42 | 43 | 44 | log4j 45 | log4j 46 | 47 | 48 | com.fasterxml.jackson.core 49 | jackson-databind 50 | 51 | 52 | com.fasterxml.jackson.core 53 | jackson-core 54 | 55 | 56 | org.dom4j 57 | dom4j 58 | 59 | 60 | com.google.code.gson 61 | gson 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /web/src/pages/channel/ChannelRemoveConfirm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 84 | 85 | 88 | -------------------------------------------------------------------------------- /m-quartz/src/main/java/fun/bookish/blueberry/quartz/listener/GeneralTriggerListener.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.quartz.listener; 2 | 3 | import org.quartz.*; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.text.SimpleDateFormat; 9 | 10 | 11 | /** 12 | * 通用的job监听器 13 | * @author Don9 14 | */ 15 | @Component 16 | public class GeneralTriggerListener implements TriggerListener { 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(GeneralTriggerListener.class); 19 | 20 | @Override 21 | public String getName() { 22 | return "GeneralTriggerListener"; 23 | } 24 | 25 | @Override 26 | public void triggerFired(Trigger trigger, JobExecutionContext context) { 27 | String name = trigger.getJobKey().getName(); 28 | String group = trigger.getJobKey().getGroup(); 29 | String description = context.getJobDetail().getDescription(); 30 | if (LOGGER.isDebugEnabled()) { 31 | LOGGER.debug("任务开始执行 [name = {}, group = {}, description = {}]", name, group, description); 32 | } 33 | } 34 | 35 | @Override 36 | public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) { 37 | return false; 38 | } 39 | 40 | @Override 41 | public void triggerMisfired(Trigger trigger) { 42 | String name = trigger.getJobKey().getName(); 43 | String group = trigger.getJobKey().getGroup(); 44 | String description = trigger.getDescription(); 45 | if (LOGGER.isDebugEnabled()) { 46 | LOGGER.debug("任务补偿 [name = {}, group = {}, description = {}]", name, group, description); 47 | } 48 | } 49 | 50 | @Override 51 | public void triggerComplete(Trigger trigger, JobExecutionContext context, Trigger.CompletedExecutionInstruction triggerInstructionCode) { 52 | String name = trigger.getJobKey().getName(); 53 | String group = trigger.getJobKey().getGroup(); 54 | String description = context.getJobDetail().getDescription(); 55 | String nextFireTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(trigger.getNextFireTime()); 56 | if (LOGGER.isDebugEnabled()) { 57 | LOGGER.debug("任务执行结束 [name = {}, group = {}, description = {}, nextFireTime = {}]", name, group, description, nextFireTime); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/request/producer/SipRequestProducer.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.request.producer; 2 | 3 | import fun.bookish.blueberry.sip.SipServer; 4 | import fun.bookish.blueberry.sip.exception.SipRequestCreationException; 5 | import fun.bookish.blueberry.sip.request.producer.impl.SipRequestProducerImpl; 6 | 7 | import javax.sip.message.Request; 8 | 9 | /** 10 | * sip请求生产者接口 11 | */ 12 | public interface SipRequestProducer { 13 | 14 | static SipRequestProducer create(SipServer sipServer) { 15 | return new SipRequestProducerImpl(sipServer); 16 | } 17 | 18 | /** 19 | * 创建MESSAGE请求 20 | * 21 | * @param toDeviceId 22 | * @param toAddress 23 | * @param deviceId 24 | * @param transport 25 | * @param content 26 | * @return 27 | * @throws SipRequestCreationException 28 | */ 29 | Request createMessageRequest(String toDeviceId, String toAddress, String deviceId, String transport, String content) throws SipRequestCreationException; 30 | 31 | /** 32 | * 创建INVITE请求 33 | * 34 | * @param toDeviceId 35 | * @param toAddress 36 | * @param deviceId 37 | * @param transport 38 | * @param content 39 | * @return 40 | * @throws SipRequestCreationException 41 | */ 42 | Request createInviteRequest(String toDeviceId, String toAddress, String deviceId, String transport, String content) throws SipRequestCreationException; 43 | 44 | /** 45 | * 创建INVITE请求 46 | * 47 | * @param toDeviceId 48 | * @param toAddress 49 | * @param deviceId 50 | * @param transport 51 | * @param fromTag 52 | * @param content 53 | * @return 54 | * @throws SipRequestCreationException 55 | */ 56 | Request createInviteRequest(String toDeviceId, String toAddress, String deviceId, String transport, String fromTag, String content) throws SipRequestCreationException; 57 | 58 | /** 59 | * 创建BYE请求 60 | * 61 | * @param toDeviceId 62 | * @param toAddress 63 | * @param deviceId 64 | * @param transport 65 | * @param fromTag 66 | * @param toTag 67 | * @param callId 68 | * @return 69 | * @throws SipRequestCreationException 70 | */ 71 | Request createByeRequest(String toDeviceId, String toAddress, String deviceId, String transport, String fromTag, String toTag, String callId) throws SipRequestCreationException; 72 | 73 | } 74 | -------------------------------------------------------------------------------- /m-server/src/main/java/fun/bookish/blueberry/server/videoqualitydetect/arithmeticapplydevice/entity/VideoQualityDetectArithmeticApplyDevicePO.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.server.videoqualitydetect.arithmeticapplydevice.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import com.baomidou.mybatisplus.annotation.IdType; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import java.io.Serializable; 7 | 8 | /** 9 | *

10 | * 视频质量检测算法应用设备表 11 | *

12 | * 13 | * @author RabbitNoTeeth 14 | * @since 2021-06-15 15 | */ 16 | @TableName("t_video_quality_detect_arithmetic_apply_device") 17 | public class VideoQualityDetectArithmeticApplyDevicePO implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 算法id 26 | */ 27 | private Integer arithmeticId; 28 | 29 | /** 30 | * 设备id 31 | */ 32 | private String deviceId; 33 | 34 | /** 35 | * 通道id 36 | */ 37 | private String channelId; 38 | 39 | /** 40 | * 创建时间 41 | */ 42 | private String createdAt; 43 | 44 | 45 | public Integer getId() { 46 | return id; 47 | } 48 | 49 | public void setId(Integer id) { 50 | this.id = id; 51 | } 52 | 53 | public Integer getArithmeticId() { 54 | return arithmeticId; 55 | } 56 | 57 | public void setArithmeticId(Integer arithmeticId) { 58 | this.arithmeticId = arithmeticId; 59 | } 60 | 61 | public String getDeviceId() { 62 | return deviceId; 63 | } 64 | 65 | public void setDeviceId(String deviceId) { 66 | this.deviceId = deviceId; 67 | } 68 | 69 | public String getChannelId() { 70 | return channelId; 71 | } 72 | 73 | public void setChannelId(String channelId) { 74 | this.channelId = channelId; 75 | } 76 | 77 | public String getCreatedAt() { 78 | return createdAt; 79 | } 80 | 81 | public void setCreatedAt(String createdAt) { 82 | this.createdAt = createdAt; 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | return "VideoQualityDetectArithmeticApplyDevicePO{" + 88 | "id=" + id + 89 | ", arithmeticId=" + arithmeticId + 90 | ", deviceId=" + deviceId + 91 | ", channelId=" + channelId + 92 | ", createdAt=" + createdAt + 93 | "}"; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /m-quartz/src/main/java/fun/bookish/blueberry/quartz/listener/QuartzSchedulerListener.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.quartz.listener; 2 | 3 | import org.quartz.*; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * 任务调度器监听器 10 | * @author Don9 11 | */ 12 | @Component 13 | public class QuartzSchedulerListener implements SchedulerListener { 14 | 15 | private static final Logger LOGGER = LoggerFactory.getLogger(QuartzSchedulerListener.class); 16 | 17 | @Override 18 | public void jobScheduled(Trigger trigger) { 19 | 20 | } 21 | 22 | @Override 23 | public void jobUnscheduled(TriggerKey triggerKey) { 24 | 25 | } 26 | 27 | @Override 28 | public void triggerFinalized(Trigger trigger) { 29 | 30 | } 31 | 32 | @Override 33 | public void triggerPaused(TriggerKey triggerKey) { 34 | 35 | } 36 | 37 | @Override 38 | public void triggersPaused(String triggerGroup) { 39 | 40 | } 41 | 42 | @Override 43 | public void triggerResumed(TriggerKey triggerKey) { 44 | 45 | } 46 | 47 | @Override 48 | public void triggersResumed(String triggerGroup) { 49 | 50 | } 51 | 52 | @Override 53 | public void jobAdded(JobDetail jobDetail) { 54 | 55 | } 56 | 57 | @Override 58 | public void jobDeleted(JobKey jobKey) { 59 | 60 | } 61 | 62 | @Override 63 | public void jobPaused(JobKey jobKey) { 64 | 65 | } 66 | 67 | @Override 68 | public void jobsPaused(String jobGroup) { 69 | 70 | } 71 | 72 | @Override 73 | public void jobResumed(JobKey jobKey) { 74 | 75 | } 76 | 77 | @Override 78 | public void jobsResumed(String jobGroup) { 79 | 80 | } 81 | 82 | @Override 83 | public void schedulerError(String msg, SchedulerException cause) { 84 | 85 | } 86 | 87 | @Override 88 | public void schedulerInStandbyMode() { 89 | LOGGER.info("调度器暂停"); 90 | } 91 | 92 | @Override 93 | public void schedulerStarted() { 94 | LOGGER.info("调度器启动"); 95 | } 96 | 97 | @Override 98 | public void schedulerStarting() { 99 | 100 | } 101 | 102 | @Override 103 | public void schedulerShutdown() { 104 | LOGGER.info("调度器关闭"); 105 | } 106 | 107 | @Override 108 | public void schedulerShuttingdown() { 109 | } 110 | 111 | @Override 112 | public void schedulingDataCleared() { 113 | 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /web/src/router/routes.js: -------------------------------------------------------------------------------- 1 | 2 | const routes = [ 3 | // { 4 | // path: '/', 5 | // component: () => import('layouts/MainLayout.vue'), 6 | // children: [ 7 | // { path: '', component: () => import('pages/Index.vue') } 8 | // ] 9 | // }, 10 | { 11 | path: '/', 12 | redirect: '/device/list' 13 | }, 14 | { 15 | path: '/device/list', 16 | component: () => import('layouts/MainLayout.vue'), 17 | children: [ 18 | { path: '', component: () => import('pages/device/DeviceList') } 19 | ] 20 | }, 21 | { 22 | path: '/channels/:deviceType/:deviceId', 23 | component: () => import('layouts/MainLayout.vue'), 24 | children: [ 25 | { path: '', component: () => import('pages/channel/ChannelList') } 26 | ] 27 | }, 28 | { 29 | path: '/stream/list', 30 | component: () => import('layouts/MainLayout.vue'), 31 | children: [ 32 | { path: '', component: () => import('pages/stream/StreamList') } 33 | ] 34 | }, 35 | { 36 | path: '/schedule/list', 37 | component: () => import('layouts/MainLayout.vue'), 38 | children: [ 39 | { path: '', component: () => import('pages/schedule/ScheduleList') } 40 | ] 41 | }, 42 | { 43 | path: '/videoQualityDetect/strategy/list', 44 | component: () => import('layouts/MainLayout.vue'), 45 | children: [ 46 | { path: '', component: () => import('pages/videoqualitydetect/arithmetic/VideoQualityDetectArithmeticList') } 47 | ] 48 | }, 49 | { 50 | path: '/videoQualityDetect/record/list', 51 | component: () => import('layouts/MainLayout.vue'), 52 | children: [ 53 | { path: '', component: () => import('pages/videoqualitydetect/record/VideoQualityDetectRecordList') } 54 | ] 55 | }, 56 | { 57 | path: '/videoQualityDetect/manual', 58 | component: () => import('layouts/MainLayout.vue'), 59 | children: [ 60 | { path: '', component: () => import('pages/videoqualitydetect/manual/VideoQualityDetectManualView') } 61 | ] 62 | }, 63 | { 64 | path: '/videoQualityDetect/manual2', 65 | component: () => import('pages/videoqualitydetect/manual/VideoQualityDetectManualView') 66 | }, 67 | { 68 | path: '/api/list', 69 | component: () => import('layouts/MainLayout.vue'), 70 | children: [ 71 | { path: '', component: () => import('pages/api/ApiDocumentView') } 72 | ] 73 | }, 74 | // Always leave this as last one, 75 | // but you can also remove it 76 | { 77 | path: '*', 78 | component: () => import('pages/Error404.vue') 79 | } 80 | ] 81 | 82 | export default routes 83 | -------------------------------------------------------------------------------- /m-sip/src/main/java/fun/bookish/blueberry/sip/entity/SipDeviceInfoDesc.java: -------------------------------------------------------------------------------- 1 | package fun.bookish.blueberry.sip.entity; 2 | 3 | 4 | import fun.bookish.blueberry.sip.event.SipEventTypeEnum; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 设备信息描述 10 | */ 11 | public class SipDeviceInfoDesc extends SipDeviceDesc{ 12 | 13 | /** 14 | * 设备名称(必选) 15 | */ 16 | private String deviceName; 17 | /** 18 | * 查询结果(必选): 19 | * OK 20 | * ERROR 21 | */ 22 | private String result; 23 | /** 24 | * 设备生产商(可选) 25 | */ 26 | private String manufacturer; 27 | /** 28 | * 设备型号(可选) 29 | */ 30 | private String model; 31 | /** 32 | * 设备固件版本(可选) 33 | */ 34 | private String firmware; 35 | /** 36 | * 视频输入通道数(可选) 37 | */ 38 | private Integer channel; 39 | /** 40 | * 扩展信息(可选) 41 | */ 42 | private List info; 43 | 44 | public SipDeviceInfoDesc(String requestDeviceID, String requestDeviceAddress, String deviceId, String registerServer, SipEventTypeEnum eventType) { 45 | super(requestDeviceID, requestDeviceAddress, deviceId, registerServer, eventType); 46 | } 47 | 48 | public String getDeviceName() { 49 | return deviceName; 50 | } 51 | 52 | public void setDeviceName(String deviceName) { 53 | this.deviceName = deviceName; 54 | } 55 | 56 | public String getManufacturer() { 57 | return manufacturer; 58 | } 59 | 60 | public void setManufacturer(String manufacturer) { 61 | this.manufacturer = manufacturer; 62 | } 63 | 64 | public String getModel() { 65 | return model; 66 | } 67 | 68 | public void setModel(String model) { 69 | this.model = model; 70 | } 71 | 72 | public String getFirmware() { 73 | return firmware; 74 | } 75 | 76 | public void setFirmware(String firmware) { 77 | this.firmware = firmware; 78 | } 79 | 80 | public String getResult() { 81 | return result; 82 | } 83 | 84 | public void setResult(String result) { 85 | this.result = result; 86 | } 87 | 88 | public Integer getChannel() { 89 | return channel; 90 | } 91 | 92 | public void setChannel(Integer channel) { 93 | this.channel = channel; 94 | } 95 | 96 | public List getInfo() { 97 | return info; 98 | } 99 | 100 | public void setInfo(List info) { 101 | this.info = info; 102 | } 103 | } 104 | --------------------------------------------------------------------------------