This commit is contained in:
孙小云 2025-05-21 11:36:49 +08:00
parent 46f02ddaf1
commit 8f49a9922b
10 changed files with 275 additions and 17 deletions

67
builder/stream.sh Executable file
View File

@ -0,0 +1,67 @@
#!/bin/bash
source ../environment.sh
# 检查必要的环境变量
if [ -z "$STREAM_REMOTE_JAR" ]; then
echo "Error: STREAM_REMOTE_JAR environment variable is not set"
exit 1
fi
if [ -z "$STREAM_IMAGE" ]; then
echo "Error: STREAM_IMAGE environment variable is not set"
exit 1
fi
if [ -z "$STREAM_JAR" ]; then
echo "Error: STREAM_JAR environment variable is not set"
exit 1
fi
# 创建临时构建目录
BUILD_DIR=$(mktemp -d)
trap 'rm -rf "$BUILD_DIR"' EXIT
# 复制JAR文件
echo "Copying JAR file from $STREAM_REMOTE_JAR"
cp "$STREAM_REMOTE_JAR" "$BUILD_DIR/${STREAM_JAR}"
# 检查JAR文件是否复制成功
if [ ! -f "$BUILD_DIR/${STREAM_JAR}" ]; then
echo "Error: Failed to copy JAR file"
exit 1
fi
# 创建Dockerfile
cat > "$BUILD_DIR/Dockerfile" << EOF
FROM registry.t-aaron.com/tuoheng/ffmpeg:latest
# 设置工作目录
WORKDIR /app
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/\$TZ /etc/localtime && echo \$TZ > /etc/timezone
# 创建数据目录
RUN mkdir -p /data/temp && chmod 777 /data/temp
# 创建数据目录
RUN mkdir -p /data/recording && chmod 777 /data/recording
# 创建数据目录
RUN mkdir -p /data/record && chmod 777 /data/record
# 复制JAR文件
COPY ${STREAM_JAR} /app/
# 设置启动命令
ENTRYPOINT ["java", "-jar", "/app/${STREAM_JAR}"]
EOF
# 构建Docker镜像
echo "Building Docker image: $STREAM_IMAGE"
docker build -t "$STREAM_IMAGE" "$BUILD_DIR"
# 清理
# rm -rf "$BUILD_DIR"
echo "Docker image $STREAM_IMAGE has been built successfully"
docker push $STREAM_IMAGE

View File

@ -17,8 +17,9 @@ export OIDC_SERVER_DOMAIN=oidc-${DOMAIN}.${DOMAIN_END}
export MINIO_DOMAIN=minio-${DOMAIN}.${DOMAIN_END}
export MINIO_CONSOLE_DOMAIN=minioconsole-${DOMAIN}.${DOMAIN_END}
export AIRPORT_DOMAIN=airport-${DOMAIN}.${DOMAIN_END}
export SRS_DOMAIN=srs-${DOMAIN}.${DOMAIN_END}
export REGISTRY_HOST=${REGISTRY}/tuoheng/
#export REGISTRY_HOST=""
#Nginx 配置
@ -64,18 +65,17 @@ export KAFKA_MEMORY=1g
export KAFKA_DATA=${NETWORK}_kafka_data
#SRS 配置
# SRS对外爆露端口
export SRS_NAME=SRS_${DOMAIN}
export SRS_HTTP_PORT=8080
# SRS对外爆露端口 Name比较特别,没有DOAMIN后缀
export SRS_NAME=SRS
#export SRS_HTTP_PORT=8080
export SRS_RTMP_PORT=1935
export SRS_RTC_PORT=8000
export SRS_MEMORY=512m
export SRS_IMAGE=registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5
export SRS_DATA=${NETWORK}_srs_data
#Minio 配置
export MINIO_NAME=MINIO_${DOMAIN}
#Minio 配置 Name比较特别,没有DOAMIN后缀
export MINIO_NAME=MINIO
export MINIO_MEMORY=512m
export MINIO_IMAGE=quay.io/minio/minio
export MINIO_DATA=${NETWORK}_minio_data
@ -147,6 +147,14 @@ export GATEWAY_JAR=tuoheng_gateway.jar
export GATEWAY_REMOTE_JAR=/home/th/workspace/test/swarm/dockerfile/gateway/${GATEWAY_JAR}
export GATEWAY_MEMORY=1g
#流媒体录制配置
export STREAM_NAME=STREAM
export STREAM_IMAGE=${REGISTRY_HOST}stream:${DOMAIN}
export STREAM_REMOTE_JAR=/Users/sunpeng/workspace/ideaproject/stream_server/target/stream_server-0.0.1-SNAPSHOT.jar
export STREAM_MEMORY=1g
export STREAM_JAR=stream_server-0.0.1-SNAPSHOT.jar
export STREAM_DATA=${NETWORK}_stream_data
#河湖长
export HHZ_API_NAME=HHZ-API${DOMAIN}
export HHZ_API_IMAGE=${REGISTRY_HOST}hhzapi:${DOMAIN}

View File

@ -50,3 +50,11 @@ if ! docker volume inspect ${KAFKA_DATA} >/dev/null 2>&1; then
else
echo "${KAFKA_DATA} 卷已存在"
fi
source ../environment.sh
if ! docker volume inspect ${STREAM_DATA} >/dev/null 2>&1; then
docker volume create ${STREAM_DATA}
echo "创建 ${STREAM_DATA} 卷成功"
else
echo "${STREAM_DATA} 卷已存在"
fi

View File

@ -20,10 +20,7 @@ if [ -z "$SRS_RTMP_PORT" ]; then
echo "错误: 未找到 SRS_RTMP_PORT 环境变量"
exit 1
fi
if [ -z "$SRS_HTTP_PORT" ]; then
echo "错误: 未找到 SRS_HTTP_PORT 环境变量"
exit 1
fi
if [ -z "$SRS_RTC_PORT" ]; then
echo "错误: 未找到 SRS_RTC_PORT 环境变量"
exit 1
@ -39,16 +36,29 @@ if docker ps -a | grep -q ${SRS_NAME}; then
docker rm ${SRS_NAME} >/dev/null 2>&1
fi
# 在容器内检查并创建必要的目录结构
echo "检查SRS目录结构..."
docker run --rm \
-v "${SRS_DATA}:/usr/local/srs/objs/nginx/html" \
$SRS_IMAGE \
/bin/sh -c '
if [ -d "/usr/local/srs/objs/nginx/html/record" ]; then
echo "record目录已存在跳过创建"
else
echo "创建record目录..."
mkdir -p /usr/local/srs/objs/nginx/html/record
fi
'
# 启动SRS容器
# 启动SRS容器
# 启动SRS容器 默认也有8080端口
docker run -d \
--name ${SRS_NAME} \
--network $NETWORK \
--memory $SRS_MEMORY \
--restart unless-stopped \
-p ${SRS_RTMP_PORT}:1935 \
-p ${SRS_HTTP_PORT}:8080 \
-p ${SRS_RTC_PORT}:8000/udp \
-v "$(pwd)/volumes/srs/conf/srs.conf:/usr/local/srs/conf/srs.conf" \
-v "${SRS_DATA}:/usr/local/srs/objs" \
-v "$(pwd)/volumes/srs/conf/srs.conf:/usr/local/srs/conf/docker.conf" \
-v "${SRS_DATA}:/usr/local/srs/objs/nginx/html" \
$SRS_IMAGE

View File

@ -1,7 +1,7 @@
listen 1935;
max_connections 1000;
srs_log_tank file;
srs_log_file ./objs/srs.log;
srs_log_tank console;
daemon off;
http_server {
enabled on;
@ -15,13 +15,39 @@ rtc_server {
}
vhost __defaultVhost__ {
dvr {
enabled on;
#all表示录制所有视频流也可以按频道录制
#规则为<app>/<stream>live/stream1 live/stream2
#规则为<app>/<stream>live/stream1 live/stream2
dvr_apply all;
#dvr计划
dvr_plan segment;
#录制的路径,详细配置规则见附录三
dvr_path ./objs/nginx/html/record/[2006][01][02]/[app][stream]/[timestamp].flv;
#segment方式录制时间设置单位: s
dvr_duration 900;
#开启按关键帧且flv
dvr_wait_keyframe on;
#时间戳抖动算法。full使用完全的时间戳矫正
#zero只是保证从0开始off不矫正时间戳。
time_jitter full;
}
rtc {
enabled on;
# 开启rtc录制
rtmp_to_rtc on;
rtc_to_rtmp on;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
hls {
enabled on;
hls_path ./objs/nginx/html;

View File

@ -6,6 +6,10 @@ RUN rm -rf /etc/nginx/conf.d/*
# 创建目标目录
RUN mkdir -p /data/tuoheng_airport_web/dist
# 创建视频录制和图片的地址
RUN mkdir -p /data/recording
RUN mkdir -p /data/srs
# 复制temp_vhosts配置到nginx配置目录
COPY temp_vhosts/ /etc/nginx/conf.d/

View File

@ -16,6 +16,8 @@ docker run --pull always -d \
-p ${NGINX_HTTPS_PORT}:443 \
--env TZ=Asia/Shanghai \
--memory ${NGINX_MEMORY} \
--volume ${STREAM_DATA}:/data/recording \
--volume ${SRS_DATA}:/data/srs \
--restart unless-stopped \
${NGINX_IMAGE}

23
start/stream.sh Executable file
View File

@ -0,0 +1,23 @@
source ../environment.sh
if docker ps -a | grep -q ${STREAM_NAME}; then
echo "停止并删除已存在的 STREAM_NAME 容器..."
docker stop ${STREAM_NAME} >/dev/null 2>&1
docker rm ${STREAM_NAME} >/dev/null 2>&1
fi
docker run --pull always -d \
--name ${STREAM_NAME} \
--network ${NETWORK} \
-p 8181:8080 \
--memory ${STREAM_MEMORY} \
-e srs.domain=${SRS_DOMAIN} \
-e srs.name=${SRS_NAME} \
-e recordPath=/data/record/record/ \
-e cangneiwai=true \
-v ${STREAM_DATA}:/data/recording \
-v ${SRS_DATA}:/data/record \
--restart unless-stopped \
${STREAM_IMAGE}

View File

@ -19,6 +19,12 @@ nginx的vhosts里面的cert文件需要更新为域名的配置文件
docker exec KAFKA_bazhong /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --list
3: 建minio的权限
其他:
srs: 推流: rtmp://srs-bazhong.t-aaron.com/live/1
读流: https://srs-bazhong.t-aaron.com:2443/live/1.flv
录制地址:https://srs-bazhong.t-aaron.com:2443/recording/50ae8720-d8b3-40c6-9e2b-4eb31ed619e6.mp4
部署在大数据服务器:
低空(预备)
大数据的mysql的数据

104
test/player.html Normal file
View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>视频播放器</title>
<style>
body {
margin: 0;
padding: 20px;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.video-container {
width: 100%;
max-width: 1000px;
margin: 0 auto;
}
video {
width: 100%;
height: auto;
background-color: black;
border-radius: 4px;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
.controls {
margin-top: 20px;
text-align: center;
}
button {
padding: 10px 20px;
margin: 0 10px;
border: none;
border-radius: 4px;
background-color: #007bff;
color: white;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<h1>视频播放器</h1>
<div class="video-container">
<video id="videoPlayer" controls controlsList="nodownload">
<source src="https://srs-bazhong.t-aaron.com:2443/recording/50ae8720-d8b3-40c6-9e2b-4eb31ed619e6.mp4" type="video/mp4">
您的浏览器不支持 HTML5 视频播放。
</video>
</div>
<div class="controls">
<button onclick="document.getElementById('videoPlayer').play()">播放</button>
<button onclick="document.getElementById('videoPlayer').pause()">暂停</button>
<button onclick="document.getElementById('videoPlayer').currentTime = 0">重新播放</button>
<button onclick="toggleFullScreen()">全屏</button>
</div>
</div>
<script>
function toggleFullScreen() {
const video = document.getElementById('videoPlayer');
if (!document.fullscreenElement) {
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen();
} else if (video.msRequestFullscreen) {
video.msRequestFullscreen();
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
}
// 添加错误处理
const video = document.getElementById('videoPlayer');
video.addEventListener('error', function(e) {
console.error('视频加载错误:', e);
alert('视频加载失败,请检查网络连接或视频地址是否正确。');
});
</script>
</body>
</html>