diff --git a/apps/push-serverless/Dockerfile b/apps/push-serverless/Dockerfile index 30e1cdc5..c307a1f9 100644 --- a/apps/push-serverless/Dockerfile +++ b/apps/push-serverless/Dockerfile @@ -8,19 +8,38 @@ COPY . ./ RUN yarn workspaces focus push-serverless api-types && yarn workspace api-types build && yarn workspace push-serverless build -FROM ossrs/srs:5 +FROM ossrs/srs:6 + +ENV NODE_ENV=production +ENV FFMPEG_PATH=/usr/local/bin/ffmpeg +ENV FFPROBE_PATH=/usr/local/bin/ffprobe RUN apt-get update &&\ apt-get install -y \ - ca-certificates gnupg openssl libssl-dev libc6 curl ffmpeg nginx &&\ + nginx curl wget unzip &&\ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - &&\ apt-get install -y nodejs &&\ apt-get clean &&\ - rm -rf /var/lib/apt/lists/* - -ENV NODE_ENV=production -ENV FFMPEG_PATH=/usr/local/srs/objs/ffmpeg/bin/ffmpeg -ENV FFPROBE_PATH=/usr/bin/ffprobe + rm -rf /var/lib/apt/lists/* &&\ + FFMPEG_VERSION=6.1 && \ + ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + ARCH="64"; \ + elif [ "$ARCH" = "aarch64" ]; then \ + ARCH="arm-64"; \ + else \ + echo "Unsupported architecture: $ARCH" && exit 1; \ + fi && \ + URL="https://github.com/ffbinaries/ffbinaries-prebuilt/releases/download/v${FFMPEG_VERSION}/ffmpeg-${FFMPEG_VERSION}-linux-${ARCH}.zip" && \ + wget $URL -O /tmp/ffmpeg.zip && \ + unzip /tmp/ffmpeg.zip -d /tmp && \ + mv /tmp/ffmpeg /usr/local/bin/ffmpeg && \ + URL="https://github.com/ffbinaries/ffbinaries-prebuilt/releases/download/v${FFMPEG_VERSION}/ffprobe-${FFMPEG_VERSION}-linux-${ARCH}.zip" && \ + wget $URL -O /tmp/ffprobe.zip && \ + unzip /tmp/ffprobe.zip -d /tmp && \ + mv /tmp/ffprobe /usr/local/bin/ffprobe && \ + rm -rf /tmp/ffmpeg.zip /tmp/ffprobe.zip && \ + apt-get purge -y wget unzip curl COPY ./apps/push-serverless/vm/usr/local/srs/conf/knzklive.conf /usr/local/srs/conf/knzklive.conf COPY ./apps/push-serverless/vm/etc/nginx/conf.d/knzklive.conf /etc/nginx/conf.d/knzklive.conf diff --git a/apps/push-serverless/src/services/encoder.ts b/apps/push-serverless/src/services/encoder.ts index 4b1526c5..3302f81f 100644 --- a/apps/push-serverless/src/services/encoder.ts +++ b/apps/push-serverless/src/services/encoder.ts @@ -71,13 +71,19 @@ export class Encoder { .audioCodec('aac') .audioBitrate('128k') .audioChannels(2) - .videoCodec('libx264') + .videoCodec('libx265') .videoBitrate('2500k') .size('1920x1080') .autopad() .format('mp4') .output(`${chunkDir}/${timestamp}.mp4`) - .outputOptions(['-async 1', '-vsync 1', '-filter:v fps=30']) + .outputOptions([ + '-async 1', + '-vsync 1', + '-filter:v fps=30', + '-tag:v hvc1', + '-crf 22' + ]) .duration(remainingSeconds); stream.on('start', (cmd: string) => { @@ -211,7 +217,9 @@ export class Encoder { '-hls_time 1', '-hls_list_size 10', '-hls_flags delete_segments+omit_endlist', - `-hls_segment_filename ${path}/${idx}-%d.ts` + '-segment_list_flags live', + `-hls_segment_filename ${path}/${idx}-%d.ts`, + '-tag:v hvc1' ]) .output(`${path}/stream.m3u8`) .inputOptions(['-re', '-preset', 'ultrafast', '-tune', 'zerolatency']); @@ -255,7 +263,7 @@ export class Encoder { .audioCodec('aac') .audioBitrate('128k') // .audioChannels(2) - .videoCodec('libx264') + .videoCodec('libx265') .videoBitrate('800k') .size('640x360') .autopad() @@ -265,8 +273,11 @@ export class Encoder { '-hls_time 2', '-hls_list_size 10', '-hls_flags delete_segments+omit_endlist', + '-segment_list_flags live', `-hls_segment_filename ${path}/${idx}-%d.ts`, - '-filter:v fps=30' + '-filter:v fps=30', + '-tag:v hvc1', + '-crf 25' ]) .output(`${path}/stream.m3u8`) .inputOptions(['-re', '-preset', 'ultrafast', '-tune', 'zerolatency']); @@ -315,6 +326,7 @@ export class Encoder { '-hls_time 1', '-hls_list_size 10', '-hls_flags delete_segments+omit_endlist', + '-segment_list_flags live', `-hls_segment_filename ${path}/${idx}-%d.ts` ]) .output(`${path}/stream.m3u8`) @@ -352,7 +364,7 @@ export class Encoder { .audioCodec('aac') .audioBitrate('128k') // .audioChannels(2) - .videoCodec('libx264') + .videoCodec('libx265') .videoBitrate('1000k') .format('flv') .inputOptions(['-re']) diff --git a/apps/web/locales/en.json b/apps/web/locales/en.json index 175d618d..ebc891fa 100644 --- a/apps/web/locales/en.json +++ b/apps/web/locales/en.json @@ -100,7 +100,7 @@ "live.player.settings.type.flvWs.title": "Source quality", "live.player.settings.type.flvWs.note": "Ultra-Low latency (iOS is not supported) (Beta)", "live.player.settings.type.flvHttp.title": "Source quality", - "live.player.settings.type.flvHttp.note": "Low latency (iOS is not supported)", + "live.player.settings.type.flvHttp.note": "Ultra-Low latency (iOS is not supported)", "live.player.settings.type.hlsHq.title": "High quality", "live.player.settings.type.hlsHq.note": "Low latency (For iOS)", "live.player.settings.type.hlsLq.title": "Low quality", diff --git a/apps/web/locales/ja.json b/apps/web/locales/ja.json index 1ddd57f3..b6f89c0b 100644 --- a/apps/web/locales/ja.json +++ b/apps/web/locales/ja.json @@ -100,7 +100,7 @@ "live.player.settings.type.flvWs.title": "ソース画質", "live.player.settings.type.flvWs.note": "超低遅延 (iOS 非対応) (Beta)", "live.player.settings.type.flvHttp.title": "ソース画質", - "live.player.settings.type.flvHttp.note": "低遅延 (iOS 非対応)", + "live.player.settings.type.flvHttp.note": "超低遅延 (iOS 非対応)", "live.player.settings.type.hlsHq.title": "高画質", "live.player.settings.type.hlsHq.note": "低遅延 (iOS 向け)", "live.player.settings.type.hlsLq.title": "低画質", diff --git a/apps/web/organisms/live/admin/index.tsx b/apps/web/organisms/live/admin/index.tsx index 9b865b02..3e758354 100644 --- a/apps/web/organisms/live/admin/index.tsx +++ b/apps/web/organisms/live/admin/index.tsx @@ -14,7 +14,8 @@ import { Spinner, Text, UnorderedList, - ListItem + ListItem, + Badge } from '@chakra-ui/react'; import { FC, useEffect } from 'react'; import { useStream } from '~/utils/hooks/api/use-stream'; @@ -24,7 +25,6 @@ import { GeneralSettings } from './general-settings'; import Link from 'next/link'; import { LivePublic } from '~/../../packages/api-types/common/types'; import { AutoMods } from './auto-mods'; -import { NewFeature } from '~/atoms/new-badge'; type Props = { liveId: number; @@ -79,10 +79,7 @@ export const Admin: FC = ({ 配信設定 配信ソフトウェア設定 - - モデレーション - - + モデレーション @@ -113,16 +110,32 @@ export const Admin: FC = ({ 現在、配信システム側でハードリミットは設定されていませんが、快適な配信をするために以下の設定を推奨します。 - + - キーフレーム間隔: 1s (重要: - 間隔が大きい/オートだと視聴がカクつきます) + キーフレーム間隔:{' '} + 1s (重要: 間隔が大きい/0(オート)だとカクつきます) - 映像エンコーダ: H264{' '} - の任意のハードウェア/ソフトウェアエンコーダ (重要: - H265(HEVC) は対応していません) + 映像エンコーダ: H265(HEVC) / H264{' '} + の任意のハードウェア/ソフトウェアエンコーダ + + + + NEW + + H265(HEVC) + コーデックを使用すると、より少ないビットレートで高画質な配信ができます。 + + + + + (OBS) + エンコーダーを変更すると他の設定がリセットされることがあります。変更後は再確認してください。 + + + + 出力解像度: 1920x1080 ビットレート: 2000 kbps 前後