学习路之uniapp --- 视频直播开发(在现有nginx服务器上搭建RTMP媒流体服务器
零、环境准备:centos 7、nginx1.24.0、宝塔8.1
一、找到现有nginx安装文件
- 下载nginx-rtmp-module模块源文件:(选项)
sudo git clone https://github.com/arut/nginx-rtmp-module /www/server/nginx_plus/nginx-rtmp-module/
- 修改nginx下载文件
/www/server/panel/install/nginx.sh 447
--add-module=/www/server/nginx_plus/nginx-rtmp-module/
- 运行安装nginx
sudo sh /www/server/panel/install/nginx.sh install 1.24.0
二、查看nginx -V
三、流媒体服务配置
1. 创建配置目录
mkdir -p /www/rtmp/{hls,live} # 存储视频切片和直播数据
2. RTMP核心配置(软件商店-已安装软件-nginx配置)
在代码http { 之前追加:
rtmp {
server {
listen 1935;#端口监听,1935:rtmp默认端口;注意端口被占用
chunk_size 4096;
application live { #rtmp推流请求路径
live on; #开启直播模式
hls on; # 启用HLS切片
hls_path /www/rtmp/hls;
hls_fragment 3s;
}
}
}
- 增加访问配置:http内部:server内部增加location /hls部分代码
http {
server {
listen 80;
server_name localhost;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /www/rtmp;
}
四、客户端(推流、拉流)
- 推流
rtmp://47.112.111.11:1935/live/stream123
RTMP推流: rtmp://服务器IP:1935/live/自定义流密钥
<live-pusher id='livePusher' ref="livePusher" class="livePusher" url="rtmp://47.112.111.11:1935/live/stream123" mode="SD" :muted="false"
:enable-camera="true" :auto-focus="true" @statechange="onPushStateChange" style="width:100%;height:70vh" />
推流成功:在服务器的/www/rtmp/hls 目录下面生成了m3nu8文件及其他文件
- flv HLS拉流: http://域名:端口/hls/流密钥.m3u8 (如80端口可以省略)
<video id="myVideo"
src="http://47.112.111.11/hls/stream123.m3u8"
@error="videoErrorCallback" :danmu-list="danmuList" :autoplay="true" enable-danmu danmu-btn>
</video>
拉流成功:可以直接在浏览器:http://47.112.111.11/hls/stream123.m3u8 下载这个文件下来
- HTTP-FLV拉流: http://域名/live?app=live&stream=流密钥. (暂未使用)
五、问题
1.先检查自己的1935端口是否放开(阿里云服务器和宝塔 1935 都需要放开 )
检查端口是否被占用: lsof -i:1935
六、补充
push-video.vue
<template>
<view class="container">
<live-pusher id='livePusher' ref="livePusher" class="livePusher" url="rtmp://47.112.111.11:1935/live/stream123" mode="SD" :muted="false"
:enable-camera="true" :auto-focus="true" @statechange="onPushStateChange" style="width:100%;height:70vh" />
<view class="control-panel">
<button @click="toggleCamera">切换摄像头</button>
<button @click="togglePush">{{ isPushing ? '停止推流' : '开始推流' }}</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isPushing: false,
}
},
onReady() {
// 注意:需要在onReady中 或 onLoad 延时
this.context = uni.createLivePusherContext("livePusher", this);
},
methods: {
togglePush() {
if (this.isPushing) {
this.context.stop();
} else {
this.context.start();
}
this.isPushing = !this.isPushing;
},
toggleCamera() {
this.context.switchCamera({
success: (a) => {
console.log("livePusher.switchCamera:" + JSON.stringify(a));
}
});
},
onPushStateChange(e) {
console.log('推流状态:', e.detail.code);
}
}
}
</script>
<style>
.control-panel {
margin-top: 20px;
flex-direction: row;
justify-content: space-around;
}
</style>
index.vue
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<video id="myVideo"
src="http://47.112.111.11/hls/stream123.m3u8"
@error="videoErrorCallback" :danmu-list="danmuList" :autoplay="true" enable-danmu danmu-btn>
</video>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
danmuList: []
}
},
onLoad() {
},
methods: {
onPlayStateChange(e) {
const stateMap = {
2001: '连接中',
2002: '播放中',
2003: '缓冲中',
2004: '播放结束'
};
uni.showToast({
title: stateMap[e.detail.code]
});
},
videoErrorCallback(e){
console.log('aaaaaaa');
console.log(e);
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
参考文件:https://blog.csdn.net/zhangwjshan/article/details/135848552