如何获取上传视频文件的缩略图?

3

我已经尝试了几天来为上传的文件创建缩略图,但一直没有成功。我尝试了Xuggler、FFMpegFrameGrabber和其他一些随机代码,但似乎都不起作用。从视频中捕获单个帧应该是一个微不足道的任务。有人知道我该如何做吗?


希望这个答案能帮到你:https://dev59.com/JnA75IYBdhLWcg3wJFgL - KhAn SaAb
@khAn 那只适用于图像吗?还是可以在视频文件上使用相同的方法? - Tometoyou
检查这个链接:https://dev59.com/n3VD5IYBdhLWcg3wOo5h - KhAn SaAb
刚试了一下,但是返回了错误信息:“无法找到<<文件名>>的播放器”。 - Tometoyou
6个回答

5
package com.tape.controller;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.imageio.ImageIO;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.OpenCVFrameGrabber;

public class VideoThumbTaker {

    protected String ffmpegApp;

    public VideoThumbTaker(String ffmpegApp)
    {
        this.ffmpegApp = ffmpegApp;
    }

    public void getThumb(String videoFilename, String thumbFilename, int width, int height,int hour, int min, float sec)
      throws IOException, InterruptedException
    {
        ProcessBuilder processBuilder = new ProcessBuilder(ffmpegApp, "-y", "-i", videoFilename, "-vframes", "1",
    "-ss", hour + ":" + min + ":" + sec, "-f", "mjpeg", "-s", width + "*" + height, "-an", thumbFilename);
        Process process = processBuilder.start();
        InputStream stderr = process.getErrorStream();
        InputStreamReader isr = new InputStreamReader(stderr);
        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null);
        process.waitFor();
    }

    public static void main(String[] args) throws Exception, IOException
    {
        FFmpegFrameGrabber g = new FFmpegFrameGrabber("C:\\JavaEE\\New Project\\tape\\src\\main\\webapp\\web-resources\\videos\\vid.mp4");
        g.setFormat("mp4");
        g.start();

        for (int i = 0 ; i < 50 ; i++) {
            ImageIO.write(g.grab().getBufferedImage(), "png", new File("C:\\JavaEE\\New Project\\tape\\src\\main\\webapp\\web-resources\\thumbnails\\video-frame-" + System.currentTimeMillis() + ".png"));
        }

         g.stop();
    }
}

我使用了基于 FFMpegFrameGrabber 的 Java 代码来创建视频缩略图。你可以试试看。

Maven 依赖:

<dependency>
   <groupId>org.bytedeco</groupId>
   <artifactId>javacv</artifactId>
   <version>0.8</version>
</dependency>

3

请点击此链接查看依赖关系。

FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber("/home/anuresh/Downloads/avw.mp4");

frameGrabber.start();

Java2DFrameConverter aa = new Java2DFrameConverter()

try {
    BufferedImage bi

  //  for (int i = 0; i < 1000; i++) {
        Frame f = frameGrabber. grabKeyFrame() ;

        bi = aa.convert(f)
    while (bi!=null)
    {

        ImageIO.write(bi, "png", new File("/home/anuresh/Downloads/thumb/jkkjkjg" + System.currentTimeMillis() + ".png"));

        f = frameGrabber.   grabKeyFrame() ;
        bi = aa.convert(f)
    }
    frameGrabber.stop();
} catch (Exception e) {

    e.printStackTrace();
}

也可以使用 grabFrame 或 imageFrame,有关更多信息,请参阅文档。 - Anuresh Verma
给出了这个错误:主线程中的异常java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.ffmpeg.global.avutil - Naveen Gopalakrishna

1

0

使用ffmpegthumbnailer快速轻量级视频缩略图生成器。


我该如何在Java中使用它? - Tometoyou
这是一个命令行工具。您必须在Java代码中执行命令。要在Java上执行命令,请阅读:https://dev59.com/oWoy5IYBdhLWcg3wg-Ym - ashok_rajput

0

您可以使用humble-videoXuggle-xuggler的继承者)

在Maven中使用:

<project>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>io.humble</groupId>
      <artifactId>humble-video-all</artifactId>
      <version>0.2.1</version>
    </dependency>
  </dependencies>
</project>

humble-video 没有示例,但我想它与 xuggler 相似,请看 DecodeAndCaptureFrames.java


0

使用谦虚视频并处理旋转的视频图像

import io.humble.video.*;
import io.humble.video.awt.MediaPictureConverter;
import io.humble.video.awt.MediaPictureConverterFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.*;
import java.nio.file.Path;

        demuxer = Demuxer.make();
        demuxer.open(videoFile.toString(), null, false, true, null, null);
        final int numStreams = demuxer.getNumStreams();
        int streamIndex = -1;
        Decoder videoDecoder = null;
        String rotate = null;
        for (int i = 0; i < numStreams; ++i) {
            final DemuxerStream stream = demuxer.getStream(i);
            final KeyValueBag metaData = stream.getMetaData();
            final Decoder decoder = stream.getDecoder();
            if (decoder != null && decoder.getCodecType() == MediaDescriptor.Type.MEDIA_VIDEO) {
                videoDecoder = decoder;
                streamIndex = i;
                rotate = metaData.getValue("rotate", KeyValueBag.Flags.KVB_NONE);
                break;
            }
        }
        if (videoDecoder == null) {
            throw new IOException("Not a valid video file");
        }
        videoDecoder.open(null, null);

        final MediaPicture picture = MediaPicture.make(
            videoDecoder.getWidth(),
            videoDecoder.getHeight(),
            videoDecoder.getPixelFormat());

        final MediaPictureConverter converter =
            MediaPictureConverterFactory.createConverter(
                MediaPictureConverterFactory.HUMBLE_BGR_24,
                picture);

        final MediaPacket packet = MediaPacket.make();
        BufferedImage image = null;
        MUX:
        while (demuxer.read(packet) >= 0) {
            if (packet.getStreamIndex() != streamIndex) {
                continue;
            }
            int offset = 0;
            int bytesRead = 0;
            videoDecoder.decodeVideo(picture, packet, offset);
            do {
                bytesRead += videoDecoder.decode(picture, packet, offset);
                if (picture.isComplete()) {
                    image = converter.toImage(null, picture);
                    break MUX;
                }
                offset += bytesRead;

            } while (offset < packet.getSize());
        }
        if (image == null) {
            throw new IOException("Unable to find a complete video frame");
        }
        if (rotate != null) {
            final AffineTransform transform = new AffineTransform();
            transform.translate(0.5 * image.getHeight(), 0.5 * image.getWidth());
            transform.rotate(Math.toRadians(Double.parseDouble(rotate)));
            transform.translate(-0.5 * image.getWidth(), -0.5 * image.getHeight());
            final AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
            image = op.filter(image, null);
        }

        final Path target = videoFile.getParent().resolve(videoFile.getFileName() + ".thumb.jpg");

        final double mul;
        if (image.getWidth() > image.getHeight()) {
            mul = 216 / (double) image.getWidth();
        } else {
            mul = 216 / (double) image.getHeight();
        }

        final int newW = (int) (image.getWidth() * mul);
        final int newH = (int) (image.getHeight() * mul);
        final Image thumbnailImage = image.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
        image = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_BGR);

        final Graphics2D g2d = image.createGraphics();
        g2d.drawImage(thumbnailImage, 0, 0, null);
        g2d.dispose();

        ImageIO.write(image, "jpeg", target.toFile());
        return target.toAbsolutePath();

你能否详细说明如何在指定时间生成视频缩略图? - t4dohx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接