视频截取第一帧

朴灿烈づ我的快乐病毒、 2023-01-17 12:58 283阅读 0赞

前言

网上视频截取第一帧的案例还是比较多的,普遍的方法主要是使用ffmpeg 对其截取。在实践过程中,发现window 截取成功。但linux 环境中截取失败,对于失败原因这里将失败内容贴出来,供他人查看失败原因

  1. #
  2. # A fatal error has been detected by the Java Runtime Environment:
  3. #
  4. # SIGSEGV (0xb) at pc=0x000000000000d1f6, pid=14, tid=0x00007fe8b67e6b10
  5. #
  6. # JRE version: OpenJDK Runtime Environment (8.0_212-b04) (build 1.8.0_212-b04)
  7. # Java VM: OpenJDK 64-Bit Server VM (25.212-b04 mixed mode linux-amd64 compressed oops)
  8. # Derivative: IcedTea 3.12.0
  9. # Distribution: Custom build (Sat May 4 17:33:35 UTC 2019)
  10. # Problematic frame:
  11. # C 0x000000000000d1f6
  12. #
  13. # Core dump written. Default location: //core or core.14
  14. #
  15. # If you would like to submit a bug report, please include
  16. # instructions on how to reproduce the bug and visit:
  17. # https://icedtea.classpath.org/bugzilla
  18. # The crash happened outside the Java Virtual Machine in native code.
  19. # See problematic frame for where to report the bug.
  20. #
  21. --------------- T H R E A D ---------------
  22. Current thread (0x00005565ead9c800): JavaThread "http-nio-8889-exec-9" daemon [_thread_in_native, id=109, stack(0x00007fe8b66e6000,0x00007fe8b67e6ad0)]
  23. siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x000000000000d1f6
  24. (省略部分)
  25. Stack: [0x00007fe8b66e6000,0x00007fe8b67e6ad0], sp=0x00007fe8b67e1558, free space=1005k
  26. Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
  27. C 0x000000000000d1f6
  28. Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
  29. j org.bytedeco.javacpp.avformat.avformat_open_input(Lorg/bytedeco/javacpp/avformat$AVFormatContext;Ljava/lang/String;Lorg/bytedeco/javacpp/avformat$AVInputFormat;Lorg/bytedeco/javacpp/avutil$AVDictionary;)I+0
  30. j org.bytedeco.javacv.FFmpegFrameGrabber.startUnsafe()V+624
  31. j org.bytedeco.javacv.FFmpegFrameGrabber.start()V+1
  32. j com.megvii.qingqiu.middle.platform.provider.util.VideoFrameUtil.fetchFrame(Ljava/io/File;Ljava/io/File;)V+26
  33. j com.megvii.qingqiu.middle.platform.provider.util.VideoFrameUtil.fetchFrame(Lorg/springframework/web/multipart/MultipartFile;)Ljava/io/File;+148
  34. j
  35. (省略部分)

实践

这里将 ffmpeg 截取的方式改为 jcodec 和 jcodec-javase 来处理

maven 依赖(注释部分为使用ffmpeg 方式处理)

  1. <dependency>
  2. <groupId>org.jcodec</groupId>
  3. <artifactId>jcodec</artifactId>
  4. <version>0.2.5</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.jcodec</groupId>
  8. <artifactId>jcodec-javase</artifactId>
  9. <version>0.2.5</version>
  10. </dependency>
  11. <!--<dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacpp</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv-platform</artifactId> <version>3.4.1-1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>ffmpeg-platform</artifactId> <version>3.4.2-1.4.1</version> </dependency>-->

**视频截取工具类(注释部分为使用ffmpeg 方式处理) **

  1. package com.yin.demo
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.commons.io.FileUtils;
  4. import org.jcodec.api.FrameGrab;
  5. import org.jcodec.api.JCodecException;
  6. import org.jcodec.common.model.Picture;
  7. import org.jcodec.scale.AWTUtil;
  8. import org.springframework.web.multipart.MultipartFile;
  9. import javax.imageio.ImageIO;
  10. import java.awt.image.BufferedImage;
  11. import java.io.File;
  12. import java.io.IOException;
  13. import java.util.UUID;
  14. //import org.bytedeco.javacv.FFmpegFrameGrabber;
  15. //import org.bytedeco.javacv.Frame;
  16. //import org.bytedeco.javacv.Java2DFrameConverter;
  17. /** * @author yinfeiyue */
  18. @Slf4j
  19. public class VideoFrameUtil {
  20. /** * 获取指定视频的帧并保存为图片至指定目录 * @param videoFilePath 源视频文件路径 * @param frameFilePath 截取帧的图片存放路径 */
  21. public static void fetchFrame(String videoFilePath, String frameFilePath)
  22. throws Exception {
  23. File videoFile = new File(videoFilePath);
  24. File frameFile= new File(frameFilePath);
  25. getThumbnail(videoFile, frameFile);
  26. }
  27. /** * * 获取指定视频的帧并保存为图片至指定目录 * @param videoFile 源视频文件 * @param targetFile 截取帧的图片 */
  28. public static void fetchFrame(MultipartFile videoFile, File targetFile) throws Exception {
  29. File file = new File(videoFile.getName());
  30. FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file);
  31. getThumbnail(file, targetFile);
  32. }
  33. // /**
  34. // *
  35. // * 获取指定视频的帧并保存为图片至指定目录
  36. // * @param videoFile 源视频文件
  37. // * @param targetFile 截取帧的图片
  38. // */
  39. // public static void fetchFrame(File videoFile, File targetFile) throws Exception {
  40. // long start = System.currentTimeMillis();
  41. //
  42. // FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
  43. // log.debug("视频文件 - 帧截取 - FFMPEG初始化完成");
  44. //
  45. // ff.start();
  46. // log.debug("视频文件 - 帧截取 - 调用start开始");
  47. //
  48. // int lenght = ff.getLengthInFrames();
  49. // int i = 0;
  50. // Frame f = null;
  51. // while (i < lenght) {
  52. // // 过滤前5帧,避免出现全黑的图片,依自己情况而定
  53. // f = ff.grabFrame();
  54. // if ((i > 5) && (f.image != null)) {
  55. // break;
  56. // }
  57. // i++;
  58. // }
  59. // log.debug("视频文件 - 帧截取 - 过滤前5帧");
  60. //
  61. // assert f != null;
  62. // int oWidth = f.imageWidth;
  63. // int oHeight = f.imageHeight;
  64. // // 对截取的帧进行等比例缩放
  65. // int width = 800;
  66. // int height = (int) (((double) width / oWidth) * oHeight);
  67. // Java2DFrameConverter converter = new Java2DFrameConverter();
  68. // BufferedImage fecthedImage = converter.getBufferedImage(f);
  69. // BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
  70. // bi.getGraphics().drawImage(fecthedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH),
  71. // 0, 0, null);
  72. // ImageIO.write(bi, "jpg", targetFile);
  73. // ff.stop();
  74. // log.debug("视频文件 - 帧截取 - 调用stop结束");
  75. //
  76. // System.out.println(System.currentTimeMillis() - start);
  77. //
  78. // }
  79. /** * 获取指定视频的帧并保存为图片至指定目录 * * @param videoFile 源视频文件 */
  80. public static File fetchFrame(MultipartFile videoFile) throws Exception {
  81. String originalFilename = videoFile.getOriginalFilename();
  82. File file = new File(originalFilename);
  83. File targetFile = null;
  84. try {
  85. FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file);
  86. int i = originalFilename.lastIndexOf(".");
  87. String imageName = "";
  88. if (i > 0) {
  89. imageName = originalFilename.substring(0, i);
  90. } else {
  91. imageName = UUID.randomUUID().toString().replace("-", "");
  92. }
  93. imageName = imageName + ".jpg";
  94. targetFile = new File(imageName);
  95. getThumbnail(file, targetFile);
  96. } catch (Exception e) {
  97. log.error("fetch frame fail", e);
  98. }finally {
  99. if (file.exists()) {
  100. file.delete();
  101. }
  102. }
  103. log.debug("视频文件 - 帧截取 - 处理结束");
  104. return targetFile;
  105. }
  106. private static final String FILE_EXT = "jpg";
  107. /** * 帧数 */
  108. private static final int THUMB_FRAME = 5;
  109. public static void getThumbnail(File videoFile,File targetFile) {
  110. try {
  111. // 根据扩展名创建一个新文件路径
  112. Picture picture = FrameGrab.getFrameFromFile(videoFile, THUMB_FRAME);
  113. BufferedImage bufferedImage = AWTUtil.toBufferedImage(picture);
  114. ImageIO.write(bufferedImage, FILE_EXT, targetFile);
  115. } catch (IOException | JCodecException e) {
  116. e.printStackTrace();
  117. log.error("getThumbnail fail", e);
  118. }
  119. }
  120. public static void main(String[] args) {
  121. try {
  122. long startTime = System.currentTimeMillis();
  123. getThumbnail(new File("C:\\Users\\xxx\\Desktop\\video\\33.mp4"), new File("C:\\Users\\xxx\\Desktop\\video\\33.jpg"));
  124. System.out.println("count time is "+(System.currentTimeMillis()-startTime));
  125. } catch (Exception e) {
  126. e.printStackTrace();
  127. }
  128. }
  129. }

发表评论

表情:
评论列表 (有 0 条评论,283人围观)

还没有评论,来说两句吧...

相关阅读