详解如何用Java实现对m3u8直播流抽帧

目录
  • 什么是抽帧
  • 什么是 FFmpeg
  • 什么是 JavaCV
  • 最简单的抽帧
  • 抽帧算法

什么是抽帧

抽帧(frame extraction)是指从视频流中提取一些特定的帧,通常是关键帧或者随机帧,以供后续处理。对于m3u8直播流,可以使用Java中的FFmpeg库来实现抽帧功能。

什么是 FFmpeg

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。

什么是 JavaCV

JavaCV 是一款基于JavaCPP 调用方式,由多种开源计算机视觉库组成的包装库,封装了包含FFmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在内的计算机视觉领域的常用库和实用程序类。

最简单的抽帧

使用 Java 中的 FFmpeg 库实现的最简单的抽帧。

<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.4.1</version>
</dependency>
import org.bytedeco.javacv.*;
import java.io.IOException;

public class FrameExtractor {
    public static void main(String[] args) throws IOException, FrameGrabber.Exception, FrameRecorder.Exception {
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("直播流地址xxx.m3u8");
        grabber.setOption("rtsp_transport", "tcp");
        grabber.start();

        Frame frame;
        Java2DFrameConverter converter = new Java2DFrameConverter();
        int i = 0;

        // grabber.grabImage() 获取帧图片,不包含音频
        // grabber.grab() 包含音频
        while ((frame = grabber.grabImage()) != null) {
            // 在这里处理抽取到的帧
            // 例如,将帧保存为图像文件
            converter.convert(frame).createGraphics().dispose();
            String outputFilename = "frame_" + i + ".jpg";
            File f = new File(outputFilename);
            if(!f.exists())f.mkdirs();
            ImageIO.write(converter.convert(frame), "jpg", f);
            i++;
        }
        grabber.stop();
    }
}

抽帧算法

什么是帧率:每秒刷新几次就是几帧。例如25帧就是每秒展示25张图片。

指定每几秒抽取几帧。这里的核心思想是,平均数累加。

假设对帧率为25的视频。要实现每3秒抽3帧。

设:帧率=fps;时间=t;t时间内抽取总帧数=x;

avg=(fps.t)/x;

只需找出 1*avg,2*avg,...,x*avg分别对应的值就找到了需要抽取的帧。

最后只需要使用一个变量对帧率计数。在指定的帧率进行抽取操作就可以了。

代码:

public class FrameExtractor {
    public static void main(String[] args) throws IOException, FrameGrabber.Exception, FrameRecorder.Exception {
        // 读取流
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("http:.m3u8");
        grabber.setOption("rtsp_transport", "tcp");
        grabber.start();

        Frame frame;
        Java2DFrameConverter converter = new Java2DFrameConverter();

        // 控制读取帧数
        int frameRate = (int) grabber.getFrameRate();
        int targetFrameRateNum[] = {10,10}; //(每10秒读10帧) 目标帧率数量,每几秒钟读取几帧
        SortedSet<Integer> targetFrameRate = new TreeSet<>(); // 需要抽取的目标帧率
        // 计算需要抽取的目标帧
        int calFrameRate = frameRate * targetFrameRateNum[0];
        int partSize = calFrameRate / targetFrameRateNum[1];
        int remainder = calFrameRate % targetFrameRateNum[1];
        int current = 1;
        for (int i = 0; i < targetFrameRateNum[1]; i++) {
            // 避免出现帧数多一个
            if (current <= calFrameRate){
                targetFrameRate.add(current);
            }
            current += partSize;
            if (i < remainder) {
                current++;
            }
        }

        // 计数器
        int frameCount = 0;
        int i = 0;
        while ((frame = grabber.grabImage()) != null) {
            // 每读取一帧,增加计数器
            frameCount++;
            // 如果计数器达到目标帧率,则进行处理
            if (targetFrameRate.contains(frameCount)) {
                // 处理抽取到的帧

            }
            // 重置计数器
            if (calFrameRate == frameCount){
                frameCount = 0;
            }
        }

        grabber.stop();
    }
}

到此这篇关于详解如何用Java实现对m3u8直播流抽帧的文章就介绍到这了,更多相关Java m3u8直播流抽帧内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java将m3u8格式转成视频文件的方法

    这是一次尝试,android手机将在线的m3u8小电影保存到手机端,手机端把文件复制到电脑端. 然后使用小工具合并成可播放的视频. /** * 合并视频文件 * */ public class MergeVideos { /** * source为源地址,destination为合并之后的文件地址,videoName为合并后视频的名字,num为视频数量 * @param source * @param destination * @throws IOException */ public sta

  • ffmpeg网页视频流m3u8 ts实现视频下载

    目录 引言 下载视频所有的ts切片文件 引言 现在很多视频网站播放流视频,都不是采用mp4/flv文件直接播放,而是采用m3u8/ts这种方式播放. 简单说就是,网站后台把视频切片成成百上千个xx.ts文件,一般10秒一个,每个都几百kb很小.然后通过xx.m3u8播放列表把这些文件连接起来. 通过Chrome DevTool的Network栏,我们可以清楚的看到加载过程: 我们直接点击这个playlist.m3u8播放列表文件,在旁边的preview栏中查看内容,可以看到: #EXTM3U #

  • 详解如何用Java实现对m3u8直播流抽帧

    目录 什么是抽帧 什么是 FFmpeg 什么是 JavaCV 最简单的抽帧 抽帧算法 什么是抽帧 抽帧(frame extraction)是指从视频流中提取一些特定的帧,通常是关键帧或者随机帧,以供后续处理.对于m3u8直播流,可以使用Java中的FFmpeg库来实现抽帧功能. 什么是 FFmpeg FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案. 什么是 JavaCV JavaCV

  • 详解如何用SpringBoot 2.3.0.M1创建Docker映像

    1.发布 SpringBoot2.3.0.M1刚刚发布,它带来了一些有趣的新特性,可以帮助您将SpringBoot应用程序打包到Docker映像中.在这篇博客文章中,我们将查看创建Docker映像的典型方式,并展示如何通过使用这些新特性来改进这些镜像 2.说明 SpringBoot 2.3.0.M1 暂时不支持Windows, 很鸡肋 暂时在Mac 和Linux 上运行良好 3.常见的Docker 运行方式 一般情况下,通过docker 运行springboot 是这样的 FROM openjd

  • 详解如何在Java中加密和解密zip文件

    目录 依赖 压缩一个文件 压缩多个文件 压缩一个目录 创建一个分割的压缩文件 提取所有文件 提取单个文件 总结 依赖 让我们先把 zip4j 依赖关系添加到我们的 pom.xml 文件中. <dependency>     <groupId>net.lingala.zip4j</groupId>     <artifactId>zip4j</artifactId>     <version>2.9.0</version>

  • Java构造方法实例详解(动力节点java学院整理)

    构造函数是一种特殊的函数.其主要功能是用来在创建对象时初始化对象, 即为v对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.构造函数与类名相同,可重载多个不同的构造函数.在JAVA语言中,构造函数与C++语言中的构造函数相同,JAVA语言中普遍称之为构造方法. 使用构造器时需要记住: 1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名) 2.每个类可以有一个以上的构造器 3.构造器可以有0个.1个或1个以上的参数 4.构造器没有返回值 5.构造器总是伴随

  • Java类的继承实例详解(动力节点Java学院整理)

    一.你了解类吗? 在Java中,类文件是以.java为后缀的代码文件,在每个类文件中最多只允许出现一个public类,当有public类的时候,类文件的名称必须和public类的名称相同,若不存在public,则类文件的名称可以为任意的名称(当然以数字开头的名称是不允许的). 在类内部,对于成员变量,如果在定义的时候没有进行显示的赋值初始化,则Java会保证类的每个成员变量都得到恰当的初始化: 1)对于  char.short.byte.int.long.float.double等基本数据类型的

  • java实现对map的字典序排序操作示例

    本文实例讲述了java实现对map的字典序排序操作.分享给大家供大家参考,具体如下: java中对map的字典序排序,算法验证比对微信官网https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN,搜索关键字"附录1-JS-SDK使用权限签名算法" import java.util.ArrayList; import java.util.Collectio

  • 详解springSecurity之java配置篇

    一 前言 本篇是springSecurity知识的入门第二篇,主要内容是如何使用java配置的方式进行配置springSeciruty,然后通过一个简单的示例自定义登陆页面,覆盖原有springSecurity默认的登陆页面:学习这篇的基础是 知识追寻者之前发布 过 的<springSecurity入门篇> 二 java配置 2.1配置账号密码 如下所示, 使用 @EnableWebSecurity 在配置类上开启security配置功能: 在配置类中定义bean 名为 UserDetails

  • 详解如何将JAVA程序制作成可以直接执行的exe文件

    突然心血来潮,想自己做个小程序玩玩,但是怎么把他做成一个exe文件,让大家能够更好的理解和使用呢,百度了一下,说是需要exe4j来生成,但是看了很多关于exe4j将java程序生成exe文件的教程,觉着都不是自己想要的结果,还是自己综合一下,写篇文章记录一下. 下载和安装的步骤我就略过了,直接说重点. 一 : 将写好的java程序打成jar包,如下图: 1: . 2: 3: 4: 5:此处填写MANIFEST.MF文件路径,MANIFEST.MF手动创建后放在下项目路径下即可 MANIFEST.

  • 详解如何用alpine镜像做一个最小的镜像并运行c++程序

    需求 工作中我们如果要制作镜像,一般都是直接pull官方镜像,比如我们要运行一个c++程序我们可能直接pull一个gcc,或者ubuntu镜像就可以了,但是存在一个问题,我们只是要运行一个c++程序却要运行一个ubuntu系统,这是非常消耗资源的,所以就去网上搜了搜发现早期的docker都是使用alpine镜像来做基础镜像,所以就用alpile镜像来制作镜像 dockerfile FROM alpine:3.7 MAINTAINER Rethink #更新Alpine的软件源为国内(清华大学)的

  • 详解如何把Java中if-else代码重构成高质量代码

    为什么我们写的代码都是if-else? 程序员想必都经历过这样的场景:刚开始自己写的代码很简洁,逻辑清晰,函数精简,没有一个if-else, 可随着代码逻辑不断完善和业务的瞬息万变:比如需要对入参进行类型和值进行判断:这里要判断下对象是否为null:不同类型执行不同的流程. 落地到具体实现只能不停地加if-else来处理,渐渐地,代码变得越来越庞大,函数越来越长,文件行数也迅速突破上千行,维护难度也越来越大,到后期基本达到一种难以维护的状态. 虽然我们都很不情愿写出满屏if-else的代码,可逻

随机推荐