欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《JavaCV的摄像头实战》的第五篇,一起来考虑个问题:本地摄像头的内容,如何让网络上的其他人看见?

  • 这就涉及到了推流,如下图,基于JavaCV的应用将摄像头的视频帧推送到媒体服务器,观看者用播放器软件远程连接媒体服务器,就能观看摄像头的内容了:

  • 今天的主要工作就是开发上图的JavaCV应用,然后验证功能是否正常;

编码

  • 《JavaCV的摄像头实战之一:基础》一文创建的simple-grab-push工程中已写好父类AbstractCameraApplication,本篇继续使用该工程,创建子类实现那些抽象方法即可

  • 编码前先回顾父类的基础结构,如下图,粗体是父类定义的各个方法,红色块都是需要子类来实现抽象方法,所以接下来,咱们以本地窗口预览为目标实现这三个红色方法即可:

  • 新建文件RecordCamera.java,这是AbstractCameraApplication的子类,其代码很简单,接下来按上图顺序依次说明

  • 《JavaCV的摄像头实战之一:基础》中已部署好了媒体服务器,这里定义一个成员变量保存媒体服务器的推流地址,请您按自己的情况调整:

private static final String RECORD_ADDRESS = "rtmp://192.168.50.43:21935/hls/camera";
  • 还要准备一个成员变量,推流的时候在帧上添加时间戳:
protected long startRecordTime = 0L;
  • 将视频帧推送到媒体服务器的功能来自FrameRecorder,这是个抽象类,本篇用到的是其子类FFmpegFrameRecorder,所以定义FrameRecorder类型的成员变量:
	// 帧录制器
protected FrameRecorder recorder;
  • 然后是初始化操作,请注意各项参数设置(1280*720分辨率摄像头的情况):
    @Override
protected void initOutput() throws Exception {
// 实例化FFmpegFrameRecorder,将SRS的推送地址传入
recorder = FrameRecorder.createDefault(RECORD_ADDRESS, getCameraImageWidth(), getCameraImageHeight()); // 降低启动时的延时,参考
// https://trac.ffmpeg.org/wiki/StreamingGuide)
recorder.setVideoOption("tune", "zerolatency");
// 在视频质量和编码速度之间选择适合自己的方案,包括这些选项:
// ultrafast,superfast, veryfast, faster, fast, medium, slow, slower, veryslow
// ultrafast offers us the least amount of compression (lower encoder
// CPU) at the cost of a larger stream size
// at the other end, veryslow provides the best compression (high
// encoder CPU) while lowering the stream size
// (see: https://trac.ffmpeg.org/wiki/Encode/H.264)
// ultrafast对CPU消耗最低
recorder.setVideoOption("preset", "ultrafast");
// Constant Rate Factor (see: https://trac.ffmpeg.org/wiki/Encode/H.264)
recorder.setVideoOption("crf", "28");
// 2000 kb/s, reasonable "sane" area for 720
recorder.setVideoBitrate(2000000); // 设置编码格式
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 设置封装格式
recorder.setFormat("flv"); // FPS (frames per second)
// 一秒内的帧数
recorder.setFrameRate(getFrameRate());
// Key frame interval, in our case every 2 seconds -> 30 (fps) * 2 = 60
// 关键帧间隔
recorder.setGopSize((int)getFrameRate()*2); // 帧录制器开始初始化
recorder.start();
}
  • 接下来是output方法,关键是recorder.record,另外要注意时间戳的计算和设置:
    @Override
protected void output(Frame frame) throws Exception {
if (0L==startRecordTime) {
startRecordTime = System.currentTimeMillis();
} // 时间戳
recorder.setTimestamp(1000 * (System.currentTimeMillis()-startRecordTime)); // 存盘
recorder.record(frame);
}
  • 最后是处理视频的循环结束后,程序退出前要做的事情,即关闭帧抓取器:
    @Override
protected void releaseOutputResource() throws Exception {
recorder.close();
}
  • 另外还要注意两帧之间的延时,由于推流涉及到网络,因此不能像本地预览那样根据帧率严格计算,实际间隔要更小一些:
    @Override
protected int getInterval() {
// 相比本地预览,推流时两帧间隔时间更短
return super.getInterval()/4;
}
  • 至此,推流功能已开发完成,再写上main方法,注意参数600表示抓取和录制的操作执行600秒:
    public static void main(String[] args) {
new RecordCamera().action(600);
}
  • 运行main方法,等到控制台输出下图红框的内容时,表示已经开始推流:

  • 用本机或局域网内另一台电脑,用VLC软件打开刚才推流的地址rtmp://192.168.50.43:21935/hls/camera,稍等几秒钟后开始正常播放:

  • 还可用VLC的工具查看编码信息:

  • 至此,咱们已完成了推流功能,验证远程播放也正常,得益于JavaCV的强大,整个过程是如此的轻松愉快,接下来请继续关注欣宸原创,《JavaCV的摄像头实战》系列还会呈现更多丰富的应用;

  • 此刻聪明的您一定发现了问题:只推视频吗?连声音都没有,就这?没错,接下来的实战,咱们该挑战音频处理了

源码下载

名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本篇的源码在javacv-tutorials文件夹下,如下图红框所示:

  • javacv-tutorials里面有多个子工程,《JavaCV的摄像头实战》系列的代码在simple-grab-push工程下:

你不孤单,欣宸原创一路相伴

https://github.com/zq2599/blog_demos

JavaCV的摄像头实战之五:推流的更多相关文章

  1. JavaCV的摄像头实战之七:推流(带声音)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV的摄像头实战> ...

  2. JavaCV的摄像头实战之一:基础

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<JavaCV的摄像头实战>系列 &l ...

  3. JavaCV的摄像头实战之二:本地窗口预览

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. JavaCV的摄像头实战之四:抓图

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV的摄像头实战> ...

  5. JavaCV的摄像头实战之六:保存为mp4文件(有声音)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. JavaCV 采集摄像头和麦克风数据推送到流媒体服务器

    越来越觉得放弃JavaCV FFmpeg native API,直接使用JavaCV二次封装的API开发是很明智的选择,使用JavaCV二次封装的API开发避免了各种内存操作不当引起的crash. 上 ...

  7. [Java聊天室server]实战之五 读写循环(服务端)

    前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...

  8. 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统

    了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...

  9. kubebuilder实战之五:operator编码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. Laravel 使用 maatwebsite/excel 时长数字出现科学计数法的解决办法

    在使用 maatwebsite/excel 包导出Excel的时候,有的单元格里会存放手机号等一大串的数字,这一串数字会被Excel软件处理为科学计数法,在后续处理数据的时候会产生不小的麻烦,一个个去 ...

  2. .NET+Sqlite如何支持加密

    .NET+Sqlite如何支持加密 Sqlite SQLite 来源于公共领域 SQLite Is Public Domain. 确保代码不会受到任何专有或许可内容的污染,没有任何来自互联网上的未知来 ...

  3. Attention Is All You Need

    目录 概 主要内容 Positional Encoding auto_regressive 额外的细节 代码 Vaswani A., Shazeer N., Parmar N., Uszkoreit ...

  4. Product Integration

    目录 生存模型 连续情形 离散情形 统一 Richard D. Gill, Product integration 一般的积分是指黎曼积分, 其计算是把区域无限细分求和并取极限, 有另外一种积分是把区 ...

  5. Solon 1.6.11 发布。类似 Spring 的生态体系

    关于官网 千呼万唤始出来: https://solon.noear.org .整了一个月多了,总体样子有了...还得不断接着整! 关于 Solon Solon 是一个轻量级应用开发框架.支持 Web. ...

  6. 编写Java程序,前方有 3km 的道路障碍,4 辆普通车不能通过,必须等到清障车完成作业离开后,才能继续行驶。用程序来模拟这一过程的发生

    查看本章节 查看作业目录 需求说明: 前方有 3km 的道路障碍,4 辆普通车不能通过,必须等到清障车完成作业离开后,才能继续行驶.用程序来模拟这一过程的发生 实现思路: 创建清障车Wrecker类和 ...

  7. 微信支付 V3 RSA 加签踩坑

    最近在做微信支付,根据微信官方文档上的要求 用RSA加签去请求支付窗口的调起,下面详细列举支付开发过程: 当前项目的流程大概是,前端根据后端要求提交数据------->拿到后台返回的prepay ...

  8. VirtualBox 虚拟机怎样设置共享文件夹

    首次在VirtualBox装完系统后,很经常用到的操作就是:想将主机的东西拉倒虚拟机进行使用或安装,那怎么将主机的文件拿到虚拟机呢? 1.在虚拟机 > 设置中选择 >安装增强功能,经过这个 ...

  9. 学习git&github

    详细学习视频: 链接:https://pan.baidu.com/s/1Vub3YTo7uUUuGCJUCabBRQ 提取码:6q9x 一.git基本工作流程 我们先来理解下Git 工作区.暂存区和版 ...

  10. CentOS7添加开机启动服务或脚本

    方法一(rc.local) 改方式配置自动启动最为简单,只需要修改rc.local文件 由于在centos7中/etc/rc.d/rc.local的权限被降低了,所以需要赋予其可执行权 chmod + ...