截取视频的某一帧作为视频封面

方法一:使用FFmpeg

1、下载相关工具(只需解压)

下载地址:Download FFmpeg

点击Windows EXE Files的Window builds from gyan.dev,进行下载解压

2、pom导入依赖

       <!--  ffmpeg  -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.3</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>4.0.2-1.4.3</version>
        </dependency>

3、编写测试类

    //生成图片并调用上传方法
    @Test
    public void getVideoInfo() {
        try {
            File file = new File("C:\\Users\\lanys\\Desktop\\周报\\21400e3e608358da2d970bd7f69a37f1.mp4");//本地视频资源
            FileInputStream fileInputStream = new FileInputStream(file);
            //放入采集器
            FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(fileInputStream);
            //启动
            fFmpegFrameGrabber.start();
            //截取图片
            Frame frame = fFmpegFrameGrabber.grabImage();
            Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();
            BufferedImage bufferedImage = java2DFrameConverter.getBufferedImage(frame);

            //创建一个ByteArrayOutputStream
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            //输出 可以不用
            ImageIO.write(bufferedImage, "jpg", os);
            InputStream input = new ByteArrayInputStream(os.toByteArray());
            //InputStream转成MultipartFile
            MultipartFile multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
            s5(multipartFile);
            fFmpegFrameGrabber.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Autowired
    private OSS ossClient;
    @Autowired
    private AliyunConfig aliyunConfig;
    //将图片上传至OSS云存储空间
    public void s5(MultipartFile multipartFile){
            //获取图片名称
            String originalFilename = multipartFile.getOriginalFilename();;
               DateTime dateTime = new DateTime();
        String filePath = "uploads/dynamic/pictures/" + dateTime.toString("yyyy") + dateTime.toString("MM") + dateTime.toString("dd") + "/" + System.currentTimeMillis() +
                RandomUtils.nextInt(100, 9999) + "." +
                StringUtils.substringAfterLast(originalFilename, ".");
            try {
                ossClient.putObject(aliyunConfig.getBucket(), filePath, new
                        ByteArrayInputStream(multipartFile.getBytes()));
                log.info("--------视频上传成功--------");
            } catch (Exception e) {
                e.printStackTrace();
                log.info("上传失败");
            }
    }

方法二:使用第三方自带的截取视频帧方法

以阿里云OSS存储举例。

1、首先需要将视频上传至OSS存储空间

有关阿里云OSS的注册与使用,可以参考这个文档 阿里云OSS注册与使用_alioss-CSDN博客

2、pom引入依赖

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>

3、SpringBoot整合OSS视频帧

获得视频截图路径后,可以直接通过网络流上传至OSS存储空间中

获得视频截图方法getPoster()

  /**
     * 获取视频截图路径
     *
     * @param videosPath
     * @return
     * @throws IOException
     */
    public String getPoster(String videosPath)  {
        // 需要的参数是视频外网访问地址
        String objectName = videosPath;
        //Bucket
        String bucketName = "edu-lzsc";
        // 截取视频5s处的内容,宽度为1080,高度为1800,图片格式:png。
        String style = "video/snapshot,t_500,f_jpg,w_1080,h_1800,f_png";
        // 指定过期时间为10分钟。
        Date expiration = new Date(System.currentTimeMillis() + 1000 * 60 * 10);
        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
        //过期时间必须设置,不然报错提示
        req.setExpiration(expiration);
        req.setProcess(style);
        StorageConfig storageConfig = this.getStorageConfig();
        OSS ossClient = new OSSClientBuilder().build(storageConfig.getEndpoint(), storageConfig.getAccessKeyId(), storageConfig.getAccessKeySecret());
        //获取可视化帧数路径,有过期时间
        URL signedUrl = ossClient.generatePresignedUrl(req);
        System.out.println(signedUrl);

        System.out.println("打印获取url的路径"+videosPath+"?x-oss-process=video/snapshot,t_7000,f_png,w_800,h_600");
        //获取url的路径
        String videoPicUrl=videosPath+"?x-oss-process=video/snapshot,t_7000,f_png,w_800,h_600";

     //   String stream = UploadNetworkStream( videosPath+"?x-oss-process=video/snapshot,t_7000,f_png,w_800,h_600");
        return videoPicUrl;
    }

直接上传OSS云存储

/**
     * 上传网络流
     * @param url
     * @throws IOException
     */
    public String UploadNetworkStream(String url) throws IOException {
        System.out.println(url);
        //随机生成一个图片名
        String Path = RandomUtils.nextInt(100, 9999)+".jpg";
        DateTime dateTime = new DateTime();
        //生成一个真正的图片路径(用于数据库存储)
        String picturePath = "uploads/dynamic/videos/" + dateTime.toString("yyyy") + dateTime.toString("MM") + dateTime.toString("dd") + "/" + System.currentTimeMillis() +"/"+Path;
        // 上传网络流, url指的是生成可视化的路径,获取流
        InputStream inputStream = new URL(url).openStream();
        try{
        //上传 OssBucketName就是yml中桶的名称,picturePath 上传的路径,inputStream流
            ossClient.putObject(OssBucketName, picturePath, inputStream);
            //成功返回路径
            return picturePath;
        }catch (Exception e){
            log.info("-------图片复制失败-------");
            e.printStackTrace();
        }
        return null;
    }

这个获得截图url的方法就是直接将OSS存储的视频外网访问地址官方文档里的内容进行拼接

具体操作请见阿里云官方文档 视频截帧方法及示例_对象存储(OSS)-阿里云帮助中心

参考学习文档:学习笔记二:OSS上传视频截帧_谷歌oss视频抽帧-CSDN博客

在 Vue 项目中,可以使用 HTML5 的 canvas 标签来截取视频的某一帧作为视频封面。具体实现步骤如下: 1. 创建一个 video 标签,并设置其 src 属性为视频的地址。 ```html <video ref="videoPlayer" src="your-video-url"></video> ``` 2. 在 mounted 钩子函数中监听 video 标签的 loadedmetadata 事件,当视频元数据加载完成后,获取视频的尺寸和时长。 ```javascript mounted() { this.$refs.videoPlayer.addEventListener('loadedmetadata', () => { // 获取视频的宽度、高度和时长 this.videoWidth = this.$refs.videoPlayer.videoWidth; this.videoHeight = this.$refs.videoPlayer.videoHeight; this.videoDuration = this.$refs.videoPlayer.duration; }); } ``` 3. 创建一个 canvas 标签,并设置其宽度和高度为视频的宽度和高度。 ```html <canvas ref="canvas" :width="videoWidth" :height="videoHeight"></canvas> ``` 4. 在 mounted 钩子函数中监听 video 标签的 loadeddata 事件,当视频数据加载完成后,在 canvas 中绘制视频的某一帧。 ```javascript mounted() { this.$refs.videoPlayer.addEventListener('loadeddata', () => { // 绘制视频的某一帧到 canvas this.$refs.canvas.getContext('2d').drawImage(this.$refs.videoPlayer, 0, 0, this.videoWidth, this.videoHeight); // 将 canvas 转换成图片 URL,作为视频封面 this.videoPoster = this.$refs.canvas.toDataURL(); }); } ``` 5. 在模板中使用 videoPoster 作为视频封面。 ```html <video ref="videoPlayer" src="your-video-url" :poster="videoPoster"></video> ``` 通过这种方式,就可以在 Vue 项目中截取视频的某一帧作为视频封面了。需要注意的是,canvas 绘制视频的某一帧需要在视频数据加载完成后执行,否则可能无法正确绘制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值