From c0c8b05be2bbf51e711c760fcd3af77aba04065b Mon Sep 17 00:00:00 2001 From: John Nguyen Date: Fri, 26 Jan 2024 20:09:53 +1100 Subject: [PATCH] Use openh264 for broadcast --- .docker/base/Dockerfile.nvidia | 18 +++++++++++++++--- Dockerfile | 2 +- build-docker.sh | 7 +++++++ docker-compose.yml | 2 +- server/internal/capture/manager.go | 6 +++++- server/internal/capture/pipelines.go | 6 +++--- 6 files changed, 32 insertions(+), 9 deletions(-) create mode 100755 build-docker.sh diff --git a/.docker/base/Dockerfile.nvidia b/.docker/base/Dockerfile.nvidia index 4ae5f341..188c5207 100644 --- a/.docker/base/Dockerfile.nvidia +++ b/.docker/base/Dockerfile.nvidia @@ -20,7 +20,7 @@ RUN set -eux; \ # Install pip and ninja python3-pip python-gi-dev ninja-build \ # Install build deps - autopoint autoconf automake autotools-dev libtool gettext bison flex gtk-doc-tools \ + autopoint autoconf automake autotools-dev libtool gettext bison flex gtk-doc-tools nasm wget \ # Install libraries librtmp-dev \ libvo-aacenc-dev \ @@ -39,6 +39,15 @@ RUN set -eux; \ apt-get clean -y; \ rm -rf /var/lib/apt/lists/* /var/cache/apt/* +# +# build openh264 +RUN set -eux; \ + cd /tmp; wget https://github.com/cisco/openh264/archive/refs/tags/v2.4.0.tar.gz && tar xvf v2.4.0.tar.gz; \ + cd openh264-2.4.0; \ + meson builddir; \ + ninja -C builddir; \ + ninja -C builddir install; + # # build gstreamer RUN set -eux; \ @@ -48,7 +57,9 @@ RUN set -eux; \ meson --prefix /opt/gstreamer \ -Dgpl=enabled \ -Dugly=enabled \ + -Dbad=enabled \ -Dgst-plugins-ugly:x264=enabled \ + -Dgst-plugins-bad:openh264=enabled \ build; \ ninja -C build; \ meson install -C build; @@ -274,12 +285,13 @@ ENV NEKO_BIND=:8080 # # set gstreamer envs ENV PATH="/opt/gstreamer/bin:${PATH}" -ENV LD_LIBRARY_PATH="/opt/gstreamer/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" -ENV PKG_CONFIG_PATH="/opt/gstreamer/lib/x86_64-linux-gnu/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}" +ENV LD_LIBRARY_PATH="/opt/gstreamer/lib/x86_64-linux-gnu:/usr/local/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" +ENV PKG_CONFIG_PATH="/opt/gstreamer/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/x86_64-linux-gnu/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}" # # copy gstreamer from previous stage COPY --from=gstreamer /opt/gstreamer /opt/gstreamer +COPY --from=gstreamer /usr/local/lib/x86_64-linux-gnu /usr/local/lib/x86_64-linux-gnu # # copy static files from previous stages diff --git a/Dockerfile b/Dockerfile index 57f0840c..e93da7cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,6 +33,6 @@ RUN go mod download COPY server/ . RUN ./build -FROM cave-firefox:latest +FROM cave-firefox:202401261754 COPY --from=server /src/bin/neko /usr/bin/neko diff --git a/build-docker.sh b/build-docker.sh new file mode 100755 index 00000000..be8f3056 --- /dev/null +++ b/build-docker.sh @@ -0,0 +1,7 @@ +#!/usr/bin/sh + +VERSION=202401261754 + +docker build -t neko-cave/base-nvidia:$VERSION -f ./.docker/base/Dockerfile.nvidia . + +docker build --build-arg="BASE_IMAGE=neko-cave/base-nvidia:$VERSION" -t cave-firefox:$VERSION -f ./.docker/firefox/Dockerfile.nvidia ./.docker/firefox/ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index f0aed4e9..1b969a47 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,5 +29,5 @@ services: NEKO_ICELITE: 1 NEKO_BROADCAST_URL: rtmp://ome.thuan.au:1935/app/stream-neko NEKO_NAT1TO1: 192.168.0.34 - NEKO_HWENC: NVENC + # NEKO_HWENC: NVENC NEKO_VIDEO_CODEC: h264 diff --git a/server/internal/capture/manager.go b/server/internal/capture/manager.go index 2acc2e6d..b2110153 100644 --- a/server/internal/capture/manager.go +++ b/server/internal/capture/manager.go @@ -41,7 +41,11 @@ func New(desktop types.DesktopManager, config *config.Capture) *CaptureManagerCt if config.VideoMaxFPS > 0 && config.VideoMaxFPS < fps { fps = config.VideoMaxFPS } - return NewVideoPipeline(config.VideoCodec, config.Display, config.VideoPipeline, fps, config.VideoBitrate, config.VideoHWEnc) + pipelineStr, err := NewVideoPipeline(config.VideoCodec, config.Display, config.VideoPipeline, fps, config.VideoBitrate, config.VideoHWEnc) + + logger.Info().Msgf("pipelineStr: %s", pipelineStr) + + return pipelineStr, err }, "video"), } } diff --git a/server/internal/capture/pipelines.go b/server/internal/capture/pipelines.go index c4d68a63..564c1f65 100644 --- a/server/internal/capture/pipelines.go +++ b/server/internal/capture/pipelines.go @@ -47,9 +47,9 @@ func NewBroadcastPipeline(device string, display string, pipelineSrc string, url // replace display pipelineStr = strings.Replace(pipelineStr, "{display}", display, -1) } else { - birate := 5000 - pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1 subscribe=stream-neko buffer=1200000' %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s video/x-raw,format=NV12 ! nvh264enc name=encoder rc-lookahead=20 preset=2 gop-size=120 temporal-aq=true bitrate=%d vbv-buffer-size=%d rc-mode=cbr bframes=0 ! h264parse config-interval=-1 ! mux.", url, audio, video, birate, birate) - // pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1 subscribe=stream-neko buffer=1200000' %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s video/x-raw,format=NV12 ! openh264enc name=encoder bitrate=%d vbv-buffer-size=%d ! h264parse config-interval=-1 ! mux.", url, audio, video, birate, birate) + bitrate := 4000 + // pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1 subscribe=stream-neko buffer=1200000' %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s video/x-raw,format=NV12 ! nvh264enc name=encoder rc-lookahead=20 preset=2 gop-size=120 temporal-aq=true bitrate=%d vbv-buffer-size=%d rc-mode=cbr bframes=0 ! h264parse config-interval=-1 ! mux.", url, audio, video, bitrate, bitrate) + pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1 subscribe=stream-neko' %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s video/x-raw ! videoconvert ! queue ! openh264enc multi-thread=2 complexity=medium bitrate=%d max-bitrate=%d ! h264parse config-interval=-1 ! mux.", url, audio, video, bitrate*1000, (bitrate+1024)*1000) } return pipelineStr, nil