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亿元的成交额
近年来移动网络覆盖率、网速提升,直播行业不在是陌生的行业,直播也诞生了繁多的领域,游戏直播、户外直播等,当然还有今天的主题“直播带货”。直播带货是线上销售模式的一种,由衷是为了更好的把商品展示给用户观看&…...
【学习总结】2023寒假总结
写在前面时光匆匆,白驹过隙,转眼间寒假就过去了,这次寒假可以算的上是最长的一次假期,经历了从疫情到放开,从患病到阳康,在现实与虚幻的世界中玩耍,在痛苦的数据结构中徘徊,在每次早…...
宝塔搭建实战php源码人才求职管理系统后台端thinkphp源码(一)
大家好啊,我是测评君,欢迎来到web测评。 在开源社区里看到了这一套系统,骑士人才系统SE版,搭建测试了,感觉很不错。能够帮助一些想做招聘平台的朋友降低开发成本,就是要注意,想商业使用的话&…...
stk 根据六根数文件生成卫星轨迹(一)
先简单介绍下上面的参数。 Propagator预报轨道模型。 TwoBody为二体(开普勒运动模型)。HPOP为高精度轨道模型。目前只用到这两个。 下图为六根数参数 Orbit Epoch:为根数时间(UTC) Semimajor Axis:长半…...
深度学习算法面试常问问题(一)
博主秋招遇到的面试问题以及整理其他面经相关问题,无偿分享~ 项目叙述: 算法需求及应用场景算法的调研和初步方案的制定数据的准备(包括数据标注和数据增强)算法的介绍(包括输入和输出,loss、backbone、训…...
Spring 底层原理与解析 - 容器接口
Spring 底层原理与解析 - 容器接口 BeanFactory 能做哪些事 BeanFactory 与 ApplicaiotnContext 到底是谁提前做完了对象的加载 在之前的一篇关于 Spring 的文章Spring IoC 与容器的初始化中提到过,BeanFactory 接口与 ApplicationContext 接口之间的关系 可以看…...
Compose-Navigation简单案例上手
Navigation 快速上手 下面案例简要展示使用 Compose 版本的 Navigation 库来实现两个页面之间的跳转 这是完整的结构(忽略掉红线划过的那个包) 安装适用于 kotlin 的 navigation 依赖 dependencies {implementation("androidx.navigation:navigati…...
855. 考场就座
题目 考场就座 在考场里,一排有 N 个座位,分别编号为 0, 1, 2, …, N-1 。 当学生进入考场后,他必须坐在能够使他与离他最近的人之间的距离达到最大化的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外…...
k8s之ingress(二)
文章目录k8s之ingress1.1、Kubernetes 暴露服务的方式:1.2 基本概念1.3为什么需要Ingress资源1.4 Ingress的工作原理1.5ingress 暴露服务的方式总结k8s之ingress 1.1、Kubernetes 暴露服务的方式: Kubernetes暴露服务的方式目前只有三种:LoadBlancer Service、Nod…...
linux下监测串口数据
在编写上下位机通信代码时,需要分阶段测试,确保下位机,线路,上位机都OK. 一.检查设备数据传出 1.确定下位机的串口参数 如果波特率有问题,可能会…...
【面试之闭包】前端面试那些事(2)三分钟深入理解闭包(附详解实例)
目录1、什么是闭包,什么是作用域1.1 变量作用域1.2 闭包是啥?如何改变变量调用格局1.3 闭包的特性2、怎么用闭包,闭包实例应用2.1 常见闭包实例2.2 闭包异步函数的应用2.3 柯里化的应用3、闭包的优缺点3.1 优点3.2 缺点4、片尾彩蛋【写在前面…...
深入浅出带你学习WebSphere中间件漏洞
前言 上一篇文章给大家介绍了中间件glassfish的一些常见漏洞以及利用方法,今天我给大家带来的是WebSphere中间件的常见漏洞以及这些漏洞的利用方法,下面我们首先介绍一下WebSphere中间件是什么,然后展开来讲关于该中间件的漏洞。 WebSphere…...
如何一眼分辨是C还是C++
C语言的历史C语言是由贝尔实验室的Dennis Ritchie在20世纪70年代初开发的一种通用程序设计语言。在早期的计算机时代,许多计算机使用不同的汇编语言编写程序,这导致了程序的可移植性和代码的可重用性很低。因此,Dennis Ritchie在开发C语言时试…...
CMake系列:正确使用多配置编译系统
目录 常见错误 问题现象 正确做法 if指令应该什么时候使用 活学活用 把IF指令用于多配置编译系统是很多初学者容易犯下的错误。这篇文章启示性的教你如何正确理解、使用CMake的多配置编译系统。 常见错误 以Debug和Release配置有不同的宏定义为例,如下所示&a…...
PCB中的HDI板生产中的变化
关键词:HDI概述 HDI发展演变 HDI生产难点如果把一整个电子产业比作浩瀚的宇宙,那些智能电子设备就像宇宙中闪耀的星光,当你以“上帝”的视角手持放大镜去观察时,这些闪烁的星光点点其实都是一个个由精密的“自然规律”所“设计”好…...
程序分析与神经网络后门
原文来自微信公众号“编程语言Lab”:程序分析与神经网络后门 搜索关注“编程语言Lab”公众号(HW-PLLab)获取更多技术内容! 欢迎加入编程语言社区 SIG-程序分析,了解更多程序分析相关的技术内容。 加入方式:…...
redis主从哨兵模式
一.为什么用redis主从模式 1.数据备份:主从复制实现数据的热备份。 2.故障恢复:当主节点出现问题时,由从节点提供服务,实现快速恢复。 3.负载均衡:读写分离,主节点提供写服务,从节点提供读服务。在写少读多时提高Redis的并发。 二.为什么使用哨兵模式 主要用于主节…...
Spring 系列之 MVC
Spring 系列文章目录 文章目录Spring 系列文章目录前言一、介绍二、项目搭建1.创建空项目2.设置maven和lombok3.创建maven web module4. 配置Tomcat启动运行项目(选择local本地)5. 导入jar依赖包6.在web.xml中配置DispatcherServlet7. 加入SpringMVC的配…...
电子技术——分立CS和CE放大器的低频响应
电子技术——分立CS和CE放大器的低频响应 我们之前在学习放大器中从来没有关系过信号频率对放大器的影响,也就是说我们默认放大器具有无限的带宽,这当然不符合现实逻辑。为了说明这一点,我们使用下图: 上图描述了MOS或BJT分立电路…...
代码随想录【Day16】| 104. 二叉树的最大深度、111. 二叉树的最小深度、222. 完全二叉树的节点个数
104. 二叉树的最大深度 题目链接 题目描述: 给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例: 给定二叉树 [3,9,20,null,null,15,7],…...
状态机图、通信图题
1.下列关于通信图与顺序图中的对象的相同点的叙述.正确的是(D)。A.两种图中都可以表示对象的创建和销毁B.对象在两种图中的位置都没有任何限制C.对象在两种图中的表示方式完全一致D.对象名在两种图中的表示完全一致2.下列关于通信图的说法错误的是(C)。A.通信图是对一次交互过程…...
分布式文件存储Minio学习入门
文章目录一、分布式文件系统应用场景1. Minio介绍Minio优点2. MinIO的基础概念、3. 纠删码ES(Erasure Code)4. 存储形式5. 存储方案二、Docker部署单机Minio三、minio纠删码模式部署四、分布式集群部署分布式存储可靠性常用方法冗余校验分布式Minio优势运行分布式minio使用dock…...
handler解析(4)-Message及Message回收机制
Message中可以携带的信息 Message中可以携带的数据比较丰富,下面对一些常用的数据进行了分析。 /*** 用户定义的消息代码,以便当接受到消息是关于什么的。其中每个Hanler都有自己的命名控件,不用担心会冲突*/ public int what; /*** 如果你…...
Linux使用定时任务监控java进程并拉起
需求描述: 设计一个脚本,通过Linux定时任务,每分钟执行一次,监控jar包进程是否存在,存在则不做动作,不存在则重新拉起jar包程序。 定时任务配置: */1 * * * * bash -x /root/myfile/jars/che…...
Win 10电脑摄像头提示错误代码0xa00f4244怎么办?
如果你的Windows 10电脑无法打开摄像头,提示“我们找不到你的摄像头”的错误消息,错误代码是0xA00F4244,原因可能是杀毒软件阻止了摄像头,或者是摄像头驱动程序有问题。 小编为你整理了摄像头错误代码0xA00F4244的解决方法&#…...
MFC消息机制
1.消息映射消息映射是一个将消息和成员函数相互关联的表。比如,框架窗口接收到一个鼠标左击消息,MFC将搜索该窗口的消息映射,如果存在一个处理WM_LBUTTTONDOWN消息的处理程序,然后就调用OnButtonDown。2.消息映射机制2.1 声明宏 写…...
全国计算机等级考试报名照片要求以及证件照制作教程
马上就全国计算机等级考试就要开始了,相信现在很多同学都在网上进行报名呢,报名的时候肯定需要用到个人证件照片,所以问题来了,我们怎么自己制作证件照片呢?计算机等级考试报名时对证件照都有哪些要求呢?该…...
SQLSERVER 临时表和表变量到底有什么区别?
一:背景 1. 讲故事 今天和大家聊一套面试中经常被问到的高频题,对,就是 临时表 和 表变量 这俩玩意,如果有朋友在面试中回答的不好,可以尝试看下这篇能不能帮你成功迈过。 二:到底有什么区别 1. 前置思…...
技术生态异军突起,昇思MindSpore进入AI框架第一梯队
ChatGPT掀起的新一轮人工智能狂欢下,隐藏在背后的“大模型”正进入越来越多开发者的视野。 诚如几年前开始流行的一种说法:数据是燃料、模型是引擎、算力是加速器。ChatGPT的出现,恰如其分地诠释了数据、模型和算力的“化学反应”。而在其中…...
网站的flash怎么做的/北京seo外包平台
一、用until实现下列脚本1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并提示该用户退出系统。#!/bin/bash#author:jackCui#description:Find out if the system has a hack…...
html5+css3网站/百度网址大全
ng-zorro-antd 是 Ant Design 的 Angular 实现,主要用于研发企业级中后台产品。全部代码开源并遵循 MIT 协议,任何企业、组织及个人均可免费使用。ng-zorro-antd 13.2.0 现已发布,更新内容如下: Bug Fixes carousel: 修复 nzAft…...
域名查询是否被注册/郑州本地seo顾问
这个问题是由于使用了较新的C17标准语言,因为Windows旧的SDK定义有一个byte的类型,但在C17里也有定义std::byte类型,这样就会造成重复定义。 解决方法: 1.可以预定义一个宏:_HAS_STD_BYTE0,这样设置就可以…...
珠海响应式网站建设费用/北京百度总部电话
二分查找 1. 适用场景 适用于对排好序的序列的指定值进行查找 2. 复杂度 O(logN) 3. 代码 /*cpp*/ int binarySearch(int[] a, int key){int a_len sizeof(a)/sizeof(a[0]);int lo 0, hi a_len - 1;while (lo < hi){int mid lo (hi - lo) / 2;if (key < a[mid]) h…...
校园二手网站设计论文/博客优化网站seo怎么写
题库来源:安全生产模拟考试一点通公众号小程序 2022年安全员-B证培训试题系安全员-B证国家题库仿真模拟预测!2022安全员-B证考试模拟100题模拟考试平台操作依据安全员-B证新版考试题库。安全员-B证试卷通过安全生产模拟考试一点通上题库学习。 1、【多选…...