# РеализаÑÐ¸Ñ rtmp-клаÑÑеÑа на базе https://github.com/harlanc/xiu.git ÑÑÑим-ÑеÑвеÑа из 3 инÑÑанÑов
РеализаÑÐ¸Ñ xiu клаÑÑеÑа Ð´Ð»Ñ Ð¿ÑовеÑки ÑÑнкÑионала в локалÑной ÑÑеде, иÑполÑзÑÑ docker-compose. ÐÑоÑмоÑÑ Ð¿Ð¾Ñока в httpflv и hls Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñлена клаÑÑеÑа и налиÑие rtmp поÑока Ñ Ð²ÑеÑ
Ñленов клаÑÑеÑа
- СбоÑка и запÑÑк в неÑколÑко ÑÑадий. РкаÑеÑÑве ÑаннеÑа иÑполÑзÑеÑÑÑ alpine.
- ÐÐ»Ñ Ð·Ð°Ð¿ÑÑка по ÑмолÑÐ°Ð½Ð¸Ñ Ð¸ÑполÑзÑеÑÑÑ ÑÑандаÑÑнÑй toml конÑиг application/xiu/src/config/config_rtmp.toml.
- ÐÐ»Ñ Ð¿Ð¾Ð´Ð°Ñи и пÑоÑмоÑÑа поÑоков иÑполÑзÑеÑÑÑ ffmpeg и ffplay. Ð¡ÐµÐ¼Ð¿Ð»Ñ Ð¸Ð· https://sample-videos.com/
# ÐпиÑание ÑеÑениÑ
## СбоÑка обÑаза
СоглаÑно ÑÑебованиÑм, необÑ
одимо иÑполÑзоваÑÑ multi-stage, ÑобиÑаÑÑ Ð¿Ñиложение в одном конÑейнеÑе и копиÑоваÑÑ Ð¸ÑполнÑемÑе ÑÐ°Ð¹Ð»Ñ Ð² дÑÑгой конÑÐµÐ¹Ð½ÐµÑ Ñ Alpine.
ÐÑÐ¾ÐµÐºÑ xiu напиÑан на Rust. СледоваÑелÑно, Ð´Ð»Ñ ÑбоÑки опÑималÑно иÑполÑзоваÑÑ Ð¾Ð±Ñаз из [оÑиÑиалÑного ÑепозиÑоÑÐ¸Ñ Rust](https://hub.docker.com/_/rust).
СоздаÑм ÑабоÑий каÑалог и клониÑÑем в него пÑÐ¾ÐµÐºÑ xiu:
```
mkdir xiu-image && cd xiu-image
git clone https://github.com/harlanc/xiu.git
```
ÐиÑем Dockerfile.
```
vi Dockerfile
```
- Так как runner Ñ Ð½Ð°Ñ Alpine, добавлÑем дополниÑелÑно musl-dev.
- Ðе забÑваем о Ñом, ÑÑо нам необÑ
одимо добавиÑÑ toml конÑиг Ð´Ð»Ñ Ð·Ð°Ð¿ÑÑка по-ÑмолÑаниÑ.
- Ðо деÑолÑÑ Ð·Ð°Ð¿ÑÑкаем `xiu -c <пÑÑÑ-до конÑига>`.
- Ðо best practice ÑказÑваем веÑÑии обÑазов и не плодим RUN.
```
FROM rust:alpine3.18 as builder
COPY ./ ./
WORKDIR /xiu/application/xiu
RUN apk add --no-cache musl-dev openssl-dev && \
rustup target add x86_64-unknown-linux-musl && \
cargo build --release --target x86_64-unknown-linux-musl
FROM alpine:3.18 as runner
COPY --from=builder /xiu/target/x86_64-unknown-linux-musl/release/xiu /usr/local/bin/xiu
COPY --from=builder /xiu/application/xiu/src/config/config_rtmp.toml /etc/xiu/config_rtmp.toml
CMD ["xiu", "-c", "/etc/xiu/config_rtmp.toml"]
```
СобиÑаем обÑаз:
```
docker image build -t bgelov/xiu:1.0.0 .
```
### ТеÑÑиÑование обÑаза
ÐÑобÑем запÑÑÑиÑÑ ÐºÐ¾Ð½ÑейнеÑ:
```
docker run -d -p 1935:1935 --name xiu bgelov/xiu:1.0.0
```
ÐÑовеÑÑем, ÑÑо конÑÐµÐ¹Ð½ÐµÑ Ð·Ð°Ð¿ÑÑен и ÑмоÑÑим на логи:
```
docker ps
docker logs xiu
```
ÐÑÑ Ð¾Ðº:
```
docker logs xiu
[2023-06-22T20:11:41Z INFO rtmp::rtmp] Rtmp server listening on tcp://0.0.0.0:1935
[2023-06-22T20:11:41Z INFO xiu::api] Http api server listening on http://:8000
```
ТеÑÑиÑÑем ÑабоÑÑ Ñ Ð¸ÑполÑзованием ffmpeg и ffplay. [СкаÑиваем](https://ffmpeg.org/download.html) пÑиложениÑ. [СкаÑиваем](https://sample-videos.com/) ÑÑмпл видео.
ÐапÑÑкаем ffmpeg, Ð´Ð°Ð²Ð°Ñ ÐµÐ¼Ñ Ð½Ð° вÑ
од ÑкаÑанное видео (big_buck_bunny_720p_30mb.mp4):
```
ffmpeg -re -stream_loop -1 -i big_buck_bunny_720p_30mb.mp4 -c:a copy -c:v copy -f flv -flvflags no_duration_filesize rtmp://127.0.0.1:1935/live/test
```
ÐÐ»Ñ Ð¿ÑоÑмоÑÑа запÑÑкаем ffplay:
```
ffplay -i rtmp://localhost:1935/live/test
```
УÑпеÑ
! ÐÑ Ð²Ð¸Ð´Ð¸Ð¼ мÑлÑÑики.
### ÐÑбликаÑÐ¸Ñ Ð¾Ð±Ñаза
ÐоÑле ÑÑпеÑного ÑеÑÑа пÑбликÑем обÑаз в registry.
ФоÑмиÑÑем Ð¸Ð¼Ñ Ð¾Ð±Ñаза в ÑоÑмаÑе `-, веÑÑÐ¸Ñ 1.0.0`:
```
IMAGE_NAME="$(date --utc -d "2023-06-21 11:15" +%s)-$(md5sum Dockerfile | awk '{print $1}'):1.0.0"
echo $IMAGE_NAME
```
Тегаем обÑаз необÑ
одимÑм Ð´Ð»Ñ Ð¿ÑбликаÑи в registry именем и пÑбликÑем:
```
docker tag bgelov/xiu:1.0.0 bgelov/$IMAGE_NAME
docker push bgelov/$IMAGE_NAME
```
СÑÑлка на обÑаз: https://hub.docker.com/r/bgelov/1687346100-977d03e7f0746077d90baa216bbf61c2
## РеализÑем клаÑÑеÑ
ÐеобÑ
одимо ÑеализоваÑÑ rtmp-клаÑÑÐµÑ Ð¸Ð· 3 инÑÑанÑов, иÑполÑзÑÑ docker compose.
СоглаÑно [докÑменÑаÑии](https://github.com/harlanc/xiu), в xiu можно ÑеализоваÑÑ ÐºÐ»Ð°ÑÑÐµÑ Ð¿ÑÑÑм push на оÑÑалÑнÑе Ð½Ð¾Ð´Ñ Ð¸Ð»Ð¸ pull Ñ Ð´ÑÑгой нодÑ.
ÐÑбиÑаем ваÑÐ¸Ð°Ð½Ñ Ñ pull. ÐÑо знаÑиÑ, ÑÑо Ñ Ð½Ð°Ñ Ð±ÑÐ´ÐµÑ 2 Ñипа конÑигÑÑаÑии xiu, Ð´Ð»Ñ Ð¼Ð°ÑÑÐµÑ Ð½Ð¾Ð´Ñ Ð¸ Ð´Ð»Ñ Ð¾Ð±ÑÑнÑÑ
нод.
СоздаÑм ÑабоÑий каÑалог:
```
mkdir xiu-compose && cd xiu-compose
```
ÐиÑем docker compose Ñайл `vi docker-compose.yml`. ÐÐ»Ñ ÑпÑоÑÐµÐ½Ð¸Ñ Ñайла, вÑнеÑем название обÑаза в пеÑеменнÑÑ:
```
services:
xiu-server-1:
container_name: xiu-server-1
image: ${XIU_IMAGE}
ports:
- 1935:1935
- 8081:8081
- 8080:8080
volumes:
- ./conf/master/config_rtmp.toml:/etc/xiu/config_rtmp.toml
xiu-server-2:
container_name: xiu-server-2
image: ${XIU_IMAGE}
ports:
- 1936:1935
- 8181:8081
- 8180:8080
volumes:
- ./conf/node/config_rtmp.toml:/etc/xiu/config_rtmp.toml
xiu-server-3:
container_name: xiu-server-3
image: ${XIU_IMAGE}
ports:
- 1937:1935
- 8281:8081
- 8280:8080
volumes:
- ./conf/node/config_rtmp.toml:/etc/xiu/config_rtmp.toml
```
Ð Ñдом Ñ docker-compose.yml ÑоздаÑм Ñайл `vi .env` и добавим в него пеÑеменнÑÑ `XIU_IMAGE`:
```
XIU_IMAGE=bgelov/1687346100-977d03e7f0746077d90baa216bbf61c2:1.0.0
```
Ð Ñдом Ñ docker-compose.yml Ñак же Ñоздадим ÑÑÑÑкÑÑÑÑ Ñ ÐºÐ¾Ð½ÑигÑÑаÑиÑми xiu Ð´Ð»Ñ Ð¼Ð°ÑÑÐµÑ Ð½Ð¾Ð´Ñ Ð¸ Ð´Ð»Ñ Ð¾Ð±ÑÑной нодÑ. Так как нам нÑÐ¶Ð½Ñ Ð¿Ð¾Ñоки rtmp, httpflv и hls, за пÑÐ¸Ð¼ÐµÑ Ð²Ð¾Ð·ÑмÑм конÑиг `application\xiu\src\config\config_rtmp_httpflv_hls.toml`.
ÐиÑем конÑигÑÑаÑÐ¸Ñ Ð´Ð»Ñ Ð¼Ð°ÑÑÐµÑ Ð½Ð¾Ð´Ñ Ð¿Ð¾ пÑÑи `conf/master/config_rtmp.toml` Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ блока `[[rtmp.push]]`:
```
#live server configurations
#######################################
# RTMP configurations(cluster) #
#######################################
[rtmp]
enabled = true
port = 1935
#######################################
# push streams to other server node #
#######################################
[[rtmp.push]]
enabled = true
address = "xiu-server-2"
port = 1935
[[rtmp.push]]
enabled = true
address = "xiu-server-3"
port = 1935
######################################
# HLS configurations #
######################################
[hls]
enabled = true
port = 8080
########################################
# HTTPFLV configurations #
########################################
[httpflv]
enabled = true
port = 8081
#######################################
# LOG configurations #
#######################################
[log]
level = "info"
```
ÐиÑем конÑигÑÑаÑÐ¸Ñ Ð´Ð»Ñ Ð¾Ð±ÑÑнÑÑ
нод `conf/node/config_rtmp.toml`
```
#live server configurations
#######################################
# RTMP configurations(stand-alone) #
#######################################
[rtmp]
enabled = true
port = 1935
######################################
# HLS configurations #
######################################
[hls]
enabled = true
port = 8080
########################################
# HTTPFLV configurations #
########################################
[httpflv]
enabled = true
port = 8081
#######################################
# LOG configurations #
#######################################
[log]
level = "info"
```
ÐапÑÑкаем клаÑÑеÑ:
```
docker compose up -d
```
### ТеÑÑиÑÑем ÑабоÑоÑпоÑобноÑÑÑ ÐºÐ»Ð°ÑÑеÑа
УÑпеÑнÑм ÑезÑлÑÑаÑом ÑÑиÑаем:
- ÐалиÑие rtmp поÑока Ñ Ð²ÑеÑ
Ñленов клаÑÑеÑа
- ÐÑоÑмоÑÑ Ð¿Ð¾Ñока в httpflv и hls Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñлена клаÑÑеÑа
ÐапÑÑкаем ffmpeg на маÑÑÐµÑ Ð½Ð¾Ð´Ñ rtmp://127.0.0.1:1935, Ð´Ð°Ð²Ð°Ñ Ð½Ð° вÑ
од ÑеÑÑовое видео (big_buck_bunny_720p_30mb.mp4):
```
ffmpeg -re -stream_loop -1 -i big_buck_bunny_720p_30mb.mp4 -c:a copy -c:v copy -f flv -flvflags no_duration_filesize rtmp://127.0.0.1:1935/live/test
```
ÐÐ»Ñ Ð¿ÑоÑмоÑÑа rtmp поÑока запÑÑкаем ffplay на каждÑÑ Ð½Ð¾Ð´Ñ:
```
ffplay -i rtmp://localhost:1935/live/test
ffplay -i rtmp://localhost:1936/live/test
ffplay -i rtmp://localhost:1937/live/test
```
ÐÐ»Ñ Ð¿ÑоÑмоÑÑа поÑока в httpflv и hls запÑÑкаем:
```
# xiu-server-1
ffplay -i http://localhost:8081/live/test.flv
ffplay -i http://localhost:8080/live/test/test.m3u8
# xiu-server-2
ffplay -i http://localhost:8181/live/test.flv
ffplay -i http://localhost:8180/live/test/test.m3u8
# xiu-server-3
ffplay -i http://localhost:8281/live/test.flv
ffplay -i http://localhost:8280/live/test/test.m3u8
```