学习路之uniapp --- 视频直播开发(在现有nginx服务器上搭建RTMP媒流体服务器)

发布于:2025-05-21 ⋅ 阅读:(21) ⋅ 点赞:(0)

零、环境准备:centos 7、nginx1.24.0、宝塔8.1

一、找到现有nginx安装文件

  1. 下载nginx-rtmp-module模块源文件:(选项)
sudo git clone https://github.com/arut/nginx-rtmp-module /www/server/nginx_plus/nginx-rtmp-module/
  1. 修改nginx下载文件

/www/server/panel/install/nginx.sh 447

 --add-module=/www/server/nginx_plus/nginx-rtmp-module/
  1. 运行安装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;
        }

在这里插入图片描述

四、客户端(推流、拉流)

  1. 推流

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文件及其他文件

  1. 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 下载这个文件下来

  1. 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