登录上传 mov 文件异常的问题

This commit is contained in:
Jack 2025-09-04 17:21:19 +08:00
parent 2156332b34
commit cbbe21f1b8
5 changed files with 120 additions and 44 deletions

View File

@ -311,6 +311,12 @@ public interface ShopService {
boolean lklPayNotifyUpdateShopOrderLkl(@RequestBody JSONObject lklPayNotifyDataJson); boolean lklPayNotifyUpdateShopOrderLkl(@RequestBody JSONObject lklPayNotifyDataJson);
/**
* 终端cos上传文件
*
* @param file
* @return
*/
@PostMapping(value = "/mobile/shop/oss/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/mobile/shop/oss/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
CommonResult uploadFile(@RequestPart(name = "upfile") MultipartFile file); CommonResult uploadFile(@RequestPart(name = "upfile") MultipartFile file);

View File

@ -6,12 +6,14 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class VideoUtil { public class VideoUtil {
private static final Logger logger = LoggerFactory.getLogger(VideoUtil.class);
public static List<String> videoAllowFiles = new ArrayList<String>() {{ public static List<String> videoAllowFiles = new ArrayList<String>() {{
add("flv"); add("flv");
add("swf"); add("swf");
@ -31,7 +33,6 @@ public class VideoUtil {
add("wav"); add("wav");
add("mid"); add("mid");
}}; }};
private static Logger logger = LoggerFactory.getLogger(VideoUtil.class);
/** /**
* 得到语音或视频文件时长,单位秒 并格式化 * 得到语音或视频文件时长,单位秒 并格式化
@ -51,11 +52,43 @@ public class VideoUtil {
* @return 单位为毫秒 * @return 单位为毫秒
*/ */
public static long getMp4Duration(String videoPath) throws IOException { public static long getMp4Duration(String videoPath) throws IOException {
IsoFile isoFile = new IsoFile(videoPath); try {
long lengthInSeconds = IsoFile isoFile = new IsoFile(videoPath);
isoFile.getMovieBox().getMovieHeaderBox().getDuration() / long lengthInSeconds =
isoFile.getMovieBox().getMovieHeaderBox().getTimescale(); isoFile.getMovieBox().getMovieHeaderBox().getDuration() /
return lengthInSeconds; isoFile.getMovieBox().getMovieHeaderBox().getTimescale();
return lengthInSeconds;
} catch (Exception e) {
// 处理 MOV 文件可能存在的解析问题尝试使用 FFmpeg 获取时长
logger.warn("无法通过 IsoFile 解析视频文件时长: {}, 尝试使用 FFmpeg", videoPath);
try {
return getDurationWithFFmpeg(videoPath);
} catch (Exception ffmpegException) {
logger.error("FFmpeg 也无法解析视频文件时长: {}", videoPath);
throw new IOException("无法解析视频文件: " + videoPath, e);
}
}
}
/**
* 使用 FFmpeg 获取视频时长备用方法
*
* @param videoPath
* @return 单位为毫秒
* @throws IOException
* @throws InterruptedException
*/
private static long getDurationWithFFmpeg(String videoPath) throws IOException, InterruptedException {
String command = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 " + videoPath;
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String result = reader.readLine();
process.waitFor();
if (result != null) {
// ffprobe 返回的是秒数需要转换为毫秒
return (long) (Double.parseDouble(result) * 1000);
}
throw new IOException("无法获取视频时长");
} }
@ -194,8 +227,7 @@ public class VideoUtil {
int mm = (temp % 3600) / 60; int mm = (temp % 3600) / 60;
int ss = (temp % 3600) % 60; int ss = (temp % 3600) % 60;
return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : "" + return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : (mm < 10 ? ("0" + mm) : mm) + ":" +
(mm < 10 ? ("0" + mm) : mm) + ":" +
(ss < 10 ? ("0" + ss) : ss); (ss < 10 ? ("0" + ss) : ss);
} }
} }
@ -206,7 +238,7 @@ class InputStreamRunnable extends Thread {
public InputStreamRunnable(InputStream is, String _type) { public InputStreamRunnable(InputStream is, String _type) {
try { try {
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), "UTF-8")); bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), StandardCharsets.UTF_8));
type = _type; type = _type;
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();

View File

@ -138,18 +138,39 @@
<version>1.5.6</version> <version>1.5.6</version>
</dependency> </dependency>
<!-- 引入常用windows和linux平台 其他平台用到时在引入 --> <!-- 引入常用windows和linux平台 其他平台用到时在引入 -->
<!-- JavaCV库 -->
<!-- JavaCV库 -->
<dependency> <dependency>
<groupId>org.bytedeco</groupId> <groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId> <artifactId>javacv-platform</artifactId>
<version>4.4-1.5.6</version> <version>1.5.6</version>
<classifier>windows-x86_64</classifier>
</dependency> </dependency>
<!-- FFmpeg平台依赖 -->
<dependency> <dependency>
<groupId>org.bytedeco</groupId> <groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId> <artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version> <version>4.4-1.5.6</version>
<classifier>linux-x86_64</classifier>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>ffmpeg</artifactId>-->
<!-- <version>4.4-1.5.6</version>-->
<!-- <classifier>windows-x86_64</classifier>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>ffmpeg</artifactId>-->
<!-- <version>4.4-1.5.6</version>-->
<!-- <classifier>linux-x86_64</classifier>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; 添加 macOS 平台支持 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>ffmpeg</artifactId>-->
<!-- <version>4.4-1.5.6</version>-->
<!-- <classifier>macosx-x86_64</classifier>-->
<!-- </dependency>-->
<!-- rabbitMQ消息队列 --> <!-- rabbitMQ消息队列 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -212,7 +212,12 @@ public class OssServiceImpl implements OssService {
String cover_upname = uploadName.replace("." + VideoUtil.getVideoFormat(uploadName), ".jpg"); String cover_upname = uploadName.replace("." + VideoUtil.getVideoFormat(uploadName), ".jpg");
String floder = ALIYUN_OSS_DIR_PREFIX.concat("/") + dir + "/video/frame1/"; String floder = ALIYUN_OSS_DIR_PREFIX.concat("/") + dir + "/video/frame1/";
thumb_file_url = videoUtil.getVideoCoverV2(ossUrl, floder, cover_upname); try {
thumb_file_url = videoUtil.getVideoCoverV2(ossUrl, floder, cover_upname);
} catch (Exception e) {
logger.error("获取视频封面失败: ", e);
thumb_file_url = "";
}
/*if (VideoUtil.getVideoCover(uploadPath, cover_path, 1, "375*667")) { /*if (VideoUtil.getVideoCover(uploadPath, cover_path, 1, "375*667")) {
try { try {
thumb_file_url = uploadObject2OSS(new File(cover_path), ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(cover_upname), null, null, null); thumb_file_url = uploadObject2OSS(new File(cover_path), ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(cover_upname), null, null, null);
@ -580,7 +585,7 @@ public class OssServiceImpl implements OssService {
ObjectListing objectListing = ossCli.listObjects(listObjectsRequest); ObjectListing objectListing = ossCli.listObjects(listObjectsRequest);
List<String> commonPrefixes = objectListing.getCommonPrefixes(); List<String> commonPrefixes = objectListing.getCommonPrefixes();
logger.info(JSONUtil.toJsonStr(commonPrefixes)); logger.info(JSONUtil.toJsonStr(commonPrefixes));
return commonPrefixes; return commonPrefixes;
} }
@Override @Override
@ -632,8 +637,7 @@ public class OssServiceImpl implements OssService {
} }
/** /**
* * @param ossFolder 如folder/example.txt
* @param ossFolder 如folder/example.txt
* @param localFolder /path/to/local/example.txt * @param localFolder /path/to/local/example.txt
* @return * @return
*/ */

View File

@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -24,14 +25,7 @@ import java.util.concurrent.TimeUnit;
@Component @Component
public class VideoUtil { public class VideoUtil {
private static Logger logger = LoggerFactory.getLogger(VideoUtil.class); private static final Logger logger = LoggerFactory.getLogger(VideoUtil.class);
@Value("${aliyun.oss.dir.prefix}")
private String ALIYUN_OSS_DIR_PREFIX;
@Autowired
private OssService ossService;
public static List<String> videoAllowFiles = new ArrayList<String>() {{ public static List<String> videoAllowFiles = new ArrayList<String>() {{
add("flv"); add("flv");
add("swf"); add("swf");
@ -51,6 +45,10 @@ public class VideoUtil {
// add("wav"); // add("wav");
// add("mid"); // add("mid");
}}; }};
@Value("${aliyun.oss.dir.prefix}")
private String ALIYUN_OSS_DIR_PREFIX;
@Autowired
private OssService ossService;
/** /**
* 得到语音或视频文件时长,单位秒 并格式化 * 得到语音或视频文件时长,单位秒 并格式化
@ -213,8 +211,7 @@ public class VideoUtil {
int mm = (temp % 3600) / 60; int mm = (temp % 3600) / 60;
int ss = (temp % 3600) % 60; int ss = (temp % 3600) % 60;
return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : "" + return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : (mm < 10 ? ("0" + mm) : mm) + ":" +
(mm < 10 ? ("0" + mm) : mm) + ":" +
(ss < 10 ? ("0" + ss) : ss); (ss < 10 ? ("0" + ss) : ss);
} }
@ -227,24 +224,40 @@ public class VideoUtil {
* @return * @return
*/ */
public String getVideoCoverV2(String video, String dir, String uploadName) { public String getVideoCoverV2(String video, String dir, String uploadName) {
InputStream inputStream = OssUtils.urlToInputSteam(video);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
try { try {
grabber.start(); InputStream inputStream = OssUtils.urlToInputSteam(video);
Frame frame = grabber.grabImage(); FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
Java2DFrameConverter converter = new Java2DFrameConverter(); try {
BufferedImage bufferedImage = converter.convert(frame); grabber.start();
Map map = OssUtils.toStreamMap(bufferedImage); Frame frame = grabber.grabImage();
grabber.stop(); Java2DFrameConverter converter = new Java2DFrameConverter();
InputStream stream = (InputStream) map.get("stream"); BufferedImage bufferedImage = converter.convert(frame);
Long file_size = Convert.toLong(map.get("file_size")); Map map = OssUtils.toStreamMap(bufferedImage);
grabber.stop();
InputStream stream = (InputStream) map.get("stream");
Long file_size = Convert.toLong(map.get("file_size"));
// 上传至oos返回文件地址 // 上传至oos返回文件地址
return ossService.uploadObject2OSS(null, ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(uploadName), stream, uploadName, file_size); return ossService.uploadObject2OSS(null, ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(uploadName), stream, uploadName, file_size);
} catch (IOException e) { } catch (IOException e) {
logger.error("失败原因:", e); logger.error("处理视频封面失败:", e);
} finally {
try {
if (grabber != null) {
grabber.stop();
}
} catch (Exception e) {
logger.warn("关闭视频抓取器失败:", e);
}
}
} catch (UnsatisfiedLinkError e) {
logger.error("JavaCV本地库加载失败请检查平台依赖配置", e);
} catch (NoClassDefFoundError e) {
logger.error("JavaCV类初始化失败请检查依赖配置", e);
} catch (Exception e) {
logger.error("获取视频封面时发生未知异常:", e);
} }
return null; return "";
} }
} }
@ -255,7 +268,7 @@ class InputStreamRunnable extends Thread {
public InputStreamRunnable(InputStream is, String _type) { public InputStreamRunnable(InputStream is, String _type) {
try { try {
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), "UTF-8")); bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), StandardCharsets.UTF_8));
type = _type; type = _type;
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();