JAVACV实现直播推流

最小依赖

 <properties><javacv.version>1.5.5</javacv.version><system.windowsx64>windows-x86_64</system.windowsx64></properties><!-- javacv+javacpp核心库--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>${javacv.version}</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacpp-platform</artifactId><version>${javacv.version}</version></dependency><!-- ffmpeg最小依赖包,必须包含上面的javacv+javacpp核心库 --><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>4.3.2-${javacv.version}</version><classifier>${system.windowsx64}</classifier></dependency><!-- javacv+javacpp核心库--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>${javacv.version}</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacpp-platform</artifactId><version>${javacv.version}</version></dependency><!-- ffmpeg最小依赖包,必须包含上面的javacv+javacpp核心库 --><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>4.3.2-${javacv.version}</version><classifier>${system.windowsx64}</classifier></dependency><!-- javacv+javacpp核心库--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>${javacv.version}</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacpp-platform</artifactId><version>${javacv.version}</version></dependency><!-- 最小opencv依赖包 ,必须包含上面的javacv+javacpp --><dependency><groupId>org.bytedeco</groupId><artifactId>opencv</artifactId><version>4.5.1-${javacv.version}</version><classifier>${system.windowsx64}</classifier></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>openblas</artifactId><version>0.3.13-${javacv.version}</version><classifier>${system.windowsx64}</classifier></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>flycapture</artifactId><version>2.13.3.31-${javacv.version}</version><classifier>${system.windowsx64}</classifier></dependency>

视频采集源可以使用摄像头或者其他,我这里用了桌面录像
也排除了声音的采集

package com.test.utiles;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;/*** @author yudy* Created by 2022/9/10*/
@Slf4j
public class MyLiveTest {private static int frameRate = 16;// 录制的帧率static Frame imgFrame = null;static String url = "";static boolean isStop = false;public static void start() throws Exception {// 帧记录// window 建议使用 FFmpegFrameGrabber("desktop") 进行屏幕捕捉FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("desktop");grabber.setFormat("gdigrab");grabber.setFrameRate(frameRate);// 帧获取间隔grabber.setOption("framerate", "25");grabber.setOption("draw_mouse", "0");// 捕获指定区域,不设置则为全屏
//        grabber.setImageHeight(600);
//        grabber.setImageWidth(800);// grabber.setOption("offset_x", "200");// grabber.setOption("offset_y", "200");//必须设置了大小才能指定区域起点,参数可参考 FFmpeg 入参grabber.start();//初始化默认帧,用于锁屏状态下无法或者图形的问题导致异常
//        if (imgFrame == null){
//            InputStream in = this.getClass().getClassLoader().getResourceAsStream("img.jpeg");
//            BufferedImage image = ImageIO.read(in);
//            Java2DFrameConverter java2dConverter = new Java2DFrameConverter();
//            imgFrame = java2dConverter.convert(image);
//        }if (StringUtils.isEmpty(url)) {url = "rtmp://192.168.0.25:1935/live/livestream/aa";}// 直播推流//推送固定大小分辨率的图像FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(url,1024, 768, 0);//推送实际小打分辨率的图像
//        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(
//                url,
//                grabber.getImageWidth(), grabber.getImageHeight(), 0);recorder.setMaxDelay(5000);// 用于存储视频 , 调用stop后,需要释放,就会在指定位置输出文件,,这里我保存到D盘//FFmpegFrameRecorder recorder = FFmpegFrameRecorder.createDefault(file, grabber.getImageWidth(), grabber.getImageHeight());recorder.setInterleaved(true);// https://trac.ffmpeg.org/wiki/StreamingGuiderecorder.setVideoOption("tune", "zerolatency");// 加速  零延迟//recorder.setVideoOption("flvflags", "no_duration_filesize");// 加速// https://trac.ffmpeg.org/wiki/Encode/H.264recorder.setVideoOption("preset", "ultrafast");recorder.setFrameRate(frameRate);// 设置帧率,重要!// Key frame interval, in our case every 2 seconds -> 30 (fps) * 2 = 60recorder.setGopSize(frameRate * 2);recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);// 编码,使用编码能让视频占用内存更小,根据实际自行选择
//        recorder.profile(AVCodecContext.FF_PROFILE_H264_CONSTRAINED_BASELINE);// https://trac.ffmpeg.org/wiki/Encode/H.264recorder.setVideoOption("crf", "28");// 2000 kb/s  720Precorder.setVideoBitrate(1000000);recorder.setFormat("flv");recorder.start();new Thread(new Runnable() {@Overridepublic void run() {try {// 获取屏幕捕捉的一帧// 屏幕录制,由于已经对音频进行了记录,需要对记录时间进行调整即可// 即上面调用了 recorder.recordSamples 需要重新分配时间,否则视频输出时长等于实际 的2倍
//                    while ((frame = grabber.grab()) != null) {boolean isGdi = false;int screenW = grabber.getImageWidth();int screenH = grabber.getImageHeight();while (true) {if (isStop) {try {// 停止recorder.stop();grabber.stop();// 释放内存,我们都知道c/c++需要手动释放资源recorder.release();grabber.release();log.info("停止直播完成");} catch (Exception e) {e.printStackTrace();}break;}Frame frame = grabber.grabFrame();if (frame == null) {isGdi = true;frame = imgFrame;} else if (isGdi) {//先判断分辨率int screenWt = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();int screenHt = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();if (screenWt == screenW && screenHt == screenH) {log.info("分辨率没有变化,无需重置");isGdi = false;} else {log.info("分辨率有变化,需要重置,马上停止");isStop = true;}}recorder.record(frame);}} catch (Exception e) {isStop = true;e.printStackTrace();}}}).start();}public static void main(String[] args) throws Exception {start();}}

可以用docker起一个srs进行推流播放。

# 先启动
docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 \ccr.ccs.tencentyun.com/ossrs/srs:4

再启动推流

效果图:

本示例使用的是SRS,也可以更新为其他的平台服务!启动后SRS控制台上就可以看见当前的直播流了


也可以进行预览,预览效果图图下:

java录屏直播推流相关推荐

  1. (第一版) 完全免费的屏幕采集\录屏\直播推流的一体化工具

    这是我的第二个免费软件了, 为了方便大家,也有博友提出有这个需求,所以写了这个桌面采集\录屏\推流的一体化工具. 作为一个基本的桌面采集软件,麻雀虽小五脏俱全. 它的功能也算强大了, 基本够用. 用过 ...

  2. (第二版) 完全免费的屏幕采集\录屏\直播推流的一体化工具

    第二版是第一版的优化, 只因怕有些同学会不注意会以为没有改变,所以新起一篇, 但介绍还是承接之前的内容. 下载地址: (第二版)完全免费的屏幕采集\\录屏\\直播推流的一体化工具 第二版界面稍有变化 ...

  3. Android PC投屏简单尝试(录屏直播)2—硬解章(MediaCodec+RMTP)

    代码地址 :https://github.com/deepsadness/MediaProjectionDemo 想法来源 上一边文章的最后说使用录制的Api进行录屏直播.本来这边文章是预计在5月份完 ...

  4. android实现录像功能吗,Android实现录屏直播(一)ScreenRecorder的简单分析

    应项目需求瞄准了Bilibili的录屏直播功能,基本就仿着做一个吧.研究后发现Bilibili是使用的MediaProjection 与 VirtualDisplay结合实现的,需要 Android ...

  5. c语言安卓录屏,手写 Android 录屏直播

    简介 观看手游直播时,我们观众端看到的是选手的屏幕上的内容,这是如何实现的呢?这篇博客将手写一个录屏直播 Demo,实现类似手游直播的效果 获取屏幕数据很简单,Android 系统有提供对应的服务,难 ...

  6. iOS录屏直播(二)Broadcast Upload Extension和Broadcast Setup UI Extension

    Morris_2019.06.13 上一篇总结了ReplayKit相关的知识点,实现了应用内的录屏功能,同时涉及到了很少一部分Broadcast Upload Extension和Broadcast ...

  7. iOS录屏直播(一)初识ReplayKit

    Morris_2019.05.08 本篇主要功能: 认识ReplayKit框架 RPScreenRecorder实现在应用内录屏功能 RPPreviewViewController查看录屏内容 RPB ...

  8. iOS rtmp 摄像头/录屏直播以及观看

    之前讲过如何在centos上使用nginx搭建rtmp服务器(链接),本文介绍一下iOS 端如何通过rtmp录屏直播以及观看,完整的工程代码地址(https://github.com/zxm006/R ...

  9. 直播源码:游戏录屏直播的基本实现方式

    移动端设备性能的提升,和手机直播行业的发展,催生了一大批直播细分行业,今天我们总结的是基于直播源码的手游录屏直播技术的基本实现方式. 大致的流程是手机申请录屏权限,手机录屏,开启手机实时将数据推向网络 ...

最新文章

  1. 科大讯飞全新1024:3大计划,200项A.I.能力,全链路驱动应用场景创新!
  2. UVA 10487 Closest Sums
  3. TP5.1类的自动加载
  4. Python __slots__ 作用
  5. fedora mysql gui_fedora8安装 mysql++失败!!装了一个晚上没搞定!!伤心阿!
  6. java中为按钮添加图片_我们可以在Java接口中为成员定义私有和受保护的修饰符吗?...
  7. php 页面开启错误提示,php开启与关闭错误提示
  8. python xposed_xposed + python 怎么爬取微信朋友圈的数据
  9. 对预检请求的响应未通过访问控制检查
  10. websocket使用指南
  11. TCP滑动窗口协议作用
  12. 用R做meta分析(附效应量计算神器)
  13. Java中SpringBoot项目集成Easy版支付宝支付
  14. sql server 2008服务无法启动的原因和解决办法
  15. QQ群文件下载速度慢怎么办
  16. 电脑系统更新完后,计算机管理服务中找不到mysql的服务
  17. php控制步进电机,步进电机的速度控制的原理及方法简介
  18. C# 很少人知道的科技
  19. Nessus之——Nessus的整理
  20. 7、TM4单片机学习之串口功能

热门文章

  1. 用python画小黄人步骤图-通过python将图片生成字符画
  2. 转:Python处理音频信号实战 : 手把手教你实现音乐流派分类和特征提取
  3. 【Cadence17.2】Capture CIS原理图设计
  4. 生鲜行业用新营销模式,为“冬令进补”造火围炉
  5. 硬件系统工程师宝典-好书推荐
  6. Matlab findcircle函数实现 霍夫变换——检测圆
  7. Mysql:insert date:SQL 错误 [1292] [22001]: Data truncation: Incorrect date value:
  8. 计算机什么ups又称在线式ups,在线式ups电源的介绍
  9. 基于STM32单片机的电子钟(Proteus仿真+程序)
  10. 数据库进阶3--表之间的关联关系