Hardware-accelerated encoding/transcoding

I typically prefer not to use transcoding which is great that i’m able to disable it but in the rare case where i’m forced to, i’d like ffmpeg to use my GPU for help doing so. NVenc, etc.

:+1: Anything to make imports faster!

Here’s the current function for transcoding:

export async function ffmpegTranscode(args: {
  src: PosixFile
  dest: PosixFile
  width: Maybe<number>
  height: Maybe<number>
  videoBitrateKbps?: number
  timeoutMs: number
}) {
  // https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
  const bitrate = opt(args.videoBitrateKbps)
    .filter(gt0)
    .map(ea => sigFigs(ea, 2))
    .map(m => [
      "-b:v",
      m + "k",
      "-maxrate",
      m + "k",
      "-bufsize",
      sigFigs(m / 2, 2) + "k"
    ])
    .getOrElse(() => [])

  return stdoutResult(
    Settings.ffmpegPath.valueOrDefault,
    [
      "-loglevel",
      "error",
      "-threads",
      toS(ffmpegThreads()),
      "-i",
      args.src.nativePath,
      "-c:v",
      "libx264",
      // pix_fmt and profile are required by firefox (!!)
      "-pix_fmt",
      "yuv420p",
      "-profile:v",
      "high",
      ...bitrate,
      "-c:a",
      "aac",
      args.dest.nativePath
    ],
    {
      timeout: args.timeoutMs,
      isIgnorableError
    }
  )
}

I could just dump most of these into a setting (basically everything between -i and the dynamic bit rate). I think that would cover it (considering this): what do you think?

Also, I’d assume this would be a library setting. Hardware encoding would work on my workstation but would break on all my other computers, so I think it’ll need to be a system setting.

1 Like

I’ve just implemented this setting, which will be available in v1.0:

# +-----------------------+
# |  ffmpegTranscodeArgs  |
# +-----------------------+
#
# The following are the default arguments added to transcode requests made to
# ffmpeg (when ffmpeg is available). The following arguments will proceed the
# command: "-loglevel error -threads T -i INPUT_FILE_PATH" (where T is
# replaced by ~half the available CPU threads, and INPUT_FILE_PATH is the full
# native pathname to the source video). The following arguments will follow
# the arguments in this setting: "-b:v VIDEO_BITRATE_KBPS OUTPUT_FILE_PATH".
#
# CAUTION: this is an advanced setting. Editing this may cause videos that
# require transcoding to not be imported, or not be viewable on all browsers
# and platforms. See
# <https://forum.photostructure.com/t/hardware-accelerated-encoding-transcoding/166>
# for more details.
# (env: "PS_FFMPEG_TRANSCODE_ARGS")
#
# ffmpegTranscodeArgs = [
#   "-c:a",
#   "aac",
#   "-c:v",
#   "libx264",
#   "-pix_fmt",
#   "yuv420p",
#   "-profile:v",
#   "high"
# ]
1 Like

that would be perfect! allowing the ability to fine-tune it and set it up for GPU/CPU workloads

1 Like