From cb7d99483f8ca0581c9dd53b222124daca78aa65 Mon Sep 17 00:00:00 2001 From: Han Gyoung-Su Date: Thu, 13 Mar 2025 01:36:14 +0900 Subject: [PATCH] build(docker): update Dockerfile and add FFmpeg installation script with Leak Sanitizer support (#14) - modify Dockerfile to include static files and create videos directory - update docker-compose to change UDP port range - add install-ffmpeg-lsan.sh for FFmpeg installation with Leak Sanitizer - create lsan.Dockerfile for building with Leak Sanitizer --- Dockerfile | 6 +-- config.toml | 2 +- docker-compose.yaml | 2 +- install-ffmpeg-lsan.sh | 41 +++++++++++++++++++++ lsan.Dockerfile | 24 ++++++++++++ main.go | 7 ++-- media/hub/hub.go | 14 +++++++ media/streamer/egress/record/mp4/handler.go | 6 ++- media/streamer/egress/whep/whep.go | 5 ++- media/streamer/processes/transcoder.go | 2 + 10 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 install-ffmpeg-lsan.sh create mode 100644 lsan.Dockerfile diff --git a/Dockerfile b/Dockerfile index 445c8d8..cfc1145 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,12 +10,10 @@ ENV PKG_CONFIG_PATH=/ffmpeg_build/lib/pkgconfig:${PKG_CONFIG_PATH} ENV PATH="/usr/local/go/bin:${PATH}" COPY ./ /app WORKDIR /app -RUN ls . RUN go mod download RUN go build -o /app/bin/liveflow RUN cp config.toml /app/bin/config.toml -RUN cp index.html /app/bin/index.html - -RUN mkdir /app/bin/videos +RUN cp -r static /app/bin/static +RUN mkdir -p /app/bin/videos WORKDIR /app/bin ENTRYPOINT ["/app/bin/liveflow"] diff --git a/config.toml b/config.toml index 64f70bd..6b2a894 100644 --- a/config.toml +++ b/config.toml @@ -5,7 +5,7 @@ port = 1930 llhls = false disk_ram = true [docker] -mode = false +mode=false [mp4] record=false [ebml] diff --git a/docker-compose.yaml b/docker-compose.yaml index 154d723..bde8fc4 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,7 +10,7 @@ services: ports: - "8044:8044" - "1930:1930" - - "30000-31000:30000-31000/udp" + - "40000-41000:40000-41000/udp" environment: DOCKER_MODE: "true" build: diff --git a/install-ffmpeg-lsan.sh b/install-ffmpeg-lsan.sh new file mode 100644 index 0000000..27a87bb --- /dev/null +++ b/install-ffmpeg-lsan.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +set -ex + +# Leak Sanitizer flags +export SANITIZE_FLAGS="-fsanitize=address -g -O1" + +mkdir -p /ffmpeg_build +cd /ffmpeg_build + +git config --global http.sslVerify false + +git clone --depth 1 https://code.videolan.org/videolan/x264.git +cd x264 +./configure --prefix="/ffmpeg_build" --enable-static --disable-opencl LDFLAGS="$SANITIZE_FLAGS" +make +make install +cd .. + +wget --no-check-certificate -O ffmpeg-7.0.1.tar.bz2 https://ffmpeg.org/releases/ffmpeg-7.0.1.tar.bz2 +tar xjf ffmpeg-7.0.1.tar.bz2 +cd ffmpeg-7.0.1 + +PKG_CONFIG_PATH="/ffmpeg_build/lib/pkgconfig" ./configure \ + --prefix="/ffmpeg_build" \ + --pkg-config-flags="--static" \ + --extra-cflags="-I/ffmpeg_build/include" \ + --extra-ldflags="$SANITIZE_FLAGS -L/ffmpeg_build/lib" \ + --extra-libs="-lpthread -lm" \ + --bindir="/usr/local/bin" \ + --enable-gpl \ + --enable-libx264 \ + --enable-nonfree +make -j8 +make install +cd .. + +# Clean up +rm -rf /ffmpeg_build/src /ffmpeg_build/*.tar.bz2 + +echo "FFmpeg 7.0.1 with x264 (LSan enabled) has been successfully installed to /ffmpeg_build." diff --git a/lsan.Dockerfile b/lsan.Dockerfile new file mode 100644 index 0000000..7b9080d --- /dev/null +++ b/lsan.Dockerfile @@ -0,0 +1,24 @@ +FROM golang:1.21-bullseye + +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y build-essential git pkg-config libunistring-dev libaom-dev libdav1d-dev bzip2 nasm wget yasm ca-certificates + +COPY install-ffmpeg-lsan.sh /install-ffmpeg-lsan.sh +RUN chmod +x /install-ffmpeg-lsan.sh && /install-ffmpeg-lsan.sh + +ENV PKG_CONFIG_PATH=/ffmpeg_build/lib/pkgconfig:${PKG_CONFIG_PATH} +ENV PATH="/usr/local/go/bin:${PATH}" + +COPY ./ /app +WORKDIR /app + +ENV CGO_LDFLAGS='-fsanitize=address' +ENV CGO_CFLAGS='-fsanitize=address' +RUN go mod download +RUN go build -o /app/bin/liveflow +RUN cp config.toml /app/bin/config.toml +RUN cp -r static /app/bin/static +RUN mkdir -p /app/bin/videos +WORKDIR /app/bin +ENTRYPOINT ["/app/bin/liveflow"] \ No newline at end of file diff --git a/main.go b/main.go index f1d5c29..c92d168 100644 --- a/main.go +++ b/main.go @@ -3,15 +3,16 @@ package main import ( "context" "fmt" + "net/http" + _ "net/http/pprof" // pprof을 사용하기 위한 패키지 + "strconv" + "liveflow/config" "liveflow/media/streamer/egress/hls" "liveflow/media/streamer/egress/record/mp4" "liveflow/media/streamer/egress/record/webm" "liveflow/media/streamer/egress/whep" "liveflow/media/streamer/ingress/whip" - "net/http" - _ "net/http/pprof" // pprof을 사용하기 위한 패키지 - "strconv" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" diff --git a/media/hub/hub.go b/media/hub/hub.go index 6c451aa..b64371f 100644 --- a/media/hub/hub.go +++ b/media/hub/hub.go @@ -1,5 +1,10 @@ package hub +// #include +// #include +// +// void __lsan_do_leak_check(void); +import "C" import ( "context" "fmt" @@ -122,6 +127,7 @@ func (h *Hub) Unpublish(streamID string) { close(ch) } delete(h.streams, streamID) + //checkLeak() } // Subscribe : Subscribes to the given streamID. @@ -151,3 +157,11 @@ func (h *Hub) RemoveStream(streamID string) { delete(h.streams, streamID) } } + +//func checkLeak() { +// go func() { +// fmt.Println("will check leak") +// time.Sleep(3 * time.Second) +// C.__lsan_do_leak_check() +// }() +//} diff --git a/media/streamer/egress/record/mp4/handler.go b/media/streamer/egress/record/mp4/handler.go index bb17cdc..05c810e 100644 --- a/media/streamer/egress/record/mp4/handler.go +++ b/media/streamer/egress/record/mp4/handler.go @@ -5,11 +5,12 @@ import ( "context" "errors" "fmt" - "liveflow/media/streamer/egress/record" - "liveflow/media/streamer/processes" "os" "time" + "liveflow/media/streamer/egress/record" + "liveflow/media/streamer/processes" + astiav "github.com/asticode/go-astiav" "github.com/deepch/vdk/codec/aacparser" "github.com/sirupsen/logrus" @@ -122,6 +123,7 @@ func (m *MP4) Start(ctx context.Context, source hub.Source) error { if err != nil { log.Error(ctx, err, "failed to write trailer") } + log.Info(ctx, "mp4 file closed") }() return nil } diff --git a/media/streamer/egress/whep/whep.go b/media/streamer/egress/whep/whep.go index 4b27ec2..e5ccb00 100644 --- a/media/streamer/egress/whep/whep.go +++ b/media/streamer/egress/whep/whep.go @@ -3,9 +3,10 @@ package whep import ( "context" "errors" - "liveflow/media/streamer/processes" - astiav "github.com/asticode/go-astiav" + "github.com/asticode/go-astiav" + + "liveflow/media/streamer/processes" "github.com/deepch/vdk/codec/aacparser" "github.com/pion/rtp" diff --git a/media/streamer/processes/transcoder.go b/media/streamer/processes/transcoder.go index e5ab61c..cc47055 100644 --- a/media/streamer/processes/transcoder.go +++ b/media/streamer/processes/transcoder.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "liveflow/log" "liveflow/media/streamer/pipe" @@ -68,6 +69,7 @@ func (t *AudioTranscodingProcess) Init() error { if t.encCodecContext == nil { return errors.New("codec context is nil") } + if t.decCodecContext.MediaType() == astiav.MediaTypeAudio { t.encCodecContext.SetChannelLayout(astiav.ChannelLayoutStereo) t.encCodecContext.SetSampleRate(t.encSampleRate)