| | |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-freemarker</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | |
| | | type: com.walker.jdbc.ds.DefaultDataSource |
| | | hikari: |
| | | minimum-idle: 5 |
| | | idle-timeout: 5000 |
| | | idle-timeout: 600000 |
| | | pool-name: databasePool_walker |
| | | connection-timeout: 10000 |
| | | connection-test-query: select 1 |
| | |
| | | |
| | | video: |
| | | # 视频采集存储根路径 |
| | | # data-folder: D:/dev_tools/ai/ |
| | | data-folder: /opt/ai/video/ |
| | | data-folder: D:/dev_tools/ai/ |
| | | # data-folder: /opt/ai/video/ |
| | | |
| | | # 视频相似度AI服务URL |
| | | ai-service: http://121.36.40.27:12345 |
| | | |
| | | # 推荐相似视频(算法)前多少个 |
| | | top-n: 40 |
| | | |
| | | # 测试模式,如果是则仅生成固定测试数据,正式部署需要改为 false |
| | | test-mode: true |
| | |
| | | spring: |
| | | profiles: |
| | | active: dev |
| | | |
| | | # 视频测试界面引入 2022-09-26 |
| | | freemarker: |
| | | # 模板后缀名 |
| | | suffix: .ftl |
| | | # 文档类型 |
| | | content-type: text/html |
| | | # 页面编码 |
| | | charset: UTF-8 |
| | | # 页面缓存 |
| | | cache: false |
| | | # 模板路径 |
| | | template-loader-path: classpath:/templates/ |
| | | settings: |
| | | # 如果变量为null,转化为空字符串 |
| | | classic_compatible: true |
| | | # 数字格式不用逗号隔开 |
| | | number_format: 0.## |
| | | datetime_format: yyyy-MM-dd HH:mm:ss |
| | | # 去掉多余的空格,非常有用 |
| | | whitespace_stripping: true |
New file |
| | |
| | | package com.iplatform.reccommon; |
| | | |
| | | /** |
| | | * 任务状态类型定义。 |
| | | * @author 时克英 |
| | | * @date 2022-09-27 |
| | | */ |
| | | public enum TaskStatus { |
| | | |
| | | /** |
| | | * 视频已被加载(解析) |
| | | */ |
| | | VideoLoad{ |
| | | public String getIndex(){ |
| | | return INDEX_VIDEO_LOAD; |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 视频已成功检索并生成相似视频(完毕) |
| | | */ |
| | | VideoSearch{ |
| | | public String getIndex(){ |
| | | return INDEX_VIDEO_SEARCH; |
| | | } |
| | | }; |
| | | |
| | | public String getIndex(){ |
| | | throw new AbstractMethodError(); |
| | | } |
| | | |
| | | public static final TaskStatus getType(String index){ |
| | | if(index.equals(INDEX_VIDEO_LOAD)){ |
| | | return VideoLoad; |
| | | } else if(index.equals(INDEX_VIDEO_SEARCH)){ |
| | | return VideoSearch; |
| | | } else { |
| | | throw new UnsupportedOperationException("TaskStatus类型不支持: " + index); |
| | | } |
| | | } |
| | | |
| | | public static final String INDEX_VIDEO_LOAD = "0"; |
| | | public static final String INDEX_VIDEO_SEARCH = "1"; |
| | | } |
New file |
| | |
| | | package com.iplatform.model.po; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.walker.jdbc.BasePo; |
| | | |
| | | /** |
| | | * 表名:RC_VIDEO_BATCH * |
| | | * @author genrator |
| | | */ |
| | | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) |
| | | public class Rc_video_batch extends BasePo<Rc_video_batch> { |
| | | // 序列化版本号 |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 用于兼容老写法 |
| | | */ |
| | | @JsonIgnore |
| | | public static final Rc_video_batch ROW_MAPPER = new Rc_video_batch(); |
| | | |
| | | // 主键 |
| | | private Long id = null; |
| | | @JsonIgnore |
| | | protected boolean isset_id = false; |
| | | |
| | | // 属性列表 |
| | | private String batch_id = null; |
| | | @JsonIgnore |
| | | protected boolean isset_batch_id = false; |
| | | |
| | | private Long user_id = null; |
| | | @JsonIgnore |
| | | protected boolean isset_user_id = false; |
| | | |
| | | private String src_video_id = null; |
| | | @JsonIgnore |
| | | protected boolean isset_src_video_id = false; |
| | | |
| | | private String src_video_path = null; |
| | | @JsonIgnore |
| | | protected boolean isset_src_video_path = false; |
| | | |
| | | /** |
| | | * 默认构造函数 |
| | | */ |
| | | public Rc_video_batch() { |
| | | } |
| | | |
| | | /** |
| | | * 根据主键构造对象 |
| | | */ |
| | | public Rc_video_batch(Long id) { |
| | | this.setId(id); |
| | | } |
| | | |
| | | /** |
| | | * 设置主键值 |
| | | */ |
| | | @Override |
| | | public void setPkValue(Object value) { |
| | | this.setId((Long) value); |
| | | } |
| | | |
| | | public Long getId() { |
| | | return this.id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | this.isset_id = true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | public boolean isEmptyId() { |
| | | return this.id == null; |
| | | } |
| | | |
| | | public String getBatch_id() { |
| | | return this.batch_id; |
| | | } |
| | | |
| | | public void setBatch_id(String batch_id) { |
| | | this.batch_id = batch_id; |
| | | this.isset_batch_id = true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | public boolean isEmptyBatch_id() { |
| | | return this.batch_id == null || this.batch_id.length() == 0; |
| | | } |
| | | |
| | | public Long getUser_id() { |
| | | return this.user_id; |
| | | } |
| | | |
| | | public void setUser_id(Long user_id) { |
| | | this.user_id = user_id; |
| | | this.isset_user_id = true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | public boolean isEmptyUser_id() { |
| | | return this.user_id == null; |
| | | } |
| | | |
| | | public String getSrc_video_id() { |
| | | return this.src_video_id; |
| | | } |
| | | |
| | | public void setSrc_video_id(String src_video_id) { |
| | | this.src_video_id = src_video_id; |
| | | this.isset_src_video_id = true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | public boolean isEmptySrc_video_id() { |
| | | return this.src_video_id == null || this.src_video_id.length() == 0; |
| | | } |
| | | |
| | | public String getSrc_video_path() { |
| | | return this.src_video_path; |
| | | } |
| | | |
| | | public void setSrc_video_path(String src_video_path) { |
| | | this.src_video_path = src_video_path; |
| | | this.isset_src_video_path = true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | public boolean isEmptySrc_video_path() { |
| | | return this.src_video_path == null || this.src_video_path.length() == 0; |
| | | } |
| | | |
| | | /** |
| | | * 重写 toString() 方法 |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return new StringBuilder() |
| | | .append("id=").append(this.id) |
| | | .append("batch_id=").append(this.batch_id) |
| | | .append("user_id=").append(this.user_id) |
| | | .append("src_video_id=").append(this.src_video_id) |
| | | .append("src_video_path=").append(this.src_video_path) |
| | | .toString(); |
| | | } |
| | | |
| | | /** |
| | | * 克隆 |
| | | */ |
| | | public Rc_video_batch $clone() { |
| | | Rc_video_batch rc_video_batch = new Rc_video_batch(); |
| | | |
| | | // 数据库名称 |
| | | //rc_video_batch.setDatabaseName_(this.getDatabaseName_()); |
| | | |
| | | // 主键 |
| | | if (this.isset_id) { |
| | | rc_video_batch.setId(this.getId()); |
| | | } |
| | | // 普通属性 |
| | | if (this.isset_batch_id) { |
| | | rc_video_batch.setBatch_id(this.getBatch_id()); |
| | | } |
| | | if (this.isset_user_id) { |
| | | rc_video_batch.setUser_id(this.getUser_id()); |
| | | } |
| | | if (this.isset_src_video_id) { |
| | | rc_video_batch.setSrc_video_id(this.getSrc_video_id()); |
| | | } |
| | | if (this.isset_src_video_path) { |
| | | rc_video_batch.setSrc_video_path(this.getSrc_video_path()); |
| | | } |
| | | return rc_video_batch; |
| | | } |
| | | } |
New file |
| | |
| | | package com.iplatform.model.po; |
| | | |
| | | import com.walker.jdbc.BaseMapper; |
| | | import com.walker.jdbc.ResultSetUtils; |
| | | import com.walker.jdbc.SqlAndParameters; |
| | | import com.walker.jdbc.sqlgen.DeleteBuilder; |
| | | import com.walker.jdbc.sqlgen.InsertBuilder; |
| | | import com.walker.jdbc.sqlgen.SelectBuilder; |
| | | import com.walker.jdbc.sqlgen.UpdateBuilder; |
| | | import com.walker.jdbc.util.StringUtils; |
| | | |
| | | import org.springframework.jdbc.core.RowMapper; |
| | | |
| | | import java.sql.ResultSet; |
| | | import java.sql.SQLException; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表名:RC_VIDEO_BATCH * |
| | | * @author genrator |
| | | */ |
| | | public class Rc_video_batch_mapper extends Rc_video_batch implements BaseMapper<Rc_video_batch> { |
| | | // 序列化版本号 |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final RowMapper<Rc_video_batch> ROW_MAPPER = new Rc_video_batchRowMapper(); |
| | | |
| | | // 主键 |
| | | public static final String ID = "id"; |
| | | // 普通属性 |
| | | public static final String BATCH_ID = "batch_id"; |
| | | public static final String USER_ID = "user_id"; |
| | | public static final String SRC_VIDEO_ID = "src_video_id"; |
| | | public static final String SRC_VIDEO_PATH = "src_video_path"; |
| | | |
| | | /** |
| | | * 默认构造函数 |
| | | */ |
| | | public Rc_video_batch_mapper(Rc_video_batch rc_video_batch) { |
| | | if (rc_video_batch == null) { |
| | | throw new IllegalArgumentException("po参数不允许为空!"); |
| | | } |
| | | //主键 |
| | | if (rc_video_batch.isset_id) { |
| | | this.setId(rc_video_batch.getId()); |
| | | } |
| | | //普通属性 |
| | | if (rc_video_batch.isset_batch_id) { |
| | | this.setBatch_id(rc_video_batch.getBatch_id()); |
| | | } |
| | | if (rc_video_batch.isset_user_id) { |
| | | this.setUser_id(rc_video_batch.getUser_id()); |
| | | } |
| | | if (rc_video_batch.isset_src_video_id) { |
| | | this.setSrc_video_id(rc_video_batch.getSrc_video_id()); |
| | | } |
| | | if (rc_video_batch.isset_src_video_path) { |
| | | this.setSrc_video_path(rc_video_batch.getSrc_video_path()); |
| | | } |
| | | // 去掉,2022-09-07 |
| | | // this.setDatabaseName_(rc_video_batch.getDatabaseName_()); |
| | | } |
| | | |
| | | /** |
| | | * 获取表名 |
| | | */ |
| | | @Override |
| | | public String getTableName_() { |
| | | String tableName = "rc_video_batch"; |
| | | /** |
| | | if (StringUtils.isNotEmpty(this.getDatabaseName_())) { |
| | | return this.getDatabaseName_() + "." + tableName; |
| | | } else { |
| | | return tableName; |
| | | } |
| | | */ |
| | | return tableName; |
| | | } |
| | | |
| | | /** |
| | | * 获取主键名称 |
| | | */ |
| | | @Override |
| | | public String getPkName_() { |
| | | return ID; |
| | | } |
| | | |
| | | /** |
| | | * 获取主键值 |
| | | */ |
| | | @Override |
| | | public Object getPkValue_() { |
| | | return this.getId(); |
| | | } |
| | | |
| | | /** |
| | | * 获取插入语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getInsertSql_() { |
| | | InsertBuilder ib = new InsertBuilder(this.getTableName_()); |
| | | ib.set(ID, this.getId()); |
| | | ib.set(BATCH_ID, this.getBatch_id(), this.isset_batch_id); |
| | | ib.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ib.set(SRC_VIDEO_ID, this.getSrc_video_id(), this.isset_src_video_id); |
| | | ib.set(SRC_VIDEO_PATH, this.getSrc_video_path(), this.isset_src_video_path); |
| | | return ib.genMapSql(); |
| | | } |
| | | |
| | | /** |
| | | * 获取更新语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getUpdateSql_() { |
| | | UpdateBuilder ub = new UpdateBuilder(this.getTableName_()); |
| | | ub.set(BATCH_ID, this.getBatch_id(), this.isset_batch_id); |
| | | ub.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ub.set(SRC_VIDEO_ID, this.getSrc_video_id(), this.isset_src_video_id); |
| | | ub.set(SRC_VIDEO_PATH, this.getSrc_video_path(), this.isset_src_video_path); |
| | | ub.where(this.getPkName_(), this.getPkValue_()); |
| | | return ub.genMapSql(); |
| | | } |
| | | |
| | | /** |
| | | * 获取更新语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getUpdateSql_(String where, Map<String, Object> parameters) { |
| | | UpdateBuilder ub = new UpdateBuilder(this.getTableName_()); |
| | | ub.set(BATCH_ID, this.getBatch_id(), this.isset_batch_id); |
| | | ub.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ub.set(SRC_VIDEO_ID, this.getSrc_video_id(), this.isset_src_video_id); |
| | | ub.set(SRC_VIDEO_PATH, this.getSrc_video_path(), this.isset_src_video_path); |
| | | |
| | | return ub.genMapSql(where, parameters); |
| | | } |
| | | |
| | | /** |
| | | * 获取更新语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Object[]> getUpdateSql_(String where, Object[] parameters) { |
| | | UpdateBuilder ub = new UpdateBuilder(this.getTableName_()); |
| | | ub.set(BATCH_ID, this.getBatch_id(), this.isset_batch_id); |
| | | ub.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ub.set(SRC_VIDEO_ID, this.getSrc_video_id(), this.isset_src_video_id); |
| | | ub.set(SRC_VIDEO_PATH, this.getSrc_video_path(), this.isset_src_video_path); |
| | | |
| | | return ub.genArraySql(where, parameters); |
| | | } |
| | | |
| | | /** |
| | | * 获取删除语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getDeleteSql_() { |
| | | DeleteBuilder db = new DeleteBuilder(this.getTableName_()); |
| | | db.where(this.getPkName_(), this.getPkValue_()); |
| | | return db.genMapSql(); |
| | | } |
| | | |
| | | /** |
| | | * 获取删除语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getDeleteSql_(String where, Map<String, Object> parameters) { |
| | | DeleteBuilder db = new DeleteBuilder(this.getTableName_()); |
| | | return db.genMapSql(where, parameters); |
| | | } |
| | | |
| | | /** |
| | | * 获取删除语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Object[]> getDeleteSql_(String where, Object[] parameters) { |
| | | DeleteBuilder db = new DeleteBuilder(this.getTableName_()); |
| | | return db.genArraySql(where, parameters); |
| | | } |
| | | |
| | | /** |
| | | * 获取单行查询语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getSingleSql_() { |
| | | SelectBuilder sb = new SelectBuilder(this.getTableName_()); |
| | | sb.where(this.getPkName_(), this.getPkValue_()); |
| | | return sb.genMapSql(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取查询语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getSelectSql_(String where, Map<String, Object> parameters) { |
| | | return new SqlAndParameters<>("select id, batch_id, user_id, src_video_id, src_video_path from " + this.getTableName_() + " " + where, parameters); |
| | | } |
| | | |
| | | /** |
| | | * 获取查询语句和参数 |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Object[]> getSelectSql_(String where, Object[] parameters) { |
| | | return new SqlAndParameters<>("select id, batch_id, user_id, src_video_id, src_video_path from " + this.getTableName_() + " " + where, parameters); |
| | | } |
| | | |
| | | /** |
| | | * 将resultset的一行转化为po |
| | | */ |
| | | @Override |
| | | public Rc_video_batch mapRow(ResultSet rs, int i) throws SQLException { |
| | | return ROW_MAPPER.mapRow(rs, i); |
| | | } |
| | | |
| | | /** |
| | | * 克隆 |
| | | */ |
| | | public Rc_video_batch toRc_video_batch() { |
| | | return super.$clone(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * rc_video_batch RowMapper |
| | | * |
| | | * @author genrator |
| | | */ |
| | | class Rc_video_batchRowMapper implements RowMapper<Rc_video_batch> { |
| | | |
| | | @Override |
| | | public Rc_video_batch mapRow(ResultSet rs, int i) throws SQLException { |
| | | ResultSetUtils resultSetUtils = new ResultSetUtils(); |
| | | Rc_video_batch rc_video_batch = new Rc_video_batch(); |
| | | Integer columnIndex; |
| | | //主键 |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_batch_mapper.ID); |
| | | if (columnIndex > 0) { |
| | | rc_video_batch.setId(rs.getLong(columnIndex)); |
| | | } |
| | | //普通属性 |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_batch_mapper.BATCH_ID); |
| | | if (columnIndex > 0) { |
| | | rc_video_batch.setBatch_id(rs.getString(columnIndex)); |
| | | } |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_batch_mapper.USER_ID); |
| | | if (columnIndex > 0) { |
| | | if (rs.getBigDecimal(columnIndex) == null) { |
| | | rc_video_batch.setUser_id(null); |
| | | } else { |
| | | rc_video_batch.setUser_id(rs.getLong(columnIndex)); |
| | | } |
| | | } |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_batch_mapper.SRC_VIDEO_ID); |
| | | if (columnIndex > 0) { |
| | | rc_video_batch.setSrc_video_id(rs.getString(columnIndex)); |
| | | } |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_batch_mapper.SRC_VIDEO_PATH); |
| | | if (columnIndex > 0) { |
| | | rc_video_batch.setSrc_video_path(rs.getString(columnIndex)); |
| | | } |
| | | return rc_video_batch; |
| | | } |
| | | } |
| | |
| | | public static final Rc_video_user ROW_MAPPER = new Rc_video_user(); |
| | | |
| | | // 主键 |
| | | private Long id; |
| | | private Long id = null; |
| | | @JsonIgnore |
| | | protected boolean isset_id = false; |
| | | |
| | |
| | | this.setId((Long) value); |
| | | } |
| | | |
| | | public Long getId(){return this.id;} |
| | | public Long getId() { |
| | | return this.id; |
| | | } |
| | | |
| | | public void setId(Long id){ |
| | | this.id = id; |
| | |
| | | @Override |
| | | public String toString() { |
| | | return new StringBuilder() |
| | | .append("id=").append(this.id) |
| | | .append("user_id=").append(this.user_id) |
| | | .append("video_id=").append(this.video_id) |
| | | .append("score=").append(this.score) |
| | |
| | | //rc_video_user.setDatabaseName_(this.getDatabaseName_()); |
| | | |
| | | // 主键 |
| | | if (this.isset_id) { |
| | | rc_video_user.setId(this.getId()); |
| | | } |
| | | // 普通属性 |
| | | if (this.isset_user_id) { |
| | | rc_video_user.setUser_id(this.getUser_id()); |
| | | } |
| | | // 普通属性 |
| | | if (this.isset_video_id) { |
| | | rc_video_user.setVideo_id(this.getVideo_id()); |
| | | } |
| | |
| | | public static final RowMapper<Rc_video_user> ROW_MAPPER = new Rc_video_userRowMapper(); |
| | | |
| | | // 主键 |
| | | public static final String USER_ID = "user_id"; |
| | | public static final String ID = "id"; |
| | | // 普通属性 |
| | | public static final String USER_ID = "user_id"; |
| | | public static final String VIDEO_ID = "video_id"; |
| | | public static final String SCORE = "score"; |
| | | public static final String CREATE_TIME = "create_time"; |
| | |
| | | throw new IllegalArgumentException("po参数不允许为空!"); |
| | | } |
| | | //主键 |
| | | if (rc_video_user.isset_id) { |
| | | this.setId(rc_video_user.getId()); |
| | | } |
| | | //普通属性 |
| | | if (rc_video_user.isset_user_id) { |
| | | this.setUser_id(rc_video_user.getUser_id()); |
| | | } |
| | | //普通属性 |
| | | if (rc_video_user.isset_video_id) { |
| | | this.setVideo_id(rc_video_user.getVideo_id()); |
| | | } |
| | |
| | | */ |
| | | @Override |
| | | public String getPkName_() { |
| | | return USER_ID; |
| | | return ID; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public Object getPkValue_() { |
| | | return this.getUser_id(); |
| | | return this.getId(); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getInsertSql_() { |
| | | InsertBuilder ib = new InsertBuilder(this.getTableName_()); |
| | | ib.set(USER_ID, this.getUser_id()); |
| | | ib.set(ID, this.getId()); |
| | | ib.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ib.set(VIDEO_ID, this.getVideo_id(), this.isset_video_id); |
| | | ib.set(SCORE, this.getScore(), this.isset_score); |
| | | ib.set(CREATE_TIME, this.getCreate_time(), this.isset_create_time); |
| | |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getUpdateSql_() { |
| | | UpdateBuilder ub = new UpdateBuilder(this.getTableName_()); |
| | | ub.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ub.set(VIDEO_ID, this.getVideo_id(), this.isset_video_id); |
| | | ub.set(SCORE, this.getScore(), this.isset_score); |
| | | ub.set(CREATE_TIME, this.getCreate_time(), this.isset_create_time); |
| | |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getUpdateSql_(String where, Map<String, Object> parameters) { |
| | | UpdateBuilder ub = new UpdateBuilder(this.getTableName_()); |
| | | ub.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ub.set(VIDEO_ID, this.getVideo_id(), this.isset_video_id); |
| | | ub.set(SCORE, this.getScore(), this.isset_score); |
| | | ub.set(CREATE_TIME, this.getCreate_time(), this.isset_create_time); |
| | |
| | | @Override |
| | | public SqlAndParameters<Object[]> getUpdateSql_(String where, Object[] parameters) { |
| | | UpdateBuilder ub = new UpdateBuilder(this.getTableName_()); |
| | | ub.set(USER_ID, this.getUser_id(), this.isset_user_id); |
| | | ub.set(VIDEO_ID, this.getVideo_id(), this.isset_video_id); |
| | | ub.set(SCORE, this.getScore(), this.isset_score); |
| | | ub.set(CREATE_TIME, this.getCreate_time(), this.isset_create_time); |
| | |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Map<String, Object>> getSelectSql_(String where, Map<String, Object> parameters) { |
| | | return new SqlAndParameters<>("select user_id, video_id, score, create_time from " + this.getTableName_() + " " + where, parameters); |
| | | return new SqlAndParameters<>("select id, user_id, video_id, score, create_time from " + this.getTableName_() + " " + where, parameters); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public SqlAndParameters<Object[]> getSelectSql_(String where, Object[] parameters) { |
| | | return new SqlAndParameters<>("select user_id, video_id, score, create_time from " + this.getTableName_() + " " + where, parameters); |
| | | return new SqlAndParameters<>("select id, user_id, video_id, score, create_time from " + this.getTableName_() + " " + where, parameters); |
| | | } |
| | | |
| | | /** |
| | |
| | | Rc_video_user rc_video_user = new Rc_video_user(); |
| | | Integer columnIndex; |
| | | //主键 |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_user_mapper.USER_ID); |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_user_mapper.ID); |
| | | if (columnIndex > 0) { |
| | | rc_video_user.setUser_id(rs.getLong(columnIndex)); |
| | | rc_video_user.setId(rs.getLong(columnIndex)); |
| | | } |
| | | //普通属性 |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_user_mapper.USER_ID); |
| | | if (columnIndex > 0) { |
| | | if (rs.getBigDecimal(columnIndex) == null) { |
| | | rc_video_user.setUser_id(null); |
| | | } else { |
| | | rc_video_user.setUser_id(rs.getLong(columnIndex)); |
| | | } |
| | | } |
| | | columnIndex = resultSetUtils.findColumn(rs, Rc_video_user_mapper.VIDEO_ID); |
| | | if (columnIndex > 0) { |
| | | rc_video_user.setVideo_id(rs.getString(columnIndex)); |
| | |
| | | |
| | | ALTER TABLE rc_video_batch |
| | | ADD INDEX inx_vb_bid (batch_id) USING BTREE ; |
| | | |
| | | ALTER TABLE rc_video_user |
| | | ADD INDEX inx_vu_uid (user_id) USING BTREE ; |
| | |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | <scope>provided</scope> |
| | | </dependency> |
| | | <!-- FreeMarker做测试页面,2022/09/23 --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-freemarker</artifactId> |
| | | <scope>provided</scope> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.File; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | |
| | | package com.iplatform.recvideo; |
| | | |
| | | import java.text.DecimalFormat; |
| | | import com.walker.infrastructure.utils.NumberFormatUtils; |
| | | |
| | | /** |
| | | * 相似视频对象定义。 |
| | |
| | | |
| | | private double score = 0; |
| | | |
| | | private DecimalFormat df = new DecimalFormat("#.00"); |
| | | // private DecimalFormat df = new DecimalFormat("#.00"); |
| | | |
| | | public String getId() { |
| | | return id; |
| | |
| | | return 0; |
| | | } |
| | | double s = (this.count)/100.0; |
| | | String score = df.format(s); |
| | | this.score = Double.parseDouble(score); |
| | | // String score = df.format(s); |
| | | // this.score = Double.parseDouble(score); |
| | | this.score = NumberFormatUtils.scaleAccuracy2(s); |
| | | return this.score; |
| | | } |
| | | |
| | |
| | | package com.iplatform.recvideo; |
| | | |
| | | import com.walker.infrastructure.utils.NumberFormatUtils; |
| | | |
| | | public class SimilarVideoUser implements Comparable<SimilarVideoUser>{ |
| | | |
| | | private long userId; |
| | |
| | | } |
| | | |
| | | public double getScore() { |
| | | return score; |
| | | return NumberFormatUtils.scaleAccuracy2(this.score); |
| | | } |
| | | |
| | | @Override |
| | |
| | | package com.iplatform.recvideo.api; |
| | | |
| | | import com.iplatform.core.BeanContextAware; |
| | | import com.iplatform.recvideo.config.VideoSimilarProperties; |
| | | import com.iplatform.recvideo.scheduler.VideoSearchScheduler; |
| | | import com.iplatform.recvideo.service.VideoExecutorServiceImpl; |
| | | import com.iplatform.recvideo.support.DefaultSimilarExecutor; |
| | | import com.walker.scheduler.ScheduleEngine; |
| | | import com.walker.scheduler.util.OptionUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | | @RequestMapping("/debug/video") |
| | |
| | | private RestTemplate restTemplate; |
| | | private VideoSimilarProperties videoSimilarProperties; |
| | | private VideoExecutorServiceImpl videoExecutorService; |
| | | |
| | | private VideoSearchScheduler videoSearchScheduler = null; |
| | | |
| | | private DefaultSimilarExecutor similarExecutor = null; |
| | | |
| | |
| | | this.videoExecutorService = videoExecutorService; |
| | | } |
| | | |
| | | @RequestMapping("/start_scheduler_1") |
| | | public String testStartVideoSearchScheduler(){ |
| | | if(this.videoSearchScheduler != null){ |
| | | this.videoSearchScheduler.stop(); |
| | | this.videoSearchScheduler = null; |
| | | } |
| | | |
| | | List<Integer[]> timeRanges = new ArrayList<Integer[]>(1); |
| | | timeRanges.add(new Integer[]{10,11}); |
| | | timeRanges.add(new Integer[]{12,12}); |
| | | |
| | | this.videoSearchScheduler = new VideoSearchScheduler(100, "视频相似度分析调度任务"); |
| | | this.videoSearchScheduler.setOption(OptionUtils.combineEveryDayHourRange(timeRanges)); |
| | | this.videoSearchScheduler.setScheduleEngine(BeanContextAware.getBeanByType(ScheduleEngine.class)); |
| | | this.videoSearchScheduler.setMaxFailedTimes(10); |
| | | this.videoSearchScheduler.start(); |
| | | return this.videoSearchScheduler.getName() + " 启动"; |
| | | } |
| | | |
| | | /** |
| | | * 该测试用于模拟调度任务,每次调用一次执行器方法,批量处理一张图片数据。<p></p> |
| | | * 最终完成一批多个视频的相似度检索并写入数据库中。 |
| | |
| | | |
| | | private String aiService; |
| | | |
| | | private boolean testMode = false; |
| | | |
| | | public boolean isTestMode() { |
| | | return testMode; |
| | | } |
| | | |
| | | public void setTestMode(boolean testMode) { |
| | | this.testMode = testMode; |
| | | } |
| | | |
| | | |
| | | public String getAiService() { |
| | | return aiService; |
| | | } |
New file |
| | |
| | | package com.iplatform.recvideo.controller; |
| | | |
| | | import com.iplatform.model.po.Rc_video_batch; |
| | | import com.iplatform.model.po.Rc_video_t2; |
| | | import com.iplatform.recvideo.config.VideoSimilarProperties; |
| | | import com.iplatform.recvideo.service.VideoShowServiceImpl; |
| | | import com.walker.db.page.GenericPager; |
| | | import com.walker.infrastructure.utils.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.File; |
| | | import java.io.OutputStream; |
| | | import java.io.RandomAccessFile; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.List; |
| | | |
| | | @Controller |
| | | @RequestMapping("/video_ui") |
| | | public class VideoResultController { |
| | | |
| | | private VideoShowServiceImpl videoShowService; |
| | | private VideoSimilarProperties videoSimilarProperties; |
| | | |
| | | @Autowired |
| | | public VideoResultController(VideoShowServiceImpl videoShowService, VideoSimilarProperties videoSimilarProperties){ |
| | | this.videoShowService = videoShowService; |
| | | this.videoSimilarProperties = videoSimilarProperties; |
| | | } |
| | | |
| | | @GetMapping("/index") |
| | | public String index(Model model, String id) { |
| | | |
| | | GenericPager<Rc_video_batch> pager = this.videoShowService.queryPageVideoBatchList(); |
| | | List<Rc_video_batch> data = pager.getDatas(); |
| | | model.addAttribute("src_list", data); |
| | | model.addAttribute("video_folder", this.videoSimilarProperties.getDataFolder()); |
| | | |
| | | if(StringUtils.isNotEmpty(id)){ |
| | | List<Rc_video_t2> list = this.videoShowService.querySimilarVideoList(id); |
| | | model.addAttribute("similar_list", list); |
| | | model.addAttribute("select_id", id); |
| | | } else { |
| | | model.addAttribute("select_id", null); |
| | | } |
| | | return "video/index"; |
| | | } |
| | | |
| | | /** |
| | | * 本地视频转视频流流 |
| | | * @param response |
| | | * @return |
| | | */ |
| | | @RequestMapping("/get_video") |
| | | @ResponseBody |
| | | public void getVideo( |
| | | // HttpServletRequest request, |
| | | HttpServletResponse response, String id) { |
| | | if(StringUtils.isEmpty(id)){ |
| | | System.out.println("视频ID未提供"); |
| | | return; |
| | | } |
| | | //视频资源存储信息 |
| | | response.reset(); |
| | | //获取从那个字节开始读取文件 |
| | | // String rangeString = request.getHeader("Range"); |
| | | String rangeString = null; |
| | | |
| | | Rc_video_batch videoInfo = this.videoShowService.queryOneVideoInfo(id); |
| | | if(videoInfo == null){ |
| | | System.out.println("Rc_video_batch未查找到对象: " + id); |
| | | return; |
| | | } |
| | | String videoPath = videoInfo.getSrc_video_path(); |
| | | if(this.videoSimilarProperties.isTestMode()){ |
| | | // 测试模式,需要替换文件根路径为本机windows路径 |
| | | StringBuilder windowPath = new StringBuilder(this.videoSimilarProperties.getDataFolder()); |
| | | windowPath.append(videoInfo.getBatch_id()); |
| | | windowPath.append("/").append(id).append(".mp4"); |
| | | videoPath = windowPath.toString(); |
| | | } |
| | | |
| | | try { |
| | | //获取响应的输出流 |
| | | OutputStream outputStream = response.getOutputStream(); |
| | | // File file = new File("c:\\video.mp4"); |
| | | File file = new File(videoPath); |
| | | if(file.exists()){ |
| | | RandomAccessFile targetFile = new RandomAccessFile(file, "r"); |
| | | long fileLength = targetFile.length(); |
| | | //播放 |
| | | if(rangeString != null){ |
| | | long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-"))); |
| | | //设置内容类型 |
| | | response.setHeader("Content-Type", "video/mp4"); |
| | | //设置此次相应返回的数据长度 |
| | | response.setHeader("Content-Length", String.valueOf(fileLength - range)); |
| | | //设置此次相应返回的数据范围 |
| | | response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength); |
| | | //返回码需要为206,而不是200 |
| | | response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); |
| | | //设定文件读取开始位置(以字节为单位) |
| | | // targetFile.seek(range); |
| | | }else {//下载 |
| | | //设置响应头,把文件名字设置好 |
| | | response.setHeader("Content-Disposition", "attachment; filename=video.mp4" ); |
| | | //设置文件长度 |
| | | response.setHeader("Content-Length", String.valueOf(fileLength)); |
| | | //解决编码问题 |
| | | response.setHeader("Content-Type","application/octet-stream"); |
| | | } |
| | | |
| | | byte[] cache = new byte[1024 * 300]; |
| | | int flag; |
| | | while ((flag = targetFile.read(cache))!=-1){ |
| | | outputStream.write(cache, 0, flag); |
| | | } |
| | | }else { |
| | | String message = "file: not exists"; |
| | | //解决编码问题 |
| | | response.setHeader("Content-Type","application/json"); |
| | | outputStream.write(message.getBytes(StandardCharsets.UTF_8)); |
| | | } |
| | | |
| | | outputStream.flush(); |
| | | outputStream.close(); |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | logger.debug("开始启动批次查询:" + this.currentVideoSearchMeta.getBatchId()); |
| | | } |
| | | if(this.currentVideoSearchMeta == null){ |
| | | // 说明上次已经创建 videoSearchTask 任务,但没有返回有效任务记录 |
| | | return null; |
| | | } |
| | | |
| | | // |
| | | this.videoSearchTask.checkExecutor(this.currentVideoSearchMeta); |
| | | // |
| | | int result = this.videoSearchTask.executeOneSearch(); |
| | | int result = 0; |
| | | try{ |
| | | result = this.videoSearchTask.executeOneSearch(); |
| | | } catch (Exception ex){ |
| | | logger.error("executeOneSearch(): 执行异常:" + ex.getMessage(), ex); |
| | | result = -1; |
| | | } |
| | | |
| | | if(result == 0){ |
| | | return SUCCESS; |
| | |
| | | defaultSimilarExecutor.setVideoExecutorService(BeanContextAware.getBeanByType(VideoExecutorServiceImpl.class)); |
| | | defaultSimilarExecutor.setRestTemplate(BeanContextAware.getBeanByType(RestTemplate.class)); |
| | | defaultSimilarExecutor.startup(this.videoSimilarProperties.getDataFolder() |
| | | , videoSearchMeta.getBatchId(), this.videoSimilarProperties.getTopN(), true); |
| | | , videoSearchMeta.getBatchId(), this.videoSimilarProperties.getTopN(), this.videoSimilarProperties.isTestMode()); |
| | | this.similarExecutor = defaultSimilarExecutor; |
| | | } |
| | | |
New file |
| | |
| | | package com.iplatform.recvideo.service; |
| | | |
| | | import com.iplatform.model.po.Rc_video_batch; |
| | | import com.iplatform.model.po.Rc_video_t2; |
| | | import com.walker.db.page.GenericPager; |
| | | import com.walker.jdbc.service.BaseServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class VideoShowServiceImpl extends BaseServiceImpl { |
| | | |
| | | /** |
| | | * 返回部分原始视频集合,用于选择相似视频使用。 |
| | | * @return |
| | | */ |
| | | public GenericPager<Rc_video_batch> queryPageVideoBatchList(){ |
| | | return this.selectSplit("select * from rc_video_batch", new Object[]{}, 1, 128, new Rc_video_batch()); |
| | | } |
| | | |
| | | /** |
| | | * 返回给定原始视频,相似视频集合。 |
| | | * @param srcVideoId |
| | | * @return |
| | | */ |
| | | public List<Rc_video_t2> querySimilarVideoList(String srcVideoId){ |
| | | return this.select(new Rc_video_t2(), "where src_video_id=?", new Object[]{srcVideoId}); |
| | | } |
| | | |
| | | /** |
| | | * 根据原始视频ID,查询该视频信息。 |
| | | * @param srcVideoId |
| | | * @return |
| | | */ |
| | | public Rc_video_batch queryOneVideoInfo(String srcVideoId){ |
| | | return this.get(new Rc_video_batch(), "where src_video_id=?", new Object[]{srcVideoId}); |
| | | } |
| | | } |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>Title</title> |
| | | </head> |
| | | <body> |
| | | <p> </p> |
| | | |
| | | <table style="width: 90%;"> |
| | | <tr> |
| | | <td style="width: 20%; vertical-align: top;"><h4>选择源视频:${select_id}<br></h4></td> |
| | | <td style="width:10%;"></td> |
| | | <td style="vertical-align: top;"><h4>相似视频集合</h4></td> |
| | | </tr> |
| | | </table> |
| | | |
| | | <table style="width: 90%;"> |
| | | <tr> |
| | | <td style="width: 20%; vertical-align: top;"> |
| | | <table style="width: 90%;"> |
| | | <#list src_list as obj> |
| | | <tr> |
| | | <td> |
| | | <video id="my-video" class="video-js vjs-big-play-centered" controls="controls" poster="" width="320" height="180"> |
| | | <source src="/video_ui/get_video?id=${obj.src_video_id}" type='video/mp4'> |
| | | </video> |
| | | <br> ${obj.src_video_id} <a href="/video_ui/index?id=${obj.src_video_id}">检索相似</a> |
| | | <p> </p> |
| | | </td> |
| | | </tr> |
| | | </#list> |
| | | </table> |
| | | </td> |
| | | <td style="width:10%;"></td> |
| | | <td style="vertical-align: top;"> |
| | | <table style="width: 90%;"> |
| | | <#list similar_list as sim> |
| | | <tr> |
| | | <td> |
| | | <video id="my-video" class="video-js vjs-big-play-centered" controls="controls" poster="" width="320" height="180"> |
| | | <source src="/video_ui/get_video?id=${sim.sim_video_id}" type='video/mp4'> |
| | | </video> |
| | | <br> ${sim.sim_video_id} 得分: ${sim.score} |
| | | <p> </p> |
| | | </td> |
| | | </tr> |
| | | </#list> |
| | | </table> |
| | | </td> |
| | | </tr> |
| | | </table> |
| | | </body> |
| | | </html> |