JavaCV之rtmp推流(FLV和M3U8)

news2024/10/6 6:41:50

JavaCV与FFmpeg

FFmpeg是一款开源的多媒体处理工具集,它包含了一系列用于处理音频、视频、字幕等多媒体数据的库和工具。

JavaCV集成了FFmpeg库,使得Java开发者可以使用FFmpeg的功能,比如视频解码、编码、格式转换等。 除了FFmpeg,Javacv封装了以下库:

  1. OpenCV: JavaCV封装了OpenCV(Open Source Computer Vision Library),这是一个广泛用于计算机视觉应用的开源库。
  2. FlyCapture: 用于 Point Grey 系列相机的库。
  3. ARToolKit: 一个增强现实(Augmented Reality)库,用于跟踪相机图像中的标记。
  4. JavaCpp: 这是JavaCV的底层库,用于在Java中调用C++代码,是整个JavaCV项目的基础。
  5. Libdc1394: 用于相机和摄像机的库。
  6. JavaCV Presets: 提供了一系列预设,将原生的C/C++函数封装为Java接口,简化了在Java中调用这些功能的过程。

准备

1、引入maven包

<dependency> 
<groupId>org.bytedeco</groupId> 
<artifactId>javacv-platform</artifactId> 
<version>1.5.6</version> 
</dependency>

2、类与方法说明

FFmpegFrameGrabber 和 FFmpegFrameRecorder 是 JavaCV 中用于处理视频的两个关键类,分别用于抓取视频帧和录制视频帧,底层使用了 FFmpeg 库。
我们可以使用 FFmpegFrameGrabber 打开视频文件,获取视频信息,然后不断地从视频中获取帧。
FFmpegFrameRecorder则从输入视频中抓取帧,进行解码后,将每一帧写入输出视频文件。
FFmpegFrameGrabber 与 FFmpegFrameGrabber 配合使用,可以实现从视频源中抓取帧并将帧写入视频文件的完整流程。

2、推流流程

3、Nginx搭建rtmp服务器

(1)下载带有rtmp模块的nginx(Gryphon) nginx-win.ecsds.eu/download/
(2)在nginx中的conf文件夹配置rtmp。nginx-win.conf增加如下代码:

rtmp {
    server {
        listen 1935;
        application flv-live{
        live on;
        record off;
        allow play all;
        }
    }
}

添加后,cmd跳转到nginx目录,执行命令 nginx.exe -c conf/nginx-win.conf 即可

音视频开发免费学习地址:https://xxetb.xet.tech/s/2cGd0(登录即可免费学习)

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

FLV直播和HLS直播

FLV(Flash Video)直播:

  1. 传输协议: FLV 使用 RTMP(Real-Time Messaging Protocol)作为传输协议。RTMP 是一种实时通信协议,通常用于传输音频、视频和数据。
  2. 实时性: FLV 提供较低的延迟,通常在数秒到十几秒之间,适用于需要更快实时性的应用场景。
  3. 支持性: FLV 需要 Flash 播放器来播放,而在现代浏览器和设备中,对 Flash 的支持逐渐减少。这导致了使用 FLV 的限制。

HLS(HTTP Live Streaming)直播:

  1. 传输协议: HLS 使用 HTTP 协议,这使得它更容易穿越防火墙和代理服务器。它通常基于标准的 HTTP 80/443 端口,因此更容易被防火墙允许。
  2. 实时性: 相对于 FLV,HLS 通常有更高的延迟,通常在 10 到 30 秒之间。这使得它不太适合需要极低延迟的实时应用。
  3. 支持性: HLS 更广泛地支持各种设备和浏览器,因为它基于标准的 HTTP 和 HTML5 规范,无需专门的插件或播放器。
  4. 自适应比特率: HLS 提供了自适应比特率功能,可以根据用户的网络情况自动调整视频质量,提供更好的观看体验。

选择 FLV 还是 HLS 取决于你的具体需求。如果需要较低的延迟,并且可以接受使用 Flash 播放器的限制,那么 FLV 可能是一个合适的选择。如果需要更广泛的设备和浏览器支持,并且可以接受稍高的延迟,那么 HLS 可能更适合。在实际应用中,有时候也会结合两者,使用不同的协议来满足不同的需求。

实现Flv推流

拿一个h264格式的mov视频来演示,先将mov转为flv并且进行推流。
 

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;

public class RtmpFlv {

    private static final String outputUrl = "rtmp://localhost:1935/flv-live/test";

    private static final String inputUrl = "D:\视频.mov";

    public static void main(String[] args) throws FrameGrabber.Exception, FrameRecorder.Exception, InterruptedException {

        //设置FFmpeg日志级别
        avutil.av_log_set_level(avutil.AV_LOG_INFO);
        FFmpegLogCallback.set();

        //以文件路径的方式传入视频,当然也支持以流的方式传入
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputUrl);
        //开始捕获视频流
        grabber.start();

        //用于将捕获到的视频流转换为输出URL的mp4格式。
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight());
        recorder.setFormat("flv");
        recorder.setVideoBitrate(grabber.getVideoBitrate()); // 设置视频比特率
        recorder.setFrameRate(grabber.getVideoFrameRate()); // 设置帧率
        recorder.setGopSize((int) grabber.getVideoFrameRate()); // 设置关键帧间隔
        // CRF 是一种用于控制视频/音频质量的参数,它允许在保持目标质量的同时动态地调整比特率。较低的CRF值表示更高的质量,但也可能导致较大的文件大小
        recorder.setAudioOption("crf", "23");

        Frame frame;
        //设置音频编码为AAC
        if (grabber.getAudioChannels() > 0) {
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.setAudioBitrate(grabber.getAudioBitrate());
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        }
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //将解码后的帧记录到输出文件中
        //recorder.start通常用于处理已经解码成图像的视频数据
        recorder.start();
        while ((frame = grabber.grab()) != null) {
            recorder.record(frame);
        }
        recorder.close();
        grabber.close();
    }

运行后,打开vlc软件,点击媒体-》打开串流网络,输入rtmp://localhost:1935/flv-live/test进行播放

实现M3U8推流

代码和上面的大同小异,将一个H264的mp4视频转为hls,利用http播放m3u8文件。

import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;

public class RtmpM3U8 {

    private static final String outputUrl = "D:\nginx_rtmp\html\test.m3u8";
    private static final String inputUrl = "D:\视频.mp4";

    public static void main(String[] args) throws FrameGrabber.Exception, FrameRecorder.Exception {

        //设置FFmpeg日志级别
        avutil.av_log_set_level(avutil.AV_LOG_ERROR);
        FFmpegLogCallback.set();

        //以文件路径的方式传入视频,当然也支持以流的方式传入
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputUrl);
        //开始捕获视频流
        grabber.start();

        AVFormatContext avFormatContext = grabber.getFormatContext();
        //获取视频时长
        //long duration = avFormatContext.duration();
        //检查文件是否媒体流(视频流、音频流)
        if (avFormatContext.nb_streams() == 0) {
            //表明没有媒体流
            return;
        }

        //用于将捕获到的视频流转换为输出URL的mp4格式。
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight(),grabber.getAudioChannels());
        recorder.setFormat("hls");
        recorder.setVideoBitrate(grabber.getVideoBitrate()); // 设置视频比特率
        recorder.setFrameRate(grabber.getVideoFrameRate()); // 设置帧率
        recorder.setGopSize((int) grabber.getVideoFrameRate()); // 设置关键帧间隔

        // 设置HLS切片参数
        //将每个切片时长设置为10秒
        recorder.setOption("hls_time", "15");
        //设置切片数大小
        recorder.setOption("hls_list_size", "20");
        //设置切片循环次数为50
        recorder.setOption("hls_wrap", "20");
        //每次切片完成后,都会删除之前的切片文件。如果不设置或设置为其他值,则不会删除之前的切片文件。
        recorder.setOption("hls_flags", "delete_segments");
        //在使用 H.264 编码时,通常要求输入的像素格式为 YUV420P。如果输入的像素格式不匹配,就可能导致 avcodec_send_frame() 错误
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        //CRF 是一种用于控制视频/音频质量的参数,它允许在保持目标质量的同时动态地调整比特率。较低的CRF值表示更高的质量,但也可能导致较大的文件大小
        recorder.setAudioOption("crf", "23");

        Frame frame;
        //设置音频编码为AAC
        if (grabber.getAudioChannels() > 0) {
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.setAudioBitrate(grabber.getAudioBitrate());
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        }

        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //设置音频编码为AAC
        if (grabber.getAudioChannels() > 0) {
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.setAudioBitrate(grabber.getAudioBitrate());
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        }
        //将解码后的帧记录到输出文件中
        //recorder.start通常用于处理已经解码成图像的视频数据
        recorder.start();
        while ((frame = grabber.grab()) != null) {
            recorder.record(frame);
        }
        recorder.close();
        grabber.close();
        
    }

}

开始推流后,会在D:\nginx_rtmp\html\生成m3u8和ts文件,我们只需要播放m3u8文件即可。

打开vlc软件,点击媒体-》打开串流网络,输入http://localhost:8080/test.m3u8进行播放

原文链接 JavaCV之rtmp推流(FLV和M3U8) - 掘金

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1461847.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

01_02_mysql07_mysql8.0新特性

1.MySQL8新特性概述 MySQL从5.7版本直接跳跃发布了8.0版本 &#xff0c;可见这是一个令人兴奋的里程碑版本。MySQL 8版本在功能上做了显著的改进与增强&#xff0c;开发者对MySQL的源代码进行了重构&#xff0c;最突出的一点是多MySQL Optimizer优化器进行了改进。不仅在速度上…

在VsCode中通过Cookie登录LeetCode

在vscode中配置好leetcode之后&#xff0c;一般最常用的就是通过cookie登录leetcode ; 首先点击sign in &#xff0c; 然后选择最下面的 &#xff0c; LeetCode Cookie ! 然后输入username(也就是你的lc用户名) 或者 你leetcode绑定的邮箱 ; 输入完成之后 ; 就是要你输入你的l…

【Java EE初阶二十二】https的简单理解

1. 初识https 当前网络上,主要都是 HTTPS 了,很少能见到 HTTP.实际上 HTTPS 也是基于 HTTP.只不过 HTTPS 在 HTTP 的基础之上, 引入了"加密"机制&#xff1b;引入 HTTPS 防止你的数据被黑客篡改 &#xff1b; HTTPS 就是一个重要的保护措施.之所以能够安全, 最关键的…

C#知识点-14(索引器、foreach的循环原理、泛型、委托)

索引器 概念&#xff1a;索引器能够让我们的对象&#xff0c;以索引&#xff08;下标&#xff09;的形式&#xff0c;便捷地访问类中的集合&#xff08;数组、泛型集合、键值对&#xff09; 应用场景&#xff1a; 1、能够便捷地访问类中的集合 2、索引的数据类型、个数、顺序不…

从源码解析Kruise(K8S)原地升级原理

从源码解析Kruise原地升级原理 本文从源码的角度分析 Kruise 原地升级相关功能的实现。 本篇Kruise版本为v1.5.2。 Kruise项目地址: https://github.com/openkruise/kruise 更多云原生、K8S相关文章请点击【专栏】查看&#xff01; 原地升级的概念 当我们使用deployment等Wor…

vue:find查找函数实际开发的使用

find的作用&#xff1a; find 方法主要是查找数组中的属性&#xff0c;会遍历数组&#xff0c;对每一个元素执行提供的函数&#xff0c;直到找到使该函数返回 true 的元素。然后返回该元素的值。如果没有元素满足测试函数&#xff0c;则返回 undefined。 基础使用&#xff1a…

摄像头相机标定

相机标定 相机标定的目的有两个。 第一&#xff0c;要还原摄像头成像的物体在真实世界的位置就需要知道世界中的物体到计算机图像平面是如何变换的&#xff0c;相机标定的目的之一就是为了搞清楚这种变换关系&#xff0c;求解内外参数矩阵。 第二&#xff0c;摄像机的透视投影有…

linux下开发,stm32和arduino,我该何去何从?

linux下开发&#xff0c;stm32和arduino&#xff0c;我该何去何从&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm3的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共…

zemax消畸变目镜

用三胶合透镜代替了RKE的消色差双胶合镜&#xff0c;减少了横向色差和畸变 入瞳直径4mm波长0.51、0.56、0.61半视场22.5焦距28mm 镜头参数&#xff1a; 成像效果&#xff1a; 畸变效果&#xff1a; 点列图&#xff1a;

S281 LoRa网关助力智慧城市建设的智能交通管理

S281 LoRa网关作为智慧城市建设中的重要组成部分&#xff0c;发挥着关键的作用&#xff0c;特别是在智能交通管理方面。通过连接各类传感器设备和物联网终端&#xff0c;S281 LoRa网关实现了对城市交通系统的远程监控、智能调度和信息化管理&#xff0c;为城市交通管理部门提供…

UE5 摄像机晃动

1.新建camerashake蓝图类 命名为 晃动 2.调节相关参数 3.打开关卡序列 给摄像机添加 晃动 动画 4.播放

#gStore-weekly | workbench功能详解之知识更新

gStore workbench作为gStore的可视化管理工具&#xff0c;不仅提供了可视化查询功能&#xff0c;还提供了可视化的知识更新功能&#xff0c;用户可以在可视化界面上进行知识的新增、修改和删除等操作&#xff0c;让我们的知识管理更加清晰和便捷。 1.查询知识 登录workbenc…

新年伊始,VR全景释放“强信号”,可以结合哪些行业?

一年之计在于春&#xff0c;各行各业都想抢占在经济的第一线&#xff0c;那么如何抓住新一轮科技革命和产业变革新机遇呢&#xff1f;VR全景释放了“强信号”。对于大部分实体行业来说&#xff0c;都会有VR全景的制作需求&#xff0c;租房买房的&#xff0c;可能都见识过线上VR…

Manacher算法和扩展kmp

Manacher算法 a情况 b情况 具体例子 c情况 总结 代码 #include<iostream> #include<algorithm> #include<string> #include<cmath>using namespace std; const int N 1.1e7 1; char ss[N << 1]; int p[N << 1]; int n; void manacherss…

Qt应用-视频播放器实例

本文讲解Qt视频播放器应用实例。 实现功能 视频的播放暂停、拖动进度控制,声音控制播放列表控制播放区域的暂停控制,全屏控制等。 界面设计 <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"><class>frmVide…

c#高级-正则表达式

正则表达式是由普通字符和元字符&#xff08;特殊符号&#xff09;组成的文字形式 应用场景 1.用于验证输入的邮箱是否合法。 2.用于验证输入的电话号码是否合法。 3.用于验证输入的身份证号码是否合法。等等 正则表达式常用的限定符总结&#xff1a; 几种常用的正则简写表达式…

微服务篇之注册中心

一、eureka 1.eureka的作用 2.eureka工作流程 1. 服务提供者和服务消费者向注册中心注册服务信息&#xff0c;然后注册中心记录了对应的服务器地址。 2. 服务消费者从注册中心拉取服务提供者的信息。 3. 通过负载均衡找到对应的服务提供者地址。 4. 服务消费者远程调用对应的服…

评估睡眠阶段分类:年龄和早晚睡眠对分类性能的影响

摘要 睡眠阶段分类是专家用来监测人类睡眠数量和质量的常用方法&#xff0c;但这是一项耗时且费力的任务&#xff0c;观察者之间和观察者内部的变异性较高。本研究旨在利用小波进行特征提取&#xff0c;采用随机森林进行分类&#xff0c;寻找并评估一种自动睡眠阶段分类的方法…

C#知识点-13(进程、多线程、使用Socket实现服务器与客户端通信)

进程 定义&#xff1a;每一个正在运行的应用程序&#xff0c;都是一个进程 进程不等于正在运行的应用程序。而是为应用程序的运行构建一个运行环境 Process[] pros Process.GetProcesses();//获取电脑中所有正在运行的进程//通过进程&#xff0c;直接打开文件//告诉进程&…

ChatGPT丨成像光谱遥感技术中的AI革命:ChatGPT应用指南

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本课程重点介绍ChatGPT在遥感中的应用&#xff0c;人工智…