Compare commits

...

13 Commits

Author SHA1 Message Date
bbeaea14c3 Bump commons-io from 1.4 to 2.7 in /office-plugin
Bumps commons-io from 1.4 to 2.7.

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-26 20:46:04 +00:00
2bb0dd545d Bump xstream from 1.4.15 to 1.4.16 in /server
Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.15 to 1.4.16.
- [Release notes](https://github.com/x-stream/xstream/releases)
- [Commits](https://github.com/x-stream/xstream/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-19 13:32:13 +08:00
ac2115114c 修正Redis服务器没有设置密码,但客户端向其发送身份验证请求的问题 2021-04-19 13:31:50 +08:00
831550d847 修正office.preview.switch.disabled引用了错误常量的问题 2021-04-19 13:31:50 +08:00
1fa7b4a911 修正区分大小写的文件系统中,文件后缀名为大写时,系统提示该文件类型不支持的问题 2021-04-19 13:31:50 +08:00
bcdb5ce0e6 集成视频格式转换功能1.0(基于javacv) 2021-04-19 13:29:25 +08:00
a3485dd9b7 Merge pull request #230 from gitchenjh/master
3.5.1版
2021-04-06 17:47:07 +08:00
5a28b89f46 3.5.1版 2021-04-06 16:45:18 +08:00
58b1b50c2e 修复:pdf.js 跨域问题 2021-04-06 16:44:40 +08:00
kl
8f75df15e2 修复 tif、tiff 文件预览初始内存太小预览失败的问题 2021-03-26 10:05:58 +08:00
9883d3b064 assembly打包区分windows和linux
assembly打包区分windows和linux
2021-03-19 09:47:16 +08:00
kl
e477ce7048 修复打包插件 2021-03-19 09:45:04 +08:00
0985aed0b0 assembly打包区分windows和linux,修复windows发行包启动报找不到找不到office组件 2021-03-19 09:41:01 +08:00
27 changed files with 452 additions and 26 deletions

View File

@ -28,5 +28,5 @@ ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
ENV LANG zh_CN.UTF-8
ENV LC_ALL zh_CN.UTF-8
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-3.5/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-3.5/config/application.properties","-jar","/opt/kkFileView-3.5/bin/kkFileView-3.5.jar"]
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-3.5.1/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-3.5.1/config/application.properties","-jar","/opt/kkFileView-3.5.1/bin/kkFileView-3.5.1.jar"]

View File

@ -7,7 +7,7 @@
<parent>
<artifactId>filepreview</artifactId>
<groupId>cn.keking</groupId>
<version>3.5</version>
<version>3.5.1</version>
</parent>
<artifactId>office-plugin</artifactId>
@ -24,7 +24,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>

View File

@ -6,7 +6,7 @@
<groupId>cn.keking</groupId>
<artifactId>filepreview</artifactId>
<version>3.5</version>
<version>3.5.1</version>
<properties>
<java.version>1.8</java.version>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>filepreview</artifactId>
<groupId>cn.keking</groupId>
<version>3.5</version>
<version>3.5.1</version>
</parent>
<artifactId>kkFileView</artifactId>
@ -149,7 +149,7 @@
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.15</version>
<version>1.4.16</version>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
@ -192,6 +192,64 @@
<artifactId>galimatias</artifactId>
<version>0.2.1</version>
</dependency>
<!-- 以下是bytedeco 基于opencv ffmpeg封装的javacv用于视频处理 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.2</version>
</dependency>
<!-- 此版本中主要兼容linux和windows系统如需兼容其他系统平台请引入对应依赖即可 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>opencv</artifactId>
<version>4.1.2-1.5.2</version>
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>opencv</artifactId>
<version>4.1.2-1.5.2</version>
<classifier>windows-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas</artifactId>
<version>0.3.6-1.5.1</version>
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas</artifactId>
<version>0.3.6-1.5.1</version>
<classifier>windows-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.2.1-1.5.2</version>
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.2.1-1.5.2</version>
<classifier>windows-x86_64</classifier>
</dependency>
</dependencies>
<build>
@ -229,7 +287,8 @@
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
<descriptor>src/main/assembly/dist-win32.xml</descriptor>
<descriptor>src/main/assembly/dist-linux.xml</descriptor>
</descriptors>
</configuration>
<executions>

View File

@ -36,7 +36,7 @@
</fileSet>
<fileSet>
<directory>../office-plugin/windows-office</directory>
<outputDirectory>${file.separator}office</outputDirectory>
<outputDirectory>${file.separator}windows-office</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>make-assembly</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/bin</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
<includes>
<include>*.sh</include>
</includes>
<fileMode>755</fileMode>
<lineEnding>unix</lineEnding>
</fileSet>
<fileSet>
<directory>src/main/config</directory>
<outputDirectory>${file.separator}config</outputDirectory>
<lineEnding>unix</lineEnding>
</fileSet>
<fileSet>
<directory>src/main/log</directory>
<outputDirectory>${file.separator}log</outputDirectory>
<lineEnding>unix</lineEnding>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>make-assembly</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/bin</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
<includes>
<include>*.bat</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/config</directory>
<outputDirectory>${file.separator}config</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/log</directory>
<outputDirectory>${file.separator}log</outputDirectory>
</fileSet>
<fileSet>
<directory>../office-plugin/windows-office</directory>
<outputDirectory>${file.separator}windows-office</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@ -6,4 +6,4 @@ echo Starting kkFileView...
echo Please check log file in ../log/kkFileView.log for more information
echo You can get help in our official homesite: https://kkFileView.keking.cn
echo If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers
java -Dspring.config.location=..\config\application.properties -jar kkFileView-3.5.jar -> ..\log\kkFileView.log
java -Dspring.config.location=..\config\application.properties -jar kkFileView-3.5.1.jar -> ..\log\kkFileView.log

View File

@ -29,4 +29,4 @@ echo "Starting kkFileView..."
echo "Please execute ./showlog.sh to check log for more information"
echo "You can get help in our official homesite: https://kkFileView.keking.cn"
echo "If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers"
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar kkFileView-3.5.jar > ../log/kkFileView.log 2>&1 &
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar kkFileView-3.5.1.jar > ../log/kkFileView.log 2>&1 &

View File

@ -33,7 +33,7 @@ office.home = ${KK_OFFICE_HOME:default}
cache.type = ${KK_CACHE_TYPE:jdk}
#redis连接只有当cache.type = redis时才有用
spring.redisson.address = ${KK_SPRING_REDISSON_ADDRESS:127.0.0.1:6379}
spring.redisson.password = ${KK_SPRING_REDISSON_PASSWORD:123456}
spring.redisson.password = ${KK_SPRING_REDISSON_PASSWORD:}
#缓存是否自动清理 true 为开启注释掉或其他值都为关闭
cache.clean.enabled = ${KK_CACHE_CLEAN_ENABLED:true}
#缓存自动清理时间cache.clean.enabled = true时才有用cron表达式基于Quartz cron
@ -55,6 +55,11 @@ cache.enabled = ${KK_CACHE_ENABLED:true}
simText = ${KK_SIMTEXT:txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd}
#多媒体类型默认如下可自定义添加
media = ${KK_MEDIA:mp3,wav,mp4,flv}
#是否开启多媒体类型转视频格式转换,目前可转换视频格式有avi,mov,wmv,3gp,rm
#请谨慎开启此功能建议异步调用添加到处理队列并且增加任务队列处理线程防止视频转换占用完线程资源转换比较耗费时间,并且控制了只能串行处理转换任务
media.convert.disable = ${KK_MEDIA_CONVERT_DISABLE:false}
#支持转换的视频类型
convertMedias = ${KK_CONVERTMEDIAS:avi,mov,wmv,mkv,3gp,rm}
#office类型文档(word ppt)样式默认为图片(image)可配置为pdf预览时也有按钮切换
office.preview.type = ${KK_OFFICE_PREVIEW_TYPE:image}
#是否关闭office预览切换开关默认为false可配置为true关闭

View File

@ -1,5 +1,6 @@
[#ftl]
[#-- @implicitly included --]
[#-- @ftlvariable name="initializeMemorySize" type="java.lang.Number" --]
[#-- @ftlvariable name="currentUrl" type="java.lang.String" --]
[#-- @ftlvariable name="file" type="cn.keking.model.FileAttribute" --]
[#-- @ftlvariable name="fileName" type="java.lang.String" --]

View File

@ -24,6 +24,8 @@ public class ConfigConstants {
private static Boolean cacheEnabled;
private static String[] simTexts = {};
private static String[] medias = {};
private static String[] convertMedias = {};
private static String mediaConvertDisable;
private static String officePreviewType;
private static String officePreviewSwitchDisabled;
private static String ftpUsername;
@ -89,6 +91,33 @@ public class ConfigConstants {
ConfigConstants.medias = Media;
}
public static String[] getConvertMedias() {
return convertMedias;
}
@Value("${convertMedias:avi,mov,wmv,mkv,3gp,rm}")
public void setConvertMedias(String convertMedia) {
String[] mediaArr = convertMedia.split(",");
setConvertMediaValue(mediaArr);
}
public static void setConvertMediaValue(String[] ConvertMedia) {
ConfigConstants.convertMedias = ConvertMedia;
}
public static String getMediaConvertDisable() {
return mediaConvertDisable;
}
@Value("${media.convert.disable:true}")
public void setMediaConvertDisable(String mediaConvertDisable) {
setMediaConvertDisableValue(mediaConvertDisable);
}
public static void setMediaConvertDisableValue(String mediaConvertDisable) {
ConfigConstants.mediaConvertDisable = mediaConvertDisable;
}
public static String getOfficePreviewType() {
return officePreviewType;
}

View File

@ -57,7 +57,7 @@ public class ConfigRefreshComponent {
text = properties.getProperty("simText", ConfigConstants.DEFAULT_TXT_TYPE);
media = properties.getProperty("media", ConfigConstants.DEFAULT_MEDIA_TYPE);
officePreviewType = properties.getProperty("office.preview.type", ConfigConstants.DEFAULT_OFFICE_PREVIEW_TYPE);
officePreviewSwitchDisabled = properties.getProperty("office.preview.switch.disabled", ConfigConstants.DEFAULT_OFFICE_PREVIEW_TYPE);
officePreviewSwitchDisabled = properties.getProperty("office.preview.switch.disabled", ConfigConstants.DEFAULT_OFFICE_PREVIEW_SWITCH_DISABLED);
ftpUsername = properties.getProperty("ftp.username", ConfigConstants.DEFAULT_FTP_USERNAME);
ftpPassword = properties.getProperty("ftp.password", ConfigConstants.DEFAULT_FTP_PASSWORD);
ftpControlEncoding = properties.getProperty("ftp.control.encoding", ConfigConstants.DEFAULT_FTP_CONTROL_ENCODING);

View File

@ -1,6 +1,7 @@
package cn.keking.config;
import io.netty.channel.nio.NioEventLoopGroup;
import org.apache.commons.lang3.StringUtils;
import org.redisson.client.codec.Codec;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ -63,7 +64,7 @@ public class RedissonConfig {
.setConnectTimeout(connectTimeout)
.setIdleConnectionTimeout(idleConnectionTimeout)
.setPingTimeout(pingTimeout)
.setPassword(password);
.setPassword(StringUtils.trimToNull(password));
Codec codec=(Codec) ClassUtils.forName(getCodec(), ClassUtils.getDefaultClassLoader()).newInstance();
config.setCodec(codec);
config.setThreads(thread);

View File

@ -33,6 +33,7 @@ public enum FileType {
private static final String[] SSIM_TEXT_TYPES = ConfigConstants.getSimText();
private static final String[] CODES = {"java", "c", "php", "go", "python", "py", "js", "html", "ftl", "css", "lua", "sh", "rb", "yml", "json", "h", "cpp", "cs", "aspx", "jsp"};
private static final String[] MEDIA_TYPES = ConfigConstants.getMedia();
public static final String[] MEDIA_TYPES_CONVERT = ConfigConstants.getConvertMedias();
private static final Map<String, FileType> FILE_TYPE_MAPPER = new HashMap<>();
static {
@ -51,6 +52,9 @@ public enum FileType {
for (String media : MEDIA_TYPES) {
FILE_TYPE_MAPPER.put(media, FileType.MEDIA);
}
for (String media : MEDIA_TYPES_CONVERT) {
FILE_TYPE_MAPPER.put(media, FileType.MEDIA);
}
for (String tif : TIFF_TYPES) {
FILE_TYPE_MAPPER.put(tif, FileType.TIFF);
}

View File

@ -286,4 +286,27 @@ public class FileHandlerService {
}
return attribute;
}
/**
* @return 已转换过的视频文件集合(缓存)
*/
public Map<String, String> listConvertedMedias() {
return cacheService.getMediaConvertCache();
}
/**
* 添加转换后的视频文件缓存
* @param fileName
* @param value
*/
public void addConvertedMedias(String fileName, String value) {
cacheService.putMediaConvertCache(fileName, value);
}
/**
* @return 已转换视频文件缓存,根据文件名获取
*/
public String getConvertedMedias(String key) {
return cacheService.getMediaConvertCache(key);
}
}

View File

@ -12,15 +12,18 @@ public interface CacheService {
String FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
String FILE_PREVIEW_IMGS_KEY = "converted-preview-imgs-file";//压缩包内图片文件集合
String FILE_PREVIEW_PDF_IMGS_KEY = "converted-preview-pdfimgs-file";
String FILE_PREVIEW_MEDIA_CONVERT_KEY = "converted-preview-media-file";
String TASK_QUEUE_NAME = "convert-task";
Integer DEFAULT_PDF_CAPACITY = 500000;
Integer DEFAULT_IMG_CAPACITY = 500000;
Integer DEFAULT_PDFIMG_CAPACITY = 500000;
Integer DEFAULT_MEDIACONVERT_CAPACITY = 500000;
void initPDFCachePool(Integer capacity);
void initIMGCachePool(Integer capacity);
void initPdfImagesCachePool(Integer capacity);
void initMediaConvertCachePool(Integer capacity);
void putPDFCache(String key, String value);
void putImgCache(String key, List<String> value);
Map<String, String> getPDFCache();
@ -29,6 +32,9 @@ public interface CacheService {
List<String> getImgCache(String key);
Integer getPdfImageCache(String key);
void putPdfImageCache(String pdfFilePath, int num);
Map<String, String> getMediaConvertCache();
void putMediaConvertCache(String key, String value);
String getMediaConvertCache(String key);
void cleanCache();
void addQueueTask(String url);
String takeQueueTask() throws InterruptedException;

View File

@ -26,6 +26,7 @@ public class CacheServiceJDKImpl implements CacheService {
private Map<String, String> pdfCache;
private Map<String, List<String>> imgCache;
private Map<String, Integer> pdfImagesCache;
private Map<String, String> mediaConvertCache;
private static final int QUEUE_SIZE = 500000;
private final BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(QUEUE_SIZE);
@ -34,6 +35,7 @@ public class CacheServiceJDKImpl implements CacheService {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
initIMGCachePool(CacheService.DEFAULT_IMG_CAPACITY);
initPdfImagesCachePool(CacheService.DEFAULT_PDFIMG_CAPACITY);
initMediaConvertCachePool(CacheService.DEFAULT_MEDIACONVERT_CAPACITY);
}
@Override
@ -79,6 +81,21 @@ public class CacheServiceJDKImpl implements CacheService {
pdfImagesCache.put(pdfFilePath, num);
}
@Override
public Map<String, String> getMediaConvertCache() {
return mediaConvertCache;
}
@Override
public void putMediaConvertCache(String key, String value) {
mediaConvertCache.put(key, value);
}
@Override
public String getMediaConvertCache(String key) {
return mediaConvertCache.get(key);
}
@Override
public void cleanCache() {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
@ -116,4 +133,12 @@ public class CacheServiceJDKImpl implements CacheService {
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void initMediaConvertCachePool(Integer capacity) {
mediaConvertCache = new ConcurrentLinkedHashMap.Builder<String, String>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
}

View File

@ -34,6 +34,11 @@ public class CacheServiceRedisImpl implements CacheService {
@Override
public void initPdfImagesCachePool(Integer capacity) { }
@Override
public void initMediaConvertCachePool(Integer capacity) {
}
@Override
public void putPDFCache(String key, String value) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(FILE_PREVIEW_PDF_KEY);
@ -80,6 +85,23 @@ public class CacheServiceRedisImpl implements CacheService {
convertedList.fastPut(pdfFilePath, num);
}
@Override
public Map<String, String> getMediaConvertCache() {
return redissonClient.getMapCache(FILE_PREVIEW_MEDIA_CONVERT_KEY);
}
@Override
public void putMediaConvertCache(String key, String value) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(FILE_PREVIEW_MEDIA_CONVERT_KEY);
convertedList.fastPut(key, value);
}
@Override
public String getMediaConvertCache(String key) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(FILE_PREVIEW_MEDIA_CONVERT_KEY);
return convertedList.get(key);
}
@Override
public void cleanCache() {
cleanPdfCache();

View File

@ -73,6 +73,11 @@ public class CacheServiceRocksDBImpl implements CacheService {
}
@Override
public void initMediaConvertCachePool(Integer capacity) {
}
@Override
public void putPDFCache(String key, String value) {
try {
@ -171,6 +176,40 @@ public class CacheServiceRocksDBImpl implements CacheService {
}
}
@Override
public Map<String, String> getMediaConvertCache() {
Map<String, String> result = new HashMap<>();
try{
result = (Map<String, String>) toObject(db.get(FILE_PREVIEW_MEDIA_CONVERT_KEY.getBytes()));
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public void putMediaConvertCache(String key, String value) {
try {
Map<String, String> mediaConvertCacheItem = getMediaConvertCache();
mediaConvertCacheItem.put(key, value);
db.put(FILE_PREVIEW_MEDIA_CONVERT_KEY.getBytes(), toByteArray(mediaConvertCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public String getMediaConvertCache(String key) {
String result = "";
try{
Map<String, String> map = (Map<String, String>) toObject(db.get(FILE_PREVIEW_MEDIA_CONVERT_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public void cleanCache() {
try {

View File

@ -1,13 +1,21 @@
package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.FileType;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.service.FileHandlerService;
import cn.keking.web.filter.BaseUrlFilter;
import org.artofsolving.jodconverter.util.ConfigUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import java.io.File;
/**
* @author : kl
@ -21,6 +29,8 @@ public class MediaFilePreviewImpl implements FilePreview {
private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
private static Object LOCK=new Object();
public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview;
@ -34,14 +44,123 @@ public class MediaFilePreviewImpl implements FilePreview {
if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
} else {
model.addAttribute("mediaUrl", BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent()));
url=BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent());
fileAttribute.setUrl(url);
}
} else {
model.addAttribute("mediaUrl", url);
}
if(checkNeedConvert(fileAttribute.getSuffix())){
url=convertUrl(fileAttribute);
}else{
//正常media类型
String[] medias = ConfigConstants.getMedia();
for(String media:medias){
if(media.equals(fileAttribute.getSuffix())){
model.addAttribute("mediaUrl", url);
return MEDIA_FILE_PREVIEW_PAGE;
}
}
return otherFilePreview.notSupportedFile(model, fileAttribute, "暂不支持");
}
model.addAttribute("mediaUrl", url);
return MEDIA_FILE_PREVIEW_PAGE;
}
/**
* 检查视频文件处理逻辑
* 返回处理过后的url
* @return url
*/
private String convertUrl(FileAttribute fileAttribute) {
String url = fileAttribute.getUrl();
if(fileHandlerService.listConvertedMedias().containsKey(url)){
url= fileHandlerService.getConvertedMedias(url);
}else{
if(!fileHandlerService.listConvertedMedias().containsKey(url)){
synchronized(LOCK){
if(!fileHandlerService.listConvertedMedias().containsKey(url)){
String convertedUrl=convertToMp4(fileAttribute);
//加入缓存
fileHandlerService.addConvertedMedias(url,convertedUrl);
url=convertedUrl;
}
}
}
}
return url;
}
/**
* 检查视频文件转换是否已开启,以及当前文件是否需要转换
* @return
*/
private boolean checkNeedConvert(String suffix) {
//1.检查开关是否开启
if("false".equals(ConfigConstants.getMediaConvertDisable())){
return false;
}
//2.检查当前文件是否需要转换
String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
String type = suffix;
for(String temp : mediaTypesConvert){
if(type.equals(temp)){
return true;
}
}
return false;
}
/**
* 将浏览器不兼容视频格式转换成MP4
* @param fileAttribute
* @return
*/
private static String convertToMp4(FileAttribute fileAttribute) {
//说明:这里做临时处理,取上传文件的目录
String homePath = ConfigUtils.getHomePath();
String filePath = homePath+File.separator+"file"+File.separator+"demo"+File.separator+fileAttribute.getName();
String convertFileName=fileAttribute.getUrl().replace(fileAttribute.getSuffix(),"mp4");
File file=new File(filePath);
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
String fileName = null;
Frame captured_frame = null;
FFmpegFrameRecorder recorder = null;
try {
fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4");
File desFile=new File(fileName);
//判断一下防止穿透缓存
if(desFile.exists()){
return fileName;
}
frameGrabber.start();
recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264  //AV_CODEC_ID_MPEG4
recorder.setFormat("mp4");
recorder.setFrameRate(frameGrabber.getFrameRate());
//recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
recorder.setSampleRate(frameGrabber.getSampleRate());
recorder.setAudioChannels(frameGrabber.getAudioChannels());
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.start();
while ((captured_frame = frameGrabber.grabFrame()) != null) {
try {
recorder.setTimestamp(frameGrabber.getTimestamp());
recorder.record(captured_frame);
} catch (Exception e) {
}
}
recorder.stop();
recorder.release();
frameGrabber.stop();
} catch (Exception e) {
e.printStackTrace();
}
//是否删除源文件
//file.delete();
return convertFileName;
}
}

View File

@ -2,8 +2,10 @@ package cn.keking.service.impl;
import cn.keking.model.FileAttribute;
import cn.keking.service.FilePreview;
import cn.keking.utils.WebUtils;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
/**
* tiff 图片文件处理
@ -14,6 +16,9 @@ import org.springframework.ui.Model;
public class TiffFilePreviewImpl implements FilePreview {
private final PictureFilePreviewImpl pictureFilePreview;
private static final String INITIALIZE_MEMORY_SIZE = "initializeMemorySize";
//默认初始化 50MB 内存
private static final long INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT = 1024L * 1024 * 50;
public TiffFilePreviewImpl(PictureFilePreviewImpl pictureFilePreview) {
this.pictureFilePreview = pictureFilePreview;
@ -22,6 +27,12 @@ public class TiffFilePreviewImpl implements FilePreview {
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
pictureFilePreview.filePreviewHandle(url,model,fileAttribute);
String fileSize = WebUtils.getUrlParameterReg(url,INITIALIZE_MEMORY_SIZE);
if(StringUtils.hasText(fileSize)){
model.addAttribute(INITIALIZE_MEMORY_SIZE,fileSize);
}else {
model.addAttribute(INITIALIZE_MEMORY_SIZE,Long.toString(INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT));
}
return TIFF_FILE_PREVIEW_PAGE;
}
}

View File

@ -93,7 +93,7 @@ public class KkFileUtils {
* @return 文件后缀
*/
public static String suffixFromFileName(String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
}

View File

@ -30,8 +30,6 @@ public class FilterConfiguration {
Set<String> filterUri = new HashSet<>();
filterUri.add("/onlinePreview");
filterUri.add("/picturesPreview");
filterUri.add("/getCorsFile");
filterUri.add("/addTask");
TrustHostFilter filter = new TrustHostFilter();
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter);

View File

@ -2019,7 +2019,7 @@ var validateFileURL;
{
var HOSTED_VIEWER_ORIGINS = ["null", "http://mozilla.github.io", "https://mozilla.github.io"];
validateFileURL = function validateFileURL(file, base) {
validateFileURL = function validateFileURL(file) {
if (file === undefined) {
return;
}
@ -2036,7 +2036,7 @@ var validateFileURL;
protocol = _ref11.protocol;
if (origin !== viewerOrigin && protocol !== "blob:") {
return (base.endsWith('/') ? base : base + '/') + 'getCorsFile?urlPath=' + encodeURIComponent(file);
throw new Error("file origin does not match viewer's");
}
} catch (ex) {
var message = ex && ex.message;
@ -2089,14 +2089,12 @@ function loadAndEnablePDFBug(enabledTabs) {
function webViewerInitialized() {
var appConfig = PDFViewerApplication.appConfig;
var file;
var base;
var disableDownload;
var queryString = document.location.search.substring(1);
var params = (0, _ui_utils.parseQueryString)(queryString);
file = "file" in params ? params.file : _app_options.AppOptions.get("defaultUrl");
base = 'base' in params ? params.base : appConfig.defaultUrl;
disableDownload = 'disabledownload' in params ? params.disabledownload : 'false';
validateFileURL(file, base);
validateFileURL(file);
var fileInput = document.createElement("input");
fileInput.id = appConfig.openFileInputName;
fileInput.className = "fileInput";

View File

@ -21,7 +21,12 @@
</#if>
</body>
<script type="text/javascript">
document.getElementsByTagName('iframe')[0].src = "${baseUrl}pdfjs/web/viewer.html?base=${baseUrl}&file=" + encodeURIComponent('${finalUrl}') + "&disabledownload=${pdfDownloadDisable}";
var url = '${finalUrl}';
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
if (!url.startsWith(baseUrl)) {
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(url);
}
document.getElementsByTagName('iframe')[0].src = "${baseUrl}pdfjs/web/viewer.html?file=" + encodeURIComponent(url) + "&disabledownload=${pdfDownloadDisable}";
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
/**
* 页面变化调整高度

View File

@ -30,6 +30,9 @@
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.open('GET', $("#currentUrl").val());
var config = {};
config.TOTAL_MEMORY = ${initializeMemorySize};
Tiff.initialize(config)
xhr.onload = function (e) {
var tiff = new Tiff({buffer: xhr.response});
var canvas = tiff.toCanvas();