首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JavaCV的摄像头实战之五:推流

JavaCV的摄像头实战之五:推流

作者头像
程序员欣宸
发布于 2021-12-07 02:04:26
发布于 2021-12-07 02:04:26
1.7K00
代码可运行
举报
文章被收录于专栏:实战docker实战docker
运行总次数:0
代码可运行

本篇概览

  • 本文是《JavaCV的摄像头实战》的第五篇,一起来考虑个问题:本地摄像头的内容,如何让网络上的其他人看见?
  • 这就涉及到了推流,如下图,基于JavaCV的应用将摄像头的视频帧推送到媒体服务器,观看者用播放器软件远程连接媒体服务器,就能观看摄像头的内容了:
  • 今天的主要工作就是开发上图的JavaCV应用,然后验证功能是否正常;

编码

  • 《JavaCV的摄像头实战之一:基础》一文创建的simple-grab-push工程中已写好父类AbstractCameraApplication,本篇继续使用该工程,创建子类实现那些抽象方法即可
  • 编码前先回顾父类的基础结构,如下图,粗体是父类定义的各个方法,红色块都是需要子类来实现抽象方法,所以接下来,咱们以本地窗口预览为目标实现这三个红色方法即可:
  • 新建文件RecordCamera.java,这是AbstractCameraApplication的子类,其代码很简单,接下来按上图顺序依次说明
  • 《JavaCV的摄像头实战之一:基础》中已部署好了媒体服务器,这里定义一个成员变量保存媒体服务器的推流地址,请您按自己的情况调整:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static final String RECORD_ADDRESS = "rtmp://192.168.50.43:21935/hls/camera";
  • 还要准备一个成员变量,推流的时候在帧上添加时间戳:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protected long startRecordTime = 0L;
  • 将视频帧推送到媒体服务器的功能来自FrameRecorder,这是个抽象类,本篇用到的是其子类FFmpegFrameRecorder,所以定义FrameRecorder类型的成员变量:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 帧录制器
    protected FrameRecorder recorder;
  • 然后是初始化操作,请注意各项参数设置(1280*720分辨率摄像头的情况):
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @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,另外要注意时间戳的计算和设置:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    protected void output(Frame frame) throws Exception {
        if (0L==startRecordTime) {
            startRecordTime = System.currentTimeMillis();
        }

        // 时间戳
        recorder.setTimestamp(1000 * (System.currentTimeMillis()-startRecordTime));

        // 存盘
        recorder.record(frame);
    }
  • 最后是处理视频的循环结束后,程序退出前要做的事情,即关闭帧抓取器:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    protected void releaseOutputResource() throws Exception {
        recorder.close();
    }
  • 另外还要注意两帧之间的延时,由于推流涉及到网络,因此不能像本地预览那样根据帧率严格计算,实际间隔要更小一些:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    protected int getInterval() {
        // 相比本地预览,推流时两帧间隔时间更短
        return super.getInterval()/4;
    }
  • 至此,推流功能已开发完成,再写上main方法,注意参数600表示抓取和录制的操作执行600秒:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public static void main(String[] args) {
        new RecordCamera().action(600);
    }
  • 运行main方法,等到控制台输出下图红框的内容时,表示已经开始推流:
  • 用本机或局域网内另一台电脑,用VLC软件打开刚才推流的地址rtmp://192.168.50.43:21935/hls/camera,稍等几秒钟后开始正常播放:
  • 还可用VLC的工具查看编码信息:
  • 至此,咱们已完成了推流功能,验证远程播放也正常,得益于JavaCV的强大,整个过程是如此的轻松愉快,接下来请继续关注欣宸原创,《JavaCV的摄像头实战》系列还会呈现更多丰富的应用;
  • 此刻聪明的您一定发现了问题:只推视频吗?连声音都没有,就这?没错,接下来的实战,咱们该挑战音频处理了

源码下载

  • 《JavaCV的摄像头实战》的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):

名称

链接

备注

项目主页

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工程下:
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/12/02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JavaCV的摄像头实战之七:推流(带声音)
本篇概览 本文是《JavaCV的摄像头实战》的第七篇,在《JavaCV的摄像头实战之五:推流》一文中,咱们将摄像头的内容推送到媒体服务器,再用VLC成功播放,相信聪明的您一定觉察到了一缕瑕疵:没有声音 虽然《JavaCV的摄像头实战》系列的主题是摄像头处理,但显然音视频健全才是最常见的情况,因此就在本篇补全前文的不足吧:编码实现摄像头和麦克风的推流,并验证可以成功远程播放音视频 关于音频的采集和录制 本篇的代码是在《JavaCV的摄像头实战之五:推流》源码的基础上增加音频处理部分 编码前,咱们先来分析一下,
程序员欣宸
2021/12/07
1.9K0
JavaCV的摄像头实战之七:推流(带声音)
JavaCV的摄像头实战之三:保存为mp4文件
本篇概览 本文是《JavaCV的摄像头实战》的第三篇,如题,咱们一起实践如何将摄像头的视频内容保存为MP4文件 编码 《JavaCV的摄像头实战之一:基础》一文创建的simple-grab-push工程中已写好父类AbstractCameraApplication,本篇继续使用该工程,创建子类实现那些抽象方法即可 编码前先回顾父类的基础结构,如下图,粗体是父类定义的各个方法,红色块都是需要子类来实现抽象方法,所以接下来,咱们以本地窗口预览为目标实现这三个红色方法即可: 新建文件RecordCameraS
程序员欣宸
2021/12/07
9831
JavaCV的摄像头实战之三:保存为mp4文件
JavaCV的摄像头实战之一:基础
关于《JavaCV的摄像头实战》系列 《JavaCV的摄像头实战》顾名思义,是使用JavaCV框架对摄像头进行各种处理的实战集合,这是欣宸作为一名Java程序员,在计算机视觉(computer vision)领域的一个原创系列,通过连续的编码实战,与您一同学习掌握视频、音频、图片等资源的各种操作 另外要说明的是,整个系列使用的摄像头是USB摄像图或者笔记本的内置摄像头,并非基于网络访问的智能摄像头 本篇概览 作为整个系列的开篇,本文非常重要,从环境到代码的方方面面,都会为后续文章打好基础,简单来说本篇由以下
程序员欣宸
2021/12/07
1.9K2
JavaCV的摄像头实战之一:基础
JavaCV的摄像头实战之八:人脸检测
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《JavaCV的摄像头实战》的第八篇,前面的操作夯实了的帧和流处理的基本功,接下来开始实现一些常见的CV能力,就从本篇的人检测别开始吧 OpenCV中常用的人脸检测是基于Haar特征的级联分类器,本篇借助JavaCV来使用该分类器实现人脸检测 简单的设计 编码之前先把要做的事情梳理一下: 检测功能可能用在多个场景:窗口预览、推流、存文件都可能用到
程序员欣宸
2022/01/06
8410
JavaCV的摄像头实战之八:人脸检测
JavaCV的摄像头实战之二:本地窗口预览
本篇概览 前文《JavaCV的摄像头实战之一:基础》已经为整个系列做好了铺垫,接下来的文章会专注于如何使用来自摄像头的数据,本篇先从最简单的开始:本地窗口预览 编码 前文创建的simple-grab-push工程中已经准备好了父类AbstractCameraApplication,所以本篇继续使用该工程,创建子类实现那些抽象方法即可 编码前先回顾父类的基础结构,如下图,粗体是父类定义的各个方法,红色块都是需要子类来实现抽象方法,所以接下来,咱们以本地窗口预览为目标实现这三个红色方法即可: 新建文件Pre
程序员欣宸
2021/12/07
6420
JavaCV的摄像头实战之二:本地窗口预览
JavaCV的摄像头实战之四:抓图
本篇概览 本文是《JavaCV的摄像头实战》的第四篇,也是整个系列最简单轻松的一篇,寥寥几行代码实现从摄像头抓图的功能; 编码 《JavaCV的摄像头实战之一:基础》一文创建的simple-grab-push工程中已写好父类AbstractCameraApplication,本篇继续使用该工程,创建子类实现那些抽象方法即可 编码前先回顾父类的基础结构,如下图,粗体是父类定义的各个方法,红色块都是需要子类来实现抽象方法,所以接下来,咱们以本地窗口预览为目标实现这三个红色方法即可: 虽然父类要求子类必须实现
程序员欣宸
2021/12/07
6960
JavaCV的摄像头实战之四:抓图
JavaCV的摄像头实战之六:保存为mp4文件(有声音)
本篇概览 本文是《JavaCV的摄像头实战》的第六篇,在《JavaCV的摄像头实战之三:保存为mp4文件》一文中,咱们将摄像头的内容录制为mp4文件,相信聪明的您一定觉察到了一缕瑕疵:没有声音 虽然《JavaCV的摄像头实战》系列的主题是摄像头处理,但显然音视频健全才是最常见的情况,因此就在本篇补全前文的不足吧:编码实现摄像头和麦克风的录制 关于音频的采集和录制 本篇的代码是在《JavaCV的摄像头实战之三:保存为mp4文件》源码的基础上增加音频处理部分 编码前,咱们先来分析一下,增加音频处理后具体的代码逻
程序员欣宸
2021/12/07
9110
JavaCV的摄像头实战之六:保存为mp4文件(有声音)
JavaCV的摄像头实战之八:人脸识别
本篇概览 本文是《JavaCV的摄像头实战》的第八篇,前面的操作夯实了的帧和流处理的基本功,接下来开始实现一些常见的CV能力,就从本篇的人脸识别开始吧 OpenCV中常用的人脸识别是基于Haar特征的级联分类器,本篇借助JavaCV来使用该分类器实现人脸识别 简单的设计 编码之前先把要做的事情梳理一下: 识别功能可能用在多个场景:窗口预览、推流、存文件都可能用到,所以识别功能的代码最好独立出来,不要和预览、推流这些代码写在一起,如下图,识别的接口DetectService会作为每个应用的成员变量存在:
程序员欣宸
2021/12/07
2.2K0
JavaCV的摄像头实战之八:人脸识别
JavaCV的摄像头实战之十二:性别检测
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《JavaCV的摄像头实战》系列的第十二篇,咱们来开发一个实用功能:识别性别并显示在预览页面,如下图: 今天的代码,主要功能如下图所示: 如果您看过《JavaCV的摄像头实战》系列的其他文章,就会发现上图中只有蓝色部分是新增内容,其余的步骤都是固定套路,《JavaCV的摄像头实战》系列的每一个应用玩的都是相同套路:别看步骤挺
程序员欣宸
2022/01/06
7510
JavaCV的摄像头实战之十二:性别检测
JavaCV的摄像头实战之十三:年龄检测
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《JavaCV的摄像头实战》系列的第十三篇,前文《JavaCV的摄像头实战之十二:性别检测》中,借助训练好的卷积神经网络模型开发出了识别性别的应用,今天在前文基础上做少量改动,实现年龄识别的功能,效果如下图: 应用主要功能如下图所示: 如果您看过《JavaCV的摄像头实战》系列的其他文章,就会发现上图中只有蓝色部分是新增内容,其
程序员欣宸
2022/01/06
6060
JavaCV的摄像头实战之十三:年龄检测
JavaCV推流实战(MP4文件)
本篇概览 自己的mp4文件,如何让更多的人远程播放?如下图所示: 这里简单解释一下上图的功能: 部署开源流媒体服务器SRS 开发名为PushMp4的java应用,该应用会读取本机磁盘上的Mp4文件,读取每一帧,推送到SRS上 每个想看视频的人,就在自己电脑上用流媒体播放软件(例如VLC)连接SRS,播放PushMp4推上来的视频 今天咱们就来完成上图中的实战,整个过程分为以下步骤: 环境信息 准备MP4文件 用docker部署SRS java应用开发和运行 VLC播放 环境信息 本次实战,我这边涉及
程序员欣宸
2021/12/07
1.5K2
JavaCV推流实战(MP4文件)
JavaCV人脸识别三部曲之一:视频中的人脸保存为图片
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于人脸识别 本文是《JavaCV人脸识别三部曲》的第一篇,在《JavaCV的摄像头实战之八:人脸检测》一文中,实现了检测人脸并用方框标注出来,但仅框出人脸作用不大,最好是识别出此人的身份,这样就能做很多事情了,例如签到、告警等,这就是接下来咱们要挑战的人脸识别 人脸识别涉及到两个步骤:训练和识别,接下来简单说明解释一下 先看什么是训练,如下图,用两位天王
程序员欣宸
2022/01/06
1.6K0
JavaCV人脸识别三部曲之一:视频中的人脸保存为图片
JavaCV人脸识别三部曲之三:识别和预览
-若真如上图所示,那么显然confidence越小,是郭富城的可能性就越大了,接下来再去找一些权威的说法:
程序员欣宸
2022/01/06
1.2K1
JavaCV人脸识别三部曲之三:识别和预览
JavaCV人脸识别三部曲之二:训练
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《JavaCV人脸识别三部曲》的第二篇,前文《视频中的人脸保存为图片》咱们借助摄像头为两位群众演员生成大量人脸照片,如下图,群众演员A的照片保存在E:\temp\202112\18\001\man,B的照片保存在E:\temp\202112\18\001\woman: 照片准备好,并且每张照片的身份都已确定,本篇要做的就是用上述照片生成模
程序员欣宸
2022/01/06
8490
JavaCV人脸识别三部曲之二:训练
Java版人脸跟踪三部曲之三:编码实战
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 《Java版人脸跟踪三部曲》全文链接 《极速体验》 《开发设计》 《编码实战》 本篇概览 作为《Java版人脸跟踪三部曲》系列的终篇,本文会与大家一起写出完整的人脸跟踪应用代码 前文《开发设计》中,已经对人脸跟踪的核心技术、应用主流程、异常处理等方方面面做了详细设计,建议您简单回顾一下 接下来,自顶向下,先整体设计好主框架和关键类 程序主框架和关键类 听欣宸唠叨
程序员欣宸
2022/04/13
7330
Java版人脸跟踪三部曲之三:编码实战
JavaCV的摄像头实战之十四:口罩检测
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《JavaCV的摄像头实战》系列的第十四篇,如标题所说,今天的功能是检测摄像头内的人是否带了口罩,把检测结果实时标注在预览窗口,如下图所示: 整个处理流程如下,实现口罩检测的关键是将图片提交到百度AI开放平台,然后根据平台返回的结果在本地预览窗口标识出人脸位置,以及此人是否带了口罩: 问题提前告知 依赖云平台处理业务的一个典型问题,就
程序员欣宸
2022/04/13
9620
JavaCV的摄像头实战之十四:口罩检测
直播推流技术底层逻辑详解与私有化实现方案-以rmtp rtc hls为例-优雅草卓伊凡
由于我们的甲方客户要开始为我们项目产品上加入私有化的直播,这块不得不又捡起来曾经我们做直播推流的事情了,其实私有化直播一直并不是一件容易的事情,现在大部分市面上的产品是采用了云服务第三方来做支持的,要做私有化并且能满足大量用户其实不是简单的事情。
卓伊凡
2025/07/14
2510
Kurento实战之六:云端录制
本篇概览 本文是《Kurento实战》系列的第六篇,前文咱们学习了通过KMS的组件播放流媒体,今天再来体验KMS的另一个强大功能:音视频录制,在播放的过程中,将音视频内容存储在KMS所在的硬盘上; 整个系统的架构如下图所示,和《媒体播放》相比,蓝色是新增内容,可见依旧保持了前文架构,在此基础上,本文会使用一个新的组件RecorderEndpoint,借助此组件,取得PlayerEndpoint上的音视频内容,再将其以mkv、mp4、webm等格式存储在硬盘上: 源码下载 本篇实战中的完整源码可在GitH
程序员欣宸
2021/12/07
9570
Kurento实战之六:云端录制
Java版流媒体编解码和图像处理(JavaCPP+FFmpeg)
FFmpeg、JavaCPP、JavaCV的关系 先简单的梳理一下FFmpeg、JavaCPP、JavaCV的关系: FFmpeg、OpenCV可以理解成C语言版的本地库(Native library),Java应用无法直接使用 JavaCPP将FFmpeg、OpenCV这些常用库做了包装(wrapper),使得Java应用也能使用这些Native API(JavaCPP的底层实现是JNI) 这些JavaCPP包装后的API,被JavaCV封装成了工具类(utility classes),这些工具类比原生A
程序员欣宸
2021/12/07
2.4K0
Java版流媒体编解码和图像处理(JavaCPP+FFmpeg)
Java版人脸跟踪三部曲之一:极速体验
-《Java版人脸跟踪三部曲》系列是欣宸的又一原创,目标是通过理论加实战,与大家一同了解CamShift(连续自适应均值漂移)算法在Java领域的实际应用,整个系列由以下三篇文章组成:
程序员欣宸
2022/04/13
4910
Java版人脸跟踪三部曲之一:极速体验
推荐阅读
相关推荐
JavaCV的摄像头实战之七:推流(带声音)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档