业务需求

最近公司在做养老相关的业务,现在需要子女从小程序端对家里的老人通过家庭终端交互屏进行实时看护。

解决方案

第三方的一些现成的服务:腾讯音视频通话、直播功能; 阿里的音视频通信;两者都挺好的,但是需要收费因此放弃决定自己搭建一套直播流服务;

先看效果(自己服务器配置低有延迟、放到公司服务器上很流畅、清楚)

使用工具

Nginx、Nginx-Rtmp-Module

下载地址

Nginx:https://nginx.org/en/download.html

Nginx-Rtmp-Module:https://github.com/arut/nginx-rtmp-module

软件安装

1、下载Nginx
wget https://nginx.org/download/nginx-1.21.6.tar.gz
2、将压缩包移到需要的安装目录下
mv  nginx-1.21.6.tar.gz  /usr/local
3、下载Nginx-Rtmp-Module
git clone https://github.com/arut/nginx-rtmp-module.git
4、将文件移到需要安装目录下
mv nginx-rtmp-module  /usr/local
5、进入目录
cd /usr/local
6、解压Nginx压缩包
tar -zxvf nginx-1.21.6.tar.gz
7、进入Nginx目录
cd nginx-1.21.6
8、配置
./configure --prefix=/usr/local/nginx --add-module=../nginx-rtmp-module --with-http_ssl_module
9、安装
make && make install
10、配置 nginx.conf 文件(/usr/local/nginx/conf下)
#user  nobody;
# multiple workers works !
worker_processes 2; #pid logs/nginx.pid;
events {
worker_connections 8192;
} rtmp {
server {
listen 1935;
chunk_size 4000;
application live {
live on; record all;
record_path /tmp/av;
record_max_size 1K; record_unique on;
allow publish all;
deny publish all; allow play all;
}
}
} http {
include mime.types;
default_type application/octet-stream; sendfile off; server_names_hash_bucket_size 128; client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 30;
send_timeout 10;
keepalive_requests 10;
#gzip on;
server {
listen 8080;
server_name localhost; location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root nginx-rtmp-module/;
}
location /control {
rtmp_control all;
} location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

11、启动Nginx

cd /usr/local/nginx/sbin
./nginx -t
./nginx -s reload

启动时可能会包错:nginx: [error] invalid PID number "" in "/usr/local/nginx/logs/nginx.pid"

解决:

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

12、测试(注意打开服务器8080和1935端口安全组)

访问服务器外网 IP:8080

Java编码实现直播推流、拉流

1、新建SpringBoot项目 pom.xml 引入所需的jar包
        <!--直播相关依赖-->
<!--javacv-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/opencv-platform -->
<!--opencv-->
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
<version>4.0.1-1.4.4</version>
</dependency>
2、新建直播推流实现类
package com.honyar.iot.vedio.pushandpullimpl;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.opencv_core.IplImage;
import javax.swing.*;
public class PushStream { /**
* 直播推流实现
*/
public void getRecordPush(String outputPath, int v_rs) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException {
//创建采集器
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); //本地摄像头默认为0
//开启采集器
try {
grabber.start();
} catch (Exception e) {
try {
grabber.restart(); //一次重启尝试
} catch (Exception e2) {
throw e;
}
}
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage(); //转换器
Frame grabframe = grabber.grab(); //获取一帧
IplImage grabbedImage = null;
if (grabframe != null) {
grabbedImage = converter.convert(grabframe); //将这一帧转换为IplImage
}
//创建录制器
FrameRecorder recorder;
recorder = FrameRecorder.createDefault(outputPath, 1280, 720); //输出路径,画面高,画面宽
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //设置编码格式
recorder.setFormat("flv");
recorder.setFrameRate(v_rs);
recorder.setGopSize(v_rs); //开启录制器
try {
recorder.start();
} catch (java.lang.Exception e) {
try {
if (recorder != null) { //尝试重启录制器
recorder.stop();
recorder.start();
}
} catch (java.lang.Exception e1) {
e.printStackTrace();
}
} //直播效果展示窗口
CanvasFrame frame = new CanvasFrame("主播-菜鸡-德华", CanvasFrame.getDefaultGamma() / grabber.getGamma());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true); //推流
while (frame.isVisible() && (grabframe = grabber.grab()) != null) {
frame.showImage(grabframe); //展示直播效果
grabbedImage = converter.convert(grabframe);
Frame rotatedFrame = converter.convert(grabbedImage); if (rotatedFrame != null) {
recorder.record(rotatedFrame);
} Thread.sleep(50); //50毫秒/帧
}
}
}
3、新建直播推流启动类
package com.honyar.iot.vedio.start;

import com.honyar.iot.vedio.pushandpullimpl.PushStream;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration; /**
* 直播推流--启动
*/
@SpringBootApplication
@Configuration
public class PushApplication {
public static void main(String[] args) throws Exception {
//设置rtmp服务器推流地址(写你自己服务器外网地址)
String outputPath = "rtmp://xxx.xx.xxx.xx:1935/live/address";
PushStream recordPush = new PushStream();
recordPush.getRecordPush(outputPath, 25);
}
}
4、新建直播拉流实现类
package com.honyar.iot.vedio.pushandpullimpl;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.opencv_core.IplImage;
import javax.swing.*;
public class PushStream { /**
* 直播推流实现
*/
public void getRecordPush(String outputPath, int v_rs) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException {
//创建采集器
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); //本地摄像头默认为0
//开启采集器
try {
grabber.start();
} catch (Exception e) {
try {
grabber.restart(); //一次重启尝试
} catch (Exception e2) {
throw e;
}
}
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage(); //转换器
Frame grabframe = grabber.grab(); //获取一帧
IplImage grabbedImage = null;
if (grabframe != null) {
grabbedImage = converter.convert(grabframe); //将这一帧转换为IplImage
}
//创建录制器
FrameRecorder recorder;
recorder = FrameRecorder.createDefault(outputPath, 1280, 720); //输出路径,画面高,画面宽
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //设置编码格式
recorder.setFormat("flv");
recorder.setFrameRate(v_rs);
recorder.setGopSize(v_rs); //开启录制器
try {
recorder.start();
} catch (java.lang.Exception e) {
try {
if (recorder != null) { //尝试重启录制器
recorder.stop();
recorder.start();
}
} catch (java.lang.Exception e1) {
e.printStackTrace();
}
} //直播效果展示窗口
CanvasFrame frame = new CanvasFrame("主播-菜鸡-德华", CanvasFrame.getDefaultGamma() / grabber.getGamma());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true); //推流
while (frame.isVisible() && (grabframe = grabber.grab()) != null) {
frame.showImage(grabframe); //展示直播效果
grabbedImage = converter.convert(grabframe);
Frame rotatedFrame = converter.convert(grabbedImage); if (rotatedFrame != null) {
recorder.record(rotatedFrame);
} Thread.sleep(50); //50毫秒/帧
}
}
}
5、新建直播拉流启动类(可以多建几个模拟多个客户端)
package com.honyar.iot.vedio.start;

import com.honyar.iot.vedio.pushandpullimpl.PullStream;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration; /**
* 直播拉流--启动
*/
@SpringBootApplication
@Configuration
public class PullApplication1 {
public static void main(String[] args) throws Exception {
//rtmp服务器拉流地址(自己服务器外网地址)
String inputPath = "rtmp://xxx.xx.xxx.xx/live/address";
PullStream pullStream = new PullStream();
pullStream.getPullStream(inputPath);
}
}

6、测试

nginx + nginx-rtmp-module搭建直播流服务器实现推流实时直播功能的更多相关文章

  1. 搭建rtmp直播流服务之1:使用nginx搭建rtmp直播流服务器(nginx-rtmp模块的安装以及rtmp直播流配置)

    欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) 一.方案简要 首先通过对开发方案的仔细研究(实时监控.流媒体.直播流方案的数据源-->协议转换-->服务器--&g ...

  2. 极速搭建RTMP直播流服务器+webapp (vue) 简单实现直播效果

    在尝试使用webRTC实现webapp直播失败后,转移思路开始另外寻找可行的解决方案.在网页上尝试使用webRTC实现视频的直播与看直播,在谷歌浏览器以及safari浏览器上测试是可行的.但是基于基座 ...

  3. 使用 nginx 和 rtmp 插件搭建视频直播和点播服务器

    使用 nginx 和 rtmp 模块 ,可以很容易地搭建一个视频直播和点播服务器出来. 首先,看一下最经典的参考文献: How to set up your own private RTMP serv ...

  4. 搭建RTMP直播流服务器

    最近项目比较紧张,所以没什么时间写博客,正好这几天没什么事,赶紧记录下自己最近所学. 环境配置 服务器选用 服务器我选择的是小鸟云 ,原因很简单,他的个人用户有3个月免费使用时间. 服务器环境 Win ...

  5. 利用docker搭建RTMP直播流服务器实现直播

    一.rtmp服务器搭建 环境: centos 7.* 1.先安装docker(省略) 2.下载docker容器 docker pull alfg/nginx-rtmp 3.运行容器(记得打开防火墙端口 ...

  6. 利用Docker挂载Nginx-rtmp(服务器直播流分发)+FFmpeg(推流)+Vue.js结合Video.js(播放器流播放)来实现实时网络直播

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_75 众所周知,在视频直播领域,有不同的商家提供各种的商业解决方案,其中比较靠谱的服务商有阿里云直播,腾讯云直播,以及又拍云和网易云 ...

  7. nginx搭建mp4流服务器

    流媒体服务器 流媒体指以流方式在网络中传送音频.视频和多媒体文件的媒体形式.相对于下载后观看的网络播放形式而言,流媒体的典型特征是把连续的音频和视频信息压缩后放到网络服务器上,用户边下载边观看,而不必 ...

  8. Nginx和Squid配合搭建的Web服务器前端系统

    这个架构是目前我个人觉得比较稳妥并且最方便的架构,易于多数人接受: 前端的lvs和squid,按照安装方法,把epoll打开,配置文件照搬,基本上问题不多. 这个架构和app_squid架构的区别,也 ...

  9. Linux----CentOS-7搭建免流服务器

    本次实验采用腾讯云服务器:https://cloud.tencent.com/ 大学生身份的可以看看有没有什么活动购买 其他身份的78一个月 关于腾讯云服务器的使用可以看看腾讯云的使用手册 本博客涉及 ...

随机推荐

  1. Pycharm连接MySQL步骤及注意点

    1.数据库连接修改MySQL: 默认:MySQLDB #MySQLDB只支持Python2,暂不支持python3,所以要修改, 修改成:pymysql,在每个项目中都需要先导入pymysql模块, ...

  2. 如何通过HibernateDaoSupport将Spring和Hibernate?

    用 Spring 的 SessionFactory 调用 LocalSessionFactory.集成过程分三步: 配置 the Hibernate SessionFactory. 继承 Hibern ...

  3. ctfhub 双写绕过 文件头检查

    双写绕过 进入环境 上传一句话木马 上传路径感觉不对检查源代码 从此处可以看出需要双写绕过 使用bp抓包 此处这样修改即可双写绕过 使用蚁剑连接 即可找到flag 文件头检查 进入环境 上传一句话木马 ...

  4. 移动端的vw px rem之间换算

    一.vw px rem em是什么 1.vw:就是相对视口宽度(Viewport Width).1vw = 1% * 视口宽度.也就是说,一个视口就是100vw. 2.px:px应该是在css中使用最 ...

  5. 访问控制中默认,public,private,protected区别?

    2.继承的访问控制: (比如一个类中的protected成员对于"不同的包中的非子类"是不可见的. 说明:1.任何public的内容可以被从任何地方访问. 2.private的成员 ...

  6. 数据库number(4,3)表示什么

    1 你看 number(4,3)是表示 这个数 一共有4位是有效位,后面的3 表示有3个是小数也就是这个数 只能是1.234,这样格式的 最大只能是9.999,2 number(3,4) 表示这个数 ...

  7. vue和react给我的感受

    以下纯属个人使用两个框架的感想和体会: 不知道你们是否有这种感觉~ 我vue和react都用过一段时间,但是vue给我感觉就是经常会忘记语法,需要对照文档才知道怎么写( 难不成是我没喝六个核桃的原因吗 ...

  8. animate.css使用

    解决 使用jquery单纯添加类不能出现动画 使用jQuery向元素中添加类制作动画的时候,需要使用setTimeout实现,因为动画需要从一个状态到另外一个状态!时间设置为0

  9. shiro之第一个程序认证

    有关shiro的介绍请访问https://blog.csdn.net/Kevinnsm/article/details/111823268 三个核心组件:Subject, SecurityManage ...

  10. SpringMVC-自定义转换器

    1.定义转换器类实现Converter接口 import org.springframework.core.convert.converter.Converter; import java.text. ...