java实现视频抽帧以及获取其他视频信息

这篇具有很好参考价值的文章主要介绍了java实现视频抽帧以及获取其他视频信息。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

java实现视频抽帧以及获取其他视频信息

1.在pom.xml文件中导入jar包

<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>

2.创建工具类FetchVideoFrameUtil,复制以下代码

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/**
 * Created with IDEA
 * 视频取帧,可设置间隔秒数或获取所有帧数
 *
 * @Author shunzi
 * @Date 2023/08/16 14:38:12
 * @Description
 * @Version 1.0
 */
@Slf4j
public class FetchVideoFrameUtil {

    // 主函数
    public static void main(String[] args){
        try {
            //批量处理,视频所在文件夹
            String videoPath = "C:\\Users\\17386\\Desktop\\video\\normal video.mp4";
            //输出图片文件夹
            String picPath = "C:\\Users\\17386\\Desktop\\video-image3\\";
            // 获取视频FPS
            Double videoFrameRate = FetchVideoFrameUtil.getVideoFrameRate(new File(videoPath));
            log.info("视频频率:{}", videoFrameRate);
            // 根据FPS,动态计算抽帧速率。示例为:每秒取一帧
            BigDecimal frameNumber = BigDecimal.valueOf(videoFrameRate);
            BigDecimal frameDecimal = frameNumber.setScale(0, RoundingMode.HALF_UP);
            // TODO 这里来更改抽帧速率,通过乘法运算来控制。比如:控制抽帧频率为2秒一帧,int second = 2 * frameDecimal.intValue()。以此类推
            int second = frameDecimal.intValue();
            log.info("抽帧频率:{}", second);
            // 视频时长
            log.info("视频总时长:{}", FetchVideoFrameUtil.getVideoTime(new File(videoPath)));
            // 视频总帧数
            log.info("视频总共帧数:{}", FetchVideoFrameUtil.getVideoFrameTotalLength(new File(videoPath)));
            // 开始视频取帧流程
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("开始视频取帧流程=====开始时间" + sdf.format(new Date()));
            List<File> files = FetchVideoFrameUtil.fetchPic(new File(videoPath), picPath, second);
            System.out.println("结束视频取帧流程=====结束时间" + sdf.format(new Date()));
            log.info("抽取的图片集合:{}", JSONObject.toJSONString(files));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取指定视频的帧并保存为图片至指定目录
     * @param file  源视频文件
     * @param picPath  截取帧的图片存放路径
     * @throws Exception
     */
    public static java.util.List<File> fetchPic(File file, String picPath, int second) throws Exception{
        java.util.List<File> list = Lists.newArrayList();
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file); // 获取视频文件

        int length = FetchVideoFrameUtil.getVideoFrameTotalLength(file);
        ff.start(); // 调用视频文件播放
        int i = 0; // 图片帧数,如需跳过前几秒,则在下方过滤即可
        org.bytedeco.javacv.Frame frame = null;
        int count = 0;
        while (i < length) {
            frame = ff.grabImage(); // 获取该帧图片流
            System.out.print(i + ",");
            if(frame!=null && frame.image!=null) {
                System.out.println(i);
                writeToFile(frame, picPath, count,second,list); // 生成帧图片
                count++;
            }
            i++;
        }
        ff.stop();
        return list;
    }

    /**
     *
     * @param frame // 视频文件对象
     * @param picPath // 图片存放路径
     * @param count // 当前取到第几帧
     * @param second // 每隔多少帧取一张,一般高清视频每秒 20-24 帧,根据情况配置,如果全部提取,则将second设为 0 即可
     * @param list // 返回文件结果
     */
    public static void writeToFile(org.bytedeco.javacv.Frame frame, String picPath, int count, int second, java.util.List<File> list){
        if (second == 0) {
            // 跳过间隔取帧判断
        } else if (count % second != 0){ // 提取倍数,如每秒取一张,则: second = 20
            return;
        }
        File targetFile = new File(picPath + count + ".jpg");
        System.out.println("创建了文件:" + picPath + count + ".jpg");
        list.add(targetFile);
        String imgSuffix = "jpg";

        Java2DFrameConverter converter =new Java2DFrameConverter();
        BufferedImage srcBi =converter.getBufferedImage(frame);
        int owidth = srcBi.getWidth();
        int oheight = srcBi.getHeight();
        // 对截取的帧进行等比例缩放
        int width = 800;
        int height = (int) (((double) width / owidth) * oheight);
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        bi.getGraphics().drawImage(srcBi.getScaledInstance(width, height, Image.SCALE_SMOOTH),0, 0, null);
        try {
            ImageIO.write(bi, imgSuffix, targetFile);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取视频时长,单位为秒
     * @param file
     * @return 时长(s)
     */
    public static Long getVideoTime(File file){
        Long times = 0L;
        try {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
            ff.start();
            times = ff.getLengthInTime()/(1000*1000);
            ff.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return times;
    }

    /**
     * 获取视频帧率,单位FPS
     * @return
     */
    public static Double getVideoFrameRate(File file) {
        double frameRate = 0.0;
        try {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
            ff.start();
            frameRate = ff.getVideoFrameRate();
            ff.stop();
        } catch (FrameGrabber.Exception e) {
            throw new RuntimeException(e);
        }
        return frameRate;
    }

    /**
     * 获取视频真实格式
     * @param file
     * @return
     */
    public static String getVideoRealFormat(File file){
        String videoFormat = "";
        try {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
            ff.start();
            videoFormat = ff.getFormat();
            ff.stop();
        } catch (FrameGrabber.Exception e) {
            throw new RuntimeException(e);
        }
        return videoFormat;
    }

    /**
     * 获取视频总帧数长度
     * @return
     */
    public static int getVideoFrameTotalLength(File file) {
        int frameCount = 0;
        try {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
            ff.start();
            org.bytedeco.javacv.Frame frame;
            while ((frame = ff.grabImage()) != null) {
                frameCount++;
            }
            ff.stop();
        } catch (FrameGrabber.Exception e) {
            throw new RuntimeException(e);
        }
        return frameCount;
    }
}

文章引用出处:https://cloud.tencent.com/developer/article/1655887,并在原有基础上做了优化文章来源地址https://www.toymoban.com/news/detail-652970.html

到了这里,关于java实现视频抽帧以及获取其他视频信息的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (Java版)根据ip获取地理位置以及相关信息

    1.首先我们需要进入地图开放平台的官网,根据提示注册账号,以百度地图为例: https://lbsyun.baidu.com/ 我们新用户登录之后会弹出这个页面,选择个人爱好者进入完成注册 成功之后我们会进入到下面这个页面,如果没有申请ak的小伙伴在控制台看板这一块是有一个流程指引的

    2024年02月08日
    浏览(38)
  • Python获取音视频时长

    上代码:获取音视频时长.py pyinstaller -F 获取音视频时长.py 链接:https://pan.baidu.com/s/1WvsMyPHD3iFsM844gfC2Jg?pwd=yyds

    2024年02月15日
    浏览(55)
  • Java通过javacv获取视频、音频、图片等元数据信息(分辨率、大小、帧等信息)

    相信我们都会或多或少需要给前端返回视频或者音频的一些信息,那么今天这篇文章通过Java语言使用javacv来获取视频、音频、图片等元数据信息(分辨率、大小、帧等信息) 一、首先导入依赖 可以先导入javacv/javacv-platform依赖,由于依赖比较大,所以我们可以先去除部分不需

    2024年02月04日
    浏览(53)
  • FFmpeg基础:获取音视频的各种编码参数

    获取视频编码参数 视频编码参数主要包括:帧率、分辨率、编码格式、码率等,对应的概念如下。 帧率(Frame Rate) 每秒显示帧数(Frames Per Second)。电影的帧率一般是25fps和29.97fps,3D游戏要保持流畅则需要30fps以上的效果。 分辨率 指视频宽高的像素数值。标准1080P的分辨率为1920×

    2024年02月03日
    浏览(50)
  • MediaBox助力企业一站式获取音视频能力

    以一只音视频百宝箱,应对「千行千面」。 洪炳峰、楚佩斯| 作者 大家好,今天我分享的主题是MediaBox——行业音视频数字化再加速。 根据权威数据表明,65%的行业数字化信息来自视频,基于此,音视频技术对于行业数字化来说是至关重要的。今天我想借此机会向大家介绍

    2024年02月09日
    浏览(55)
  • elementUI实现上传视频时获取视频时长以及设置视频格式、大小限制

    在 before-upload 属性绑定的事件中可以获取上传视频的信息对象,通过给这个信息对象内的属性添加判断条件就可以实现对视频的格式及大小进行限制。对于视频时长,也包含在信息对象中,根据下面代码所示方法提取即可。 想了解如何给上传图片添加限制的小伙伴,可以查看

    2024年02月14日
    浏览(58)
  • Qt/C++音视频开发60-坐标拾取/按下鼠标获取矩形区域/转换到视频源真实坐标

    通过在通道画面上拾取鼠标按下的坐标,然后鼠标移动,直到松开,根据松开的坐标和按下的坐标,绘制一个矩形区域,作为热点或者需要电子放大的区域,拿到这个坐标区域,用途非常多,可以直接将区域中的画面放大,也可以将该圈起来的区域位置发给设备,由设备设定

    2024年02月03日
    浏览(52)
  • python实现视频抽帧,文件批量操作,文件批量处理(数据集制作的工具箱)

    环境准备 数据集制作 文件批量重命名 文件批量移动 将文件批量按照一定格式进行重命名 修改xml文件内容的方法 Pathlib库的常用接口 在计算机视觉项目中,文件批量操作和文件批量预处理是必不可少的步骤。它们涉及处理大量的图像文件,包括读取、处理、保存和预处理。

    2024年02月09日
    浏览(72)
  • 「Python|场景案例」如何获取音视频中声音片段的起止时间?

    本文主要介绍如何使用python的第三方库moviepy找出音视频中声音开始出现的位置以及声音结束的位置。 假设我们有一段音频,音频开始有一段无声片段,音频结束也有一段无声片段,我们需要知道开头无声片段的结束位置和结束无声片段的开始位置,或者换句话说, 我们需要

    2023年04月14日
    浏览(60)
  • 用ffmpeg解析mp4文件得到时长、比特率、音视频信息

    以下是使用C++语言调用FFmpeg获取视频流和音频流信息的示例代码: 上述代码通过 AVFormatContext 结构体和FFmpeg库函数 avformat_open_input 、 avformat_find_stream_info 等,获取MP4文件的视频流和音频流信息,并将结果存储到 MediaInfo 类中。在实际应用中,可以将上述代码封装成一个函数,

    2024年02月12日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包