当前位置: 首页 > news >正文

javacv桌面推送 通过推送和拉取udp组播视频流实现

ffmpeg udp 推流拉流命令

单播

推流

E:/工具/ffmpeg/ffmpeg -f gdigrab -r 23 -i desktop -pkt_size 1316 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f h264 udp://192.168.1.20:5001

拉流

ffplay -f h264 udp://192.168.1.20:5001 -fflags nobuffer -nofind_stream_info

组播

windows推流:

E:/工具/ffmpeg/ffmpeg -f gdigrab -r 23 -i desktop -pkt_size 1316 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f h264 "udp://224.1.1.1:5001?buffer_size=0&localaddr=192.168.1.20"

linux推流:

ffmpeg -f x11grab -r 23 -video_size 1920*1080 -i :0.0+0,00 -pkt_size 1316 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f h264 "udp://224.1.1.1:5001?buffer_size=0&localaddr=192.168.1.20"

拉流

ffplay -f h264 "udp://224.1.1.1:5001" -fflags nobuffer -nofind_stream_info

javacv推流拉流

先启动推流端,再启动拉流端时,有可能出现无法拉流播放的问题(ffmpeg命令推送,ffplay命令播放没有问题),解决办法有三种:

1,重复再启动拉动端试几次 (成功可能性超过50%)

2,先启动拉流端,再启动推流端 (几乎100%成功)

3,推流端已先启动,拉流端后启动的情况下,在推流端频繁切换几次窗口(类似于重新启动推流端推送数据,成功概率很大,但试验环境下也出现过不管用的情况)

Pusher.java

import java.util.function.Consumer;

import org.bytedeco.ffmpeg.global.avcodec;

import org.bytedeco.ffmpeg.global.avutil;

import org.bytedeco.javacv.FFmpegFrameGrabber;

import org.bytedeco.javacv.FFmpegFrameRecorder;

import org.bytedeco.javacv.Frame;

import org.bytedeco.javacv.FrameRecorder;

//RTMP视频推流器

public class Pusher extends BStreamer {

private Thread thread;

private static final int frameRate = ConfigUtil.getInt("frameRate");// 录制的帧率

private static final String format = ConfigUtil.getString("format");// 录制的帧率

private static final String linux = ConfigUtil.getString("linux");// 是否linux

private FFmpegFrameGrabber grabberCV;

/// 推流

FrameRecorder recorder;

private boolean exit = true;

public Pusher(String url) {

super(url);

}

public Pusher(String url, int w, int h) {

super(url, w, h);

}

public void close() throws Exception {

exit = false;

if (grabberCV != null) {

grabberCV.close();

}

if (recorder.isInterleaved()) {

recorder.close();

recorder.setInterleaved(false);

}

this.thread.interrupt();

}

public void start() throws Exception {

exit = true;

if (grabberCV != null) {

grabberCV.start();

}

if (recorder.isInterleaved()) {

recorder.start();

recorder.setInterleaved(true);

}

this.thread.start();

}

public void push(Consumer<Frame> consumer) throws Exception {

if("1".equals(linux)) {

grabberCV = new FFmpegFrameGrabber("");

grabberCV.setFormat("x11grab"); //linux

}

else {

grabberCV = new FFmpegFrameGrabber("desktop"); //windows

grabberCV.setFormat("gdigrab"); //windows

}

grabberCV.setOption("offset_x", "0");

grabberCV.setOption("offset_y", "0");

grabberCV.setFrameRate(frameRate);

grabberCV.setOption("draw_mouse", "0");

// grabberCV.setOption("video_size", "1600x900");

// 这种形式,双屏有问题

grabberCV.setImageWidth(getWidth());

grabberCV.setImageHeight(getHeight());

/// 推流

recorder = new FFmpegFrameRecorder(getUrl(), getWidth(), getHeight());

recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 28

recorder.setFormat(format); // rtmp的类型

recorder.setFrameRate(frameRate);

recorder.setVideoOption("tune", "zerolatency"); // 降低编码延时

recorder.setVideoOption("preset", "ultrafast"); // 提升编码速度

//recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // yuv420p AV_PIX_FMT_YUV420P udp时先开server,后启客户端,不设置

//recorder.setVideoBitrate(2 * 1024 * 1024); //udp时不设置

recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);

recorder.setVideoOption("-pkt_size", "1316"); //??用程序发送录屏流时不设置 udp时先开server,后启客户端,设置

this.thread = new Thread(() -> {

try {

while (exit) {

Frame f = grabberCV.grab();

if (f != null) {

if (recorder.isInterleaved()) {

// System.out.println("push stream...");

recorder.record(f);

// consumer.accept(f);

}

}

}

} catch (Exception e) {

e.printStackTrace();

recorder.setInterleaved(false);

}

});

}

}

BStreamer.java

//基础视频流

public class BStreamer {

private int width = 1600;

private int height = 900;

private String url;

public BStreamer(String url) {

this.url = url;

}

public BStreamer(String url, int w, int h) {

this.url = url;

if (w > 0 && h > 0) {

this.width = w;

this.height = h;

}

}

public int getWidth() {

return width;

}

public void setWidth(int width) {

this.width = width;

}

public int getHeight() {

return height;

}

public void setHeight(int height) {

this.height = height;

}

public String getUrl() {

return url;

}

public void setUrl(String url) {

this.url = url;

}

}

ConfigUtil.java

import java.util.Locale;

import java.util.ResourceBundle;

public class ConfigUtil {

private static Locale locale_CN = new Locale("zh","CN");

private static ResourceBundle rb = ResourceBundle.getBundle("rtmp",locale_CN);

public static String getString(String key) {

String ret = rb.getString(key);

return ret;

}

public static int getInt(String key) {

String str = rb.getString(key);

int ret = Integer.parseInt(str);

return ret;

}

}

TestRTMPPusher.java

import java.awt.Dimension;

import java.awt.Toolkit;

//import org.bytedeco.javacv.CanvasFrame;

public class TestRTMPPusher {

public static void main(String[] args) throws Exception {

String pushStreamUrl = ConfigUtil.getString("pushStreamUrl");

Toolkit tk = Toolkit.getDefaultToolkit();//得到Toolkit对象(实例化)

Dimension screen=tk.getScreenSize();//得到屏幕的大小

int width = (int)screen.getWidth();

int height = (int)screen.getHeight();

width = ConfigUtil.getInt("screenWidth");

height = ConfigUtil.getInt("screenHeight");

Pusher pusher = new Pusher(pushStreamUrl, width, height);

pusher.push(f -> {

// cf.showImage(f);

});

pusher.start();

}

}

RtmpPlayer.java

import java.awt.Cursor;

import java.awt.Graphics;

import java.io.IOException;

import java.awt.Image;

import java.awt.Dimension;

import java.awt.Toolkit;

import javax.swing.JFrame;

import javax.swing.UIManager;

import org.bytedeco.javacv.FFmpegFrameGrabber;

import org.bytedeco.javacv.Frame;

import org.bytedeco.javacv.Java2DFrameConverter;

public class RtmpPlayer extends JFrame {

private static final String format = ConfigUtil.getString("format");// 录制的帧率

private Image fecthedImage;

private int width;

private int height;

private int heightSub = ConfigUtil.getInt("heightSub");

public RtmpPlayer() throws IOException {

// 把进入窗口的鼠标设置为手型

this.setCursor(new Cursor(Cursor.HAND_CURSOR));

// 设置标题

this.setTitle("rtmp player");

Toolkit tk = Toolkit.getDefaultToolkit();//得到Toolkit对象(实例化)

Dimension screen=tk.getScreenSize();//得到屏幕的大小

width = (int)screen.getWidth();

height = (int)screen.getHeight();

// 设置窗口大小

this.setSize(width, height);

// 设置窗口默认关闭方式

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// 设置窗口大小不可改变

this.setResizable(false);

// 设置窗口居中

this.setLocationRelativeTo(null);

this.setUndecorated(true);

// 设置窗口显示

this.setVisible(true);

}

// 播流流

public void pullStream(String inputPath) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception {

// 创建+设置采集器

FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(inputPath);

//grabber.setOption("rtsp_transport", "tcp");

String playStreamUrl = ConfigUtil.getString("playStreamUrl");

if(!playStreamUrl.contains("udp://")) {

String streamProtocol = ConfigUtil.getString("streamProtocol");

String netProtocol = ConfigUtil.getString("netProtocol");

grabber.setOption(streamProtocol, netProtocol);

}

//grabber.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 28 no use

//grabber.setFormat(format); //no use

grabber.setImageWidth(width);

grabber.setImageHeight(height);

// 开启采集器

grabber.start();

Java2DFrameConverter converter2 = new Java2DFrameConverter();

// 播流

while (true) {

Frame frame = grabber.grabImage(); // 拉流

fecthedImage = converter2.getBufferedImage(frame);

repaint();

}

}

@Override

public void paint(Graphics g) {

g.drawImage(fecthedImage, 0, 0, width, height-heightSub, null);

}

// 测试播流器

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

String playStreamUrl = ConfigUtil.getString("playStreamUrl"); // rtmp服务器地址

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

new RtmpPlayer().pullStream(playStreamUrl);

} catch (Exception e) {

e.printStackTrace();

System.exit(0);

}

}

}

配置文件rtmp_zh.properties

内容:

streamProtocol=rtmp_transport

netProtocol=tcp

heightSub=0

screenWidth=1920

screenHeight=1080

#streamUrl=rtmp://192.168.1.20:1935/live/desktop

playStreamUrl=udp://224.1.1.1:5001

pushStreamUrl=udp://224.1.1.1:5001?buffer_size=0&localaddr=192.168.1.20

frameRate=23

format=h264

linux=0

//推流命令

java -cp bin;lib/javacpp-1.5.5.jar;lib/javacv-1.5.5.jar;lib/javacv-platform-1.5.5.jar;lib/opencv-4.5.1-1.5.5-windows-x86_64.jar;lib/ffmpeg-4.3.2-1.5.5.jar;lib/ffmpeg-platform-4.3.2-1.5.5.jar;lib/ffmpeg-4.3.2-1.5.5-windows-x86_64.jar TestRTMPPusher

//拉流命令

java -cp bin;lib/javacpp-1.5.5.jar;lib/javacv-1.5.5.jar;lib/javacv-platform-1.5.5.jar;lib/ffmpeg-4.3.2-1.5.5.jar;lib/ffmpeg-platform-4.3.2-1.5.5.jar;lib/ffmpeg-4.3.2-1.5.5-windows-x86_64.jar RtmpPlayer

相关文章:

javacv桌面推送 通过推送和拉取udp组播视频流实现

ffmpeg udp 推流拉流命令单播推流E:/工具/ffmpeg/ffmpeg -f gdigrab -r 23 -i desktop -pkt_size 1316 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f h264 udp://192.168.1.20:5001拉流ffplay -f h264 udp://192.168.1.20:5001 -fflags nobuffer -nofind_strea…...

2022年直播电商成交额,更是达到了24816亿元的成交额

近年来移动网络覆盖率、网速提升&#xff0c;直播行业不在是陌生的行业&#xff0c;直播也诞生了繁多的领域&#xff0c;游戏直播、户外直播等&#xff0c;当然还有今天的主题“直播带货”。直播带货是线上销售模式的一种&#xff0c;由衷是为了更好的把商品展示给用户观看&…...

【学习总结】2023寒假总结

写在前面时光匆匆&#xff0c;白驹过隙&#xff0c;转眼间寒假就过去了&#xff0c;这次寒假可以算的上是最长的一次假期&#xff0c;经历了从疫情到放开&#xff0c;从患病到阳康&#xff0c;在现实与虚幻的世界中玩耍&#xff0c;在痛苦的数据结构中徘徊&#xff0c;在每次早…...

宝塔搭建实战php源码人才求职管理系统后台端thinkphp源码(一)

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 在开源社区里看到了这一套系统&#xff0c;骑士人才系统SE版&#xff0c;搭建测试了&#xff0c;感觉很不错。能够帮助一些想做招聘平台的朋友降低开发成本&#xff0c;就是要注意&#xff0c;想商业使用的话&…...

stk 根据六根数文件生成卫星轨迹(一)

先简单介绍下上面的参数。 Propagator预报轨道模型。 TwoBody为二体&#xff08;开普勒运动模型&#xff09;。HPOP为高精度轨道模型。目前只用到这两个。 下图为六根数参数 Orbit Epoch&#xff1a;为根数时间&#xff08;UTC&#xff09; Semimajor Axis&#xff1a;长半…...

深度学习算法面试常问问题(一)

博主秋招遇到的面试问题以及整理其他面经相关问题&#xff0c;无偿分享~ 项目叙述&#xff1a; 算法需求及应用场景算法的调研和初步方案的制定数据的准备&#xff08;包括数据标注和数据增强&#xff09;算法的介绍&#xff08;包括输入和输出&#xff0c;loss、backbone、训…...

Spring 底层原理与解析 - 容器接口

Spring 底层原理与解析 - 容器接口 BeanFactory 能做哪些事 BeanFactory 与 ApplicaiotnContext 到底是谁提前做完了对象的加载 在之前的一篇关于 Spring 的文章Spring IoC 与容器的初始化中提到过&#xff0c;BeanFactory 接口与 ApplicationContext 接口之间的关系 可以看…...

Compose-Navigation简单案例上手

Navigation 快速上手 下面案例简要展示使用 Compose 版本的 Navigation 库来实现两个页面之间的跳转 这是完整的结构&#xff08;忽略掉红线划过的那个包&#xff09; 安装适用于 kotlin 的 navigation 依赖 dependencies {implementation("androidx.navigation:navigati…...

855. 考场就座

题目 考场就座 在考场里&#xff0c;一排有 N 个座位&#xff0c;分别编号为 0, 1, 2, …, N-1 。 当学生进入考场后&#xff0c;他必须坐在能够使他与离他最近的人之间的距离达到最大化的座位上。如果有多个这样的座位&#xff0c;他会坐在编号最小的座位上。(另外&#xf…...

k8s之ingress(二)

文章目录k8s之ingress1.1、Kubernetes 暴露服务的方式:1.2 基本概念1.3为什么需要Ingress资源1.4 Ingress的工作原理1.5ingress 暴露服务的方式总结k8s之ingress 1.1、Kubernetes 暴露服务的方式: Kubernetes暴露服务的方式目前只有三种&#xff1a;LoadBlancer Service、Nod…...

linux下监测串口数据

在编写上下位机通信代码时&#xff0c;需要分阶段测试&#xff0c;确保下位机&#xff0c;线路&#xff0c;上位机都&#xff2f;&#xff2b;&#xff0e; 一&#xff0e;检查设备数据传出 &#xff11;&#xff0e;确定下位机的串口参数 如果波特率有问题&#xff0c;可能会…...

【面试之闭包】前端面试那些事(2)三分钟深入理解闭包(附详解实例)

目录1、什么是闭包&#xff0c;什么是作用域1.1 变量作用域1.2 闭包是啥&#xff1f;如何改变变量调用格局1.3 闭包的特性2、怎么用闭包&#xff0c;闭包实例应用2.1 常见闭包实例2.2 闭包异步函数的应用2.3 柯里化的应用3、闭包的优缺点3.1 优点3.2 缺点4、片尾彩蛋【写在前面…...

深入浅出带你学习WebSphere中间件漏洞

前言 上一篇文章给大家介绍了中间件glassfish的一些常见漏洞以及利用方法&#xff0c;今天我给大家带来的是WebSphere中间件的常见漏洞以及这些漏洞的利用方法&#xff0c;下面我们首先介绍一下WebSphere中间件是什么&#xff0c;然后展开来讲关于该中间件的漏洞。 WebSphere…...

如何一眼分辨是C还是C++

C语言的历史C语言是由贝尔实验室的Dennis Ritchie在20世纪70年代初开发的一种通用程序设计语言。在早期的计算机时代&#xff0c;许多计算机使用不同的汇编语言编写程序&#xff0c;这导致了程序的可移植性和代码的可重用性很低。因此&#xff0c;Dennis Ritchie在开发C语言时试…...

CMake系列:正确使用多配置编译系统

目录 常见错误 问题现象 正确做法 if指令应该什么时候使用 活学活用 把IF指令用于多配置编译系统是很多初学者容易犯下的错误。这篇文章启示性的教你如何正确理解、使用CMake的多配置编译系统。 常见错误 以Debug和Release配置有不同的宏定义为例&#xff0c;如下所示&a…...

PCB中的HDI板生产中的变化

关键词&#xff1a;HDI概述 HDI发展演变 HDI生产难点如果把一整个电子产业比作浩瀚的宇宙&#xff0c;那些智能电子设备就像宇宙中闪耀的星光&#xff0c;当你以“上帝”的视角手持放大镜去观察时&#xff0c;这些闪烁的星光点点其实都是一个个由精密的“自然规律”所“设计”好…...

程序分析与神经网络后门

原文来自微信公众号“编程语言Lab”&#xff1a;程序分析与神经网络后门 搜索关注“编程语言Lab”公众号&#xff08;HW-PLLab&#xff09;获取更多技术内容&#xff01; 欢迎加入编程语言社区 SIG-程序分析&#xff0c;了解更多程序分析相关的技术内容。 加入方式&#xff1a;…...

redis主从哨兵模式

一.为什么用redis主从模式 1.数据备份:主从复制实现数据的热备份。 2.故障恢复:当主节点出现问题时,由从节点提供服务,实现快速恢复。 3.负载均衡:读写分离,主节点提供写服务,从节点提供读服务。在写少读多时提高Redis的并发。 二.为什么使用哨兵模式 主要用于主节…...

Spring 系列之 MVC

Spring 系列文章目录 文章目录Spring 系列文章目录前言一、介绍二、项目搭建1.创建空项目2.设置maven和lombok3.创建maven web module4. 配置Tomcat启动运行项目&#xff08;选择local本地&#xff09;5. 导入jar依赖包6.在web.xml中配置DispatcherServlet7. 加入SpringMVC的配…...

电子技术——分立CS和CE放大器的低频响应

电子技术——分立CS和CE放大器的低频响应 我们之前在学习放大器中从来没有关系过信号频率对放大器的影响&#xff0c;也就是说我们默认放大器具有无限的带宽&#xff0c;这当然不符合现实逻辑。为了说明这一点&#xff0c;我们使用下图&#xff1a; 上图描述了MOS或BJT分立电路…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...