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

上一次介绍了 JavaCV 采集摄像头及桌面视频数据,这次介绍一下如何采集摄像头和麦克风数据推送到流媒体服务器。

引入依赖

跟上一次一样,这里使用的还是最新的JavaCV库(1.5.5).

<properties>
<javacpp.version>1.5.5</javacpp.version>
</properties>
<dependencies>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>${javacpp.version}</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>${javacpp.version}</version>
</dependency>
</dependencies>

视频采集录制

JavaCV 采集摄像头及桌面视频数据 介绍了两种采集摄像头数据的方法,这里采用第一种,即使用 OpencvFrameGrabber 采集摄像头数据。

public class VideoRecorder implements Runnable {

  private static final int VIDEO_DEVICE_INDEX = 0;
private FFmpegFrameRecorder recorder;
private int width, height;
public VideoRecorder(FFmpegFrameRecorder recorder, int width, int height) {
this.recorder = recorder;
this.width = width;
this.height = height;
} @Override
public void run() {
try {
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(VIDEO_DEVICE_INDEX);
grabber.setImageWidth(width);
grabber.setImageHeight(height);
grabber.start(); long startTS = 0, videoTS = 0;
Frame frame = null;
while (!Thread.interrupted() && (frame = grabber.grab()) != null) {
if (startTS == 0) {
startTS = System.currentTimeMillis();
}
videoTS = 1000 * (System.currentTimeMillis() - startTS);
if (videoTS > recorder.getTimestamp()) {
recorder.setTimestamp(videoTS);
}
recorder.record(frame);
} grabber.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

音频采集录制

音频采集直接使用JDK的API即可,直接读麦克风的数据塞给录制器,采样率为44100,16bit,小端模式。

public class AudioRecoder implements Runnable {

  private FFmpegFrameRecorder recorder;
private int channels;
private int sampleRate;
public AudioRecoder(FFmpegFrameRecorder recorder, int sampleRate, int channels) {
this.recorder = recorder;
this.sampleRate = sampleRate;
this.channels = channels;
} @Override
public void run() {
try {
AudioFormat format = new AudioFormat(Float.valueOf(sampleRate), 16, channels, true, false);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, format));
line.open(format);
line.start(); int sampleRate = (int) format.getSampleRate();
int numChannels = format.getChannels();
byte[] buffer = new byte[sampleRate * numChannels]; while (!Thread.interrupted()) {
int nBytesRead = 0;
while (nBytesRead == 0) {
nBytesRead = line.read(buffer, 0, line.available());
}
int nSamplesRead = nBytesRead / 2;
short[] samples = new short[nSamplesRead];
ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);
ShortBuffer sBuff = ShortBuffer.wrap(samples, 0, nSamplesRead);
recorder.recordSamples(sampleRate, numChannels, sBuff);
}
} catch (Exception e) {
e.printStackTrace();
}
} }

录制推流

这里的录制推流涉及音频和视频,音频和视频分开线程采集并录制,这样可以降低延迟,在录制推流方面还可以通过设置录制参数降低延迟:

recorder.setVideoOption("tune", "zerolatency");
recorder.setVideoOption("preset", "ultrafast");

启动录制推流器,视频采集录制线程和音频采集录制线程,开始推流:

recorder.start();
Thread vt = new Thread(new VideoRecorder(recorder, width, height));
Thread at = new Thread(new AudioRecoder(recorder, sampleRate, channels)); vt.start();
at.start(); vt.join();
at.join();

效果展示

可以使用VLC拉取程序的推流查看效果:

拉流的音视频流信息:

录制推流完整源码可以在公众号上获取

=========================================================

关注公众号 “HiIT青年” 发送 “javacv-recoder” 获取。(如果没有收到回复,可能是你之前取消过关注。)



关注公众号,阅读更多文章。

JavaCV 采集摄像头和麦克风数据推送到流媒体服务器的更多相关文章

  1. EasyDarwin开源手机直播方案:EasyPusher手机直播推送,EasyDarwin流媒体服务器,EasyPlayer手机播放器

    在不断进行EasyDarwin开源流媒体服务器的功能和性能完善的同时,我们也配套实现了目前在安防和移动互联网行业比较火热的移动端手机直播方案,主要就是我们的 EasyPusher直播推送项目 和 Ea ...

  2. javaCV开发详解之6:本地音频(话筒设备)和视频(摄像头)抓取、混合并推送(录制)到服务器(本地)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  3. JavaCV 采集摄像头及桌面视频数据

    javacv 封装了javacpp-presets库很多native API,简化了开发,对java程序员来说比较友好. 之前使用JavaCV库都是使用ffmpeg native API开发,这种方式 ...

  4. C# 数据推送 实时数据推送 轻量级消息订阅发布 多级消息推送 分布式推送

    前言 本文将使用一个NuGet公开的组件技术来实现数据订阅推送功能,由服务器进行推送数据,客户端订阅指定的数据后,即可以接收服务器推送过来的数据,包含了自动重连功能,使用非常方便 nuget地址:ht ...

  5. 使用Node.js实现数据推送

    业务场景:后端更新数据推送到客户端(Java部分使用Tomcat服务器). 后端推送数据的解决方案有很多,比如轮询.Comet.WebSocket. 1. 轮询对于后端来说开发成本最低,就是按照传统的 ...

  6. 基于Web的数据推送技术(转)

    基于Web的数据推送技术 对于实时性数据显示要求比较高的系统,比如竞价,股票行情,实时聊天等,我们的解决方案有以下几种.1. HTTP请求发送模式,一般可以基于ajax的请求,比如每3秒一次访问下服务 ...

  7. javascript之数据推送

    我们使用ajax与后台服务进行交互,常常是通过触发事件来单次交互,但对于有些web应用来说,需要前台与后台保持长连接,前端不定时地接收后台推送的数据信息, 例如:股票行情分析.聊天室和网页在线游戏等. ...

  8. HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送(C#示例)

    传统的WEB应用程序通信时的简单时序图: 现在Web App中,大都有Ajax,是这样子: HTML5有一个Server-Sent Events(SSE)功能,允许服务端推送数据到客户端.(通常叫数据 ...

  9. SSE技术详解:使用 HTTP 做服务端数据推送应用的技术

    SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议. 严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来 ...

随机推荐

  1. vscode & typescript & optional-chaining bug

    vscode & typescript & optional-chaining bug https://www.cnblogs.com/xgqfrms/p/11745541.html ...

  2. js 在浏览器中使用 monaco editor

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  3. svg opacity & fill-opacity & stroke-opacity

    svg opacity & fill-opacity & stroke-opacity opacity = ill-opacity + stroke-opacity https://s ...

  4. requestAnimationFrame & canvas

    requestAnimationFrame & canvas https://codepen.io/xgqfrms/pen/jOEPjLJ See the Pen requestAnimati ...

  5. flutter 长按图片保存到手机

    main.dart import 'dart:io'; import 'package:flutter/material.dart'; import 'package:http/http.dart' ...

  6. MySQL 修改数据表

    修改数据表: 创建数据表 更改表明 更改字段数据类型 更改字段名称 更改字段名称和数据类型 为表添加新字段 将字段顺序改为第一位 将字段顺序改为另一个字段之后 删除字段 1 use test; 2 3 ...

  7. 07.k近邻算法kNN

    1.将数据分为测试数据和预测数据 2.数据分为data和target,data是矩阵,target是向量 3.将每条data(向量)绘制在坐标系中,就得到了一系列的点 4.根据每条data的targe ...

  8. c#(winform)获取本地打印机

    引用 using System.Drawing.Printing; //代码 PrintDocument prtdoc = new PrintDocument(); string strDefault ...

  9. oracle 19c 导入 12c ORA-39002 ORA-39358

    直接用19c导出的dmp文件导入到12c,报错: ORA-39002: invalid operation ORA-39358: Export dump file version 19.0.0.0.0 ...

  10. Java基础语法:包机制

    为了更好地组织类,Java 提供了包(package)机制. 这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class).接口(interface).枚举(enumerations)和注释( ...