关于云计算:JavaCV的摄像头实战之五推流

38次阅读

共计 3559 个字符,预计需要花费 9 分钟才能阅读完成。

欢送拜访我的 GitHub

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

本篇概览

  • 本文是《JavaCV 的摄像头实战》的第五篇,一起来思考个问题:本地摄像头的内容,如何让网络上的其他人看见?
  • 这就波及到了推流,如下图,基于 JavaCV 的利用将摄像头的视频帧推送到媒体服务器,观看者用播放器软件近程连贯媒体服务器,就能观看摄像头的内容了:

  • 明天的次要工作就是开发上图的 JavaCV 利用,而后验证性能是否失常;

编码

  • 《JavaCV 的摄像头实战之一:根底》一文创立的 <font color=”red”>simple-grab-push</font> 工程中已写好父类 <font color=”blue”>AbstractCameraApplication</font>,本篇持续应用该工程,创立子类实现那些形象办法即可
  • 编码前先回顾父类的根底构造,如下图,粗体是父类定义的各个办法,红色块都是须要子类来实现形象办法,所以接下来,咱们以本地窗口预览为指标实现这三个红色办法即可:

  • 新建文件 <font color=”blue”>RecordCamera.java</font>,这是 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 办法,留神参数 <font color=”blue”>600</font> 示意抓取和录制的操作执行 600 秒:
    public static void main(String[] args) {new RecordCamera().action(600);
    }
  • 运行 main 办法,等到控制台输入下图红框的内容时,示意曾经开始推流:

  • 用本机或局域网内另一台电脑,用 VLC 软件关上方才推流的地址 <font color=”blue”>rtmp://192.168.50.43:21935/hls/camera</font>,稍等几秒钟后开始失常播放:

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

  • 至此,咱们已实现了推流性能,验证近程播放也失常,得益于 JavaCV 的弱小,整个过程是如此的轻松愉快,接下来请持续关注欣宸原创,《JavaCV 的摄像头实战》系列还会出现更多丰盛的利用;
  • 此刻聪慧的您肯定发现了问题:只推视频吗?连声音都没有,就这?没错,接下来的实战,咱们该挑战音频解决了

源码下载

  • 《JavaCV 的摄像头实战》的残缺源码可在 GitHub 下载到,地址和链接信息如下表所示 (https://github.com/zq2599/blo…):
名称 链接 备注
我的项目主页 https://github.com/zq2599/blo… 该我的项目在 GitHub 上的主页
git 仓库地址 (https) https://github.com/zq2599/blo… 该我的项目源码的仓库地址,https 协定
git 仓库地址 (ssh) git@github.com:zq2599/blog_demos.git 该我的项目源码的仓库地址,ssh 协定
  • 这个 git 我的项目中有多个文件夹,本篇的源码在 <font color=”blue”>javacv-tutorials</font> 文件夹下,如下图红框所示:

  • <font color=”blue”>javacv-tutorials</font> 外面有多个子工程,《JavaCV 的摄像头实战》系列的代码在 <font color=”red”>simple-grab-push</font> 工程下:

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

https://github.com/zq2599/blog_demos

正文完
 0