2种方式获取视频时长、截取视频帧作为封面(java or H5)

强颜欢笑 提交于 2020-08-10 05:37:52

1、(JAVA)使用jave获取视频时长

先安装jave包,从 http://www.sauronsoftware.it/projects/jave/download.php 下载jar包,然后使用maven命令安装到本地:

mvn install:install-file -Dfile=E:\jave-1.0.2.jar -DgroupId=it.sauronsoftware -DartifactId=jave -Dversion=1.0.2 -Dpackaging=jar

命令说明:mvn install:install-file -Dfile=jar包的位置 -DgroupId=包的groupId -DartifactId=包的artifactId -Dversion=包的version -Dpackaging=jar

然后pom.xml中引入依赖

<!-- 视频时长获取 -->
<dependency>
	<groupId>it.sauronsoftware</groupId>
	<artifactId>jave</artifactId>
	<version>1.0.2</version>
</dependency>

代码(摘自网络)

package com.eya.video;

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;

import java.io.File;

/**
 * <p>
 * description
 * </p>
 *
 * @author ll
 * @date 06/11/20 10:23
 */
public class VideoTimeReader {

    public static void main(String[] args) {
        System.out.println(readTime(new File("E:\\personal\\video\\855558d1dcc2ad522c548cefe6a67bd8.mp4")));
    }

    // 获取视频时长
    private static String readTime(File source) {

        Encoder encoder = new Encoder();
        String length = "";
        try {
            MultimediaInfo m = encoder.getInfo(source);
            long ls = m.getDuration() / 1000;
            int hour = (int) (ls / 3600);
            int minute = (int) (ls % 3600) / 60;
            int second = (int) (ls - hour * 3600 - minute * 60);
            length = hour + "小时" + minute + "分" + second + "秒";
        } catch (
                Exception e) {
            e.printStackTrace();
        }
        return length;
    }

}

 

2、(JAVA)使用javacv-platform和javacv截取视频帧作为视频封面,支持直接通过视频网络地址截取帧

引入jar包,注意这2个包的版本需要匹配,不然会出错

<!-- 视频帧截取 -->
<dependency>
	<groupId>org.bytedeco</groupId>
	<artifactId>javacv-platform</artifactId>
	<version>1.4.1</version>
</dependency>
<dependency>
	<groupId>org.bytedeco</groupId>
	<artifactId>javacv</artifactId>
	<version>1.4.1</version>
</dependency>

编写java代码

package com.eya.video;

import org.apache.commons.io.IOUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;

/**
 * <p>
 * description
 * </p>
 *
 * @author ll
 * @date 06/04/20 10:29
 */
public class VideoCoverCut {

    /**
     * 截取视频第六帧的图片
     *
     * @param filePath 视频路径
     * @param dir      文件存放的根目录
     * @return 图片的相对路径 例:pic/1.png
     */
    public static String videoImage(String filePath, String dir) throws Exception {
        String pngPath = "";
//        FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
        FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(new File(filePath));

        ff.start();
        int ffLength = ff.getLengthInFrames();
        Frame f;
        int i = 0;
        while (i < ffLength) {
            f = ff.grabFrame();
            //截取第6帧
            if ((i > 5) && (f.image != null)) {
                //生成图片的相对路径 例如:pic/uuid.png
                pngPath = getPngPath();
                //执行截图并放入指定位置
                System.out.println("存储图片 : " + (dir + pngPath));
                doExecuteFrame(f, dir + pngPath);
                break;
            }
            i++;
        }
        ff.stop();

        return pngPath;
    }

    /**
     * 截取视频第六帧的图片
     *
     * @param url 网络视频地址
     * @param dir 文件存放的根目录
     * @return 图片的相对路径 例:pic/1.png
     */
    public static String getVideoCoverByURL(String url, String dir) throws Exception {
        InputStream videoInputStream = getVideoInputStream(url);
        String pngPath = "";
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoInputStream);
        ff.start();
        int ffLength = ff.getLengthInFrames();
        Frame f;
        int i = 0;
        while (i < ffLength) {
            f = ff.grabFrame();
            //截取第6帧
            if ((i > 5) && (f.image != null)) {
                //生成图片的相对路径 例如:pic/uuid.png
                pngPath = getPngPath();
                //执行截图并放入指定位置
                System.out.println("存储图片 : " + (dir + pngPath));
                doExecuteFrame(f, dir + pngPath);
                break;
            }
            i++;
        }
        ff.stop();
        IOUtils.closeQuietly(videoInputStream);

        return pngPath;
    }

    /**
     * 将网络视频地址,转成输入流
     *
     * @param videoUrl
     * @return
     */
    private static InputStream getVideoInputStream(String videoUrl) {
        // 1.下载网络文件
        try {
            URL url = new URL(videoUrl);
            //2.获取链接
            URLConnection conn = url.openConnection();
            //3.输入流
            InputStream inStream = conn.getInputStream();
            return inStream;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成图片的相对路径
     *
     * @return 图片的相对路径 例:pic/1.png
     */
    private static String getPngPath() {
        return getUUID() + ".png";
    }


    /**
     * 生成唯一的uuid
     *
     * @return uuid
     */
    private static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }


    /**
     * 截取缩略图
     *
     * @param f                       Frame
     * @param targerFilePath:封面图片存放路径
     */
    private static void doExecuteFrame(Frame f, String targerFilePath) {
        String imagemat = "png";
        if (null == f || null == f.image) {
            return;
        }
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bi = converter.getBufferedImage(f);
        File output = new File(targerFilePath);
        try {
            ImageIO.write(bi, imagemat, output);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
//        videoImage("E:\\personal\\video\\855558d1dcc2ad522c548cefe6a67bd8.mp4", "E:\\");
        getVideoCoverByURL("http://video.zhihuishu.com/zhs/ablecommons/demo/201806/dddee1c446314b84a26c74a8def3c3c7.mp4", "E:\\");

    }

}

 

3、(H5)使用H5的video获取视频的时长、截取视频图片作为封面,基于VUE语法

<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<title>Vue通过视频地址获取时长和封面</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>

<body>
	<div id="app">
		<input type="text" v-model="video">
		地址:{{video}}
		<!-- 一定要使用crossOrigin='*',否则canvas.toDataURL('image/png')的时候会抛出异常 -->
		<video style="display:none" controls="controls" autoplay name="media" ref="divVideo" :src="video"
			crossOrigin='*' @loadeddata="loadedListener">
			<source>
		</video>
		<img :src="cover" width="50px" height="50px" />
	</div>

	<script>
		new Vue({
			el: '#app',
			data: {
				video: 'http://video.zhihuishu.com/zhs/ablecommons/demo/201806/dddee1c446314b84a26c74a8def3c3c7.mp4',
				cover: ''
			},
			created() {

			},
			methods: {
				getDuration() {
					alert(this.$refs.divVideo);
				},
				loadedListener() {

					if (this.video && this.$refs.divVideo && this.$refs.divVideo.readyState === 4) {
						// 获取到的视频时长(s)
						console.log(parseInt(this.$refs.divVideo.duration));
						// console.log(this.$refs.divVideo)
						_this = this;
						// 截取封面,video标签内使用了autoplay让视频自动播放,这里设定延时2秒开始截图作为封面
						setTimeout(function () {
							var canvas = document.createElement("canvas");
							console.log(canvas)
							canvas.width = _this.$refs.divVideo.videoWidth * 0.8;
							canvas.height = _this.$refs.divVideo.videoHeight * 0.8;
							canvas.getContext('2d').drawImage(_this.$refs.divVideo, 0, 0, canvas.width, canvas
								.height);
							// 生成图片(base64)
							const dataUrl = canvas.toDataURL('image/png')
							_this.cover = dataUrl
							// console.log(dataUrl)
							// 截图完毕,停止视频
							_this.$refs.divVideo.pause()
						}, 2000)
					}
				}
			}
		})
	</script>
</body>

</html>

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!