ptch it bro

This commit is contained in:
Olive Vaughn 2026-08-26 01:24:51 -04:00
parent 9b033fb86e
commit a71fe4bb28
4 changed files with 122 additions and 26 deletions

36
Dockerfile.transcode Normal file
View file

@ -0,0 +1,36 @@
FROM golang:1.23-alpine AS builder
ARG GO_TRANSCODE_COMMIT=f8137e68c7b8da88c51aec9563eec9585c10c723
WORKDIR /src
RUN apk add --no-cache git
RUN git clone https://github.com/m1k1o/go-transcode.git . \
&& git checkout "$GO_TRANSCODE_COMMIT"
COPY patches/go-transcode-vaapi.patch /tmp/go-transcode-vaapi.patch
RUN git apply /tmp/go-transcode-vaapi.patch \
&& CGO_ENABLED=0 go build -o /go-transcode .
# Keep Alpine 3.17: upstream documents an FFmpeg 6 segmenting regression with
# newer Alpine releases. Install both Intel and Mesa VAAPI drivers so this also
# works if the Unraid host exposes an AMD render device.
FROM alpine:3.17
WORKDIR /app
RUN echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
&& apk add --no-cache \
bash \
ffmpeg \
intel-media-driver \
libva-intel-driver \
libva-utils \
mesa-va-gallium
COPY --from=builder /go-transcode /app/go-transcode
EXPOSE 8080
ENV TRANSCODE_BIND=:8080 \
TRANSCODE_VAAPI_DEVICE=/dev/dri/renderD128
ENTRYPOINT ["/app/go-transcode"]
CMD ["serve"]

View file

@ -1,33 +1,27 @@
# go-transcode configuration for VAAPI hardware encoding
# Copy this to go-transcode/config.yaml and adjust as needed
# go-transcode VOD configuration. Hardware encoding is enabled by the
# TRANSCODE_VAAPI_DEVICE environment variable in docker-compose.yml.
vod:
media-dir: /media
transcode-dir: /tmp/go-transcode
# Cache transcoded segments
cache: true
cache-dir: /cache
video-keyframes: true
video-profiles:
480p:
width: 854
height: 480
bitrate: 1200
profiles:
480p:
height: 480
videoBitrate: 1500k
audioBitrate: 128k
hwaccel: vaapi
vaapi-device: /dev/dri/renderD128
codec: h264_vaapi
720p:
width: 1280
height: 720
bitrate: 3000
720p:
height: 720
videoBitrate: 3000k
audioBitrate: 192k
hwaccel: vaapi
vaapi-device: /dev/dri/renderD128
codec: h264_vaapi
1080p:
width: 1920
height: 1080
bitrate: 6000
1080p:
height: 1080
videoBitrate: 6000k
audioBitrate: 256k
hwaccel: vaapi
vaapi-device: /dev/dri/renderD128
codec: h264_vaapi
audio-profile:
bitrate: 192

View file

@ -14,9 +14,12 @@ services:
transcode:
build:
context: https://github.com/m1k1o/go-transcode.git
context: .
dockerfile: Dockerfile.transcode
devices:
- /dev/dri:/dev/dri
environment:
- TRANSCODE_VAAPI_DEVICE=/dev/dri/renderD128
volumes:
- /mnt/user/plex:/media:ro
- ./transcode-config.yaml:/app/config.yaml:ro

View file

@ -0,0 +1,63 @@
diff --git a/hlsvod/transcode.go b/hlsvod/transcode.go
index 1b04b00..12eb935 100644
--- a/hlsvod/transcode.go
+++ b/hlsvod/transcode.go
@@ -6,5 +6,6 @@ import (
"fmt"
"log"
+ "os"
"os/exec"
"path"
"strings"
@@ -56,6 +57,16 @@ func TranscodeSegments(ctx context.Context, ffmpegBinary string, config Transcod
}...)
}
+ // Decode and filter on the GPU when a VAAPI render device is configured.
+ // This is opt-in so upstream's software behavior remains available.
+ vaapiDevice := os.Getenv("TRANSCODE_VAAPI_DEVICE")
+ if vaapiDevice != "" {
+ args = append(args, []string{
+ "-init_hw_device", "vaapi=va:" + vaapiDevice,
+ "-filter_hw_device", "va", "-hwaccel", "vaapi", "-hwaccel_output_format", "vaapi",
+ }...)
+ }
+
// Input specs
args = append(args, []string{
"-i", config.InputFilePath, // Input file
@@ -79,17 +89,26 @@ func TranscodeSegments(ctx context.Context, ffmpegBinary string, config Transcod
if profile.Width >= profile.Height {
scale = fmt.Sprintf("scale=-2:%d", profile.Height)
} else {
scale = fmt.Sprintf("scale=%d:-2", profile.Width)
}
- args = append(args, []string{
- "-vf", scale,
- "-c:v", "libx264",
- "-preset", "faster",
- "-profile:v", "high",
- "-level:v", "4.0",
- "-b:v", fmt.Sprintf("%dk", profile.Bitrate),
- }...)
+ if vaapiDevice != "" {
+ if profile.Width >= profile.Height {
+ scale = fmt.Sprintf("scale_vaapi=w=-2:h=%d:format=nv12", profile.Height)
+ } else {
+ scale = fmt.Sprintf("scale_vaapi=w=%d:h=-2:format=nv12", profile.Width)
+ }
+ args = append(args, []string{
+ "-vf", scale, "-c:v", "h264_vaapi", "-profile:v", "high",
+ "-level:v", "4.0", "-b:v", fmt.Sprintf("%dk", profile.Bitrate),
+ }...)
+ } else {
+ args = append(args, []string{
+ "-vf", scale, "-c:v", "libx264", "-preset", "faster",
+ "-profile:v", "high", "-level:v", "4.0",
+ "-b:v", fmt.Sprintf("%dk", profile.Bitrate),
+ }...)
+ }
}
// Audio specs