登录上传 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);
/**
* 终端cos上传文件
*
* @param file
* @return
*/
@PostMapping(value = "/mobile/shop/oss/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
CommonResult uploadFile(@RequestPart(name = "upfile") MultipartFile file);

View File

@ -6,12 +6,14 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class VideoUtil {
private static final Logger logger = LoggerFactory.getLogger(VideoUtil.class);
public static List<String> videoAllowFiles = new ArrayList<String>() {{
add("flv");
add("swf");
@ -31,7 +33,6 @@ public class VideoUtil {
add("wav");
add("mid");
}};
private static Logger logger = LoggerFactory.getLogger(VideoUtil.class);
/**
* 得到语音或视频文件时长,单位秒 并格式化
@ -51,11 +52,43 @@ public class VideoUtil {
* @return 单位为毫秒
*/
public static long getMp4Duration(String videoPath) throws IOException {
IsoFile isoFile = new IsoFile(videoPath);
long lengthInSeconds =
isoFile.getMovieBox().getMovieHeaderBox().getDuration() /
isoFile.getMovieBox().getMovieHeaderBox().getTimescale();
return lengthInSeconds;
try {
IsoFile isoFile = new IsoFile(videoPath);
long lengthInSeconds =
isoFile.getMovieBox().getMovieHeaderBox().getDuration() /
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 ss = (temp % 3600) % 60;
return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : "" +
(mm < 10 ? ("0" + mm) : mm) + ":" +
return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : (mm < 10 ? ("0" + mm) : mm) + ":" +
(ss < 10 ? ("0" + ss) : ss);
}
}
@ -206,7 +238,7 @@ class InputStreamRunnable extends Thread {
public InputStreamRunnable(InputStream is, String _type) {
try {
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), "UTF-8"));
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), StandardCharsets.UTF_8));
type = _type;
} catch (Exception ex) {
ex.printStackTrace();

View File

@ -138,18 +138,39 @@
<version>1.5.6</version>
</dependency>
<!-- 引入常用windows和linux平台 其他平台用到时在引入 -->
<!-- JavaCV库 -->
<!-- JavaCV库 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.4-1.5.6</version>
<classifier>windows-x86_64</classifier>
<artifactId>javacv-platform</artifactId>
<version>1.5.6</version>
</dependency>
<!-- FFmpeg平台依赖 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version>
<classifier>linux-x86_64</classifier>
</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消息队列 -->
<dependency>
<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 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")) {
try {
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);
List<String> commonPrefixes = objectListing.getCommonPrefixes();
logger.info(JSONUtil.toJsonStr(commonPrefixes));
return commonPrefixes;
return commonPrefixes;
}
@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
* @return
*/

View File

@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -24,14 +25,7 @@ import java.util.concurrent.TimeUnit;
@Component
public class VideoUtil {
private static Logger logger = LoggerFactory.getLogger(VideoUtil.class);
@Value("${aliyun.oss.dir.prefix}")
private String ALIYUN_OSS_DIR_PREFIX;
@Autowired
private OssService ossService;
private static final Logger logger = LoggerFactory.getLogger(VideoUtil.class);
public static List<String> videoAllowFiles = new ArrayList<String>() {{
add("flv");
add("swf");
@ -51,6 +45,10 @@ public class VideoUtil {
// add("wav");
// 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 ss = (temp % 3600) % 60;
return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : "" +
(mm < 10 ? ("0" + mm) : mm) + ":" +
return hh != 0 ? ((hh < 10 ? ("0" + hh) : hh) + ":") : (mm < 10 ? ("0" + mm) : mm) + ":" +
(ss < 10 ? ("0" + ss) : ss);
}
@ -227,24 +224,40 @@ public class VideoUtil {
* @return
*/
public String getVideoCoverV2(String video, String dir, String uploadName) {
InputStream inputStream = OssUtils.urlToInputSteam(video);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
try {
grabber.start();
Frame frame = grabber.grabImage();
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.convert(frame);
Map map = OssUtils.toStreamMap(bufferedImage);
grabber.stop();
InputStream stream = (InputStream) map.get("stream");
Long file_size = Convert.toLong(map.get("file_size"));
InputStream inputStream = OssUtils.urlToInputSteam(video);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
try {
grabber.start();
Frame frame = grabber.grabImage();
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.convert(frame);
Map map = OssUtils.toStreamMap(bufferedImage);
grabber.stop();
InputStream stream = (InputStream) map.get("stream");
Long file_size = Convert.toLong(map.get("file_size"));
// 上传至oos返回文件地址
return ossService.uploadObject2OSS(null, ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(uploadName), stream, uploadName, file_size);
} catch (IOException e) {
logger.error("失败原因:", e);
// 上传至oos返回文件地址
return ossService.uploadObject2OSS(null, ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(uploadName), stream, uploadName, file_size);
} catch (IOException 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) {
try {
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), "UTF-8"));
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), StandardCharsets.UTF_8));
type = _type;
} catch (Exception ex) {
ex.printStackTrace();