about summary refs log tree commit diff
path: root/pkgs/by-name/ha/handbrake/package.nix
blob: c24cee4960f95a10867e774fed13a0993fff9e87 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# Upstream distributes HandBrake with bundle of according versions of libraries
# and patches to them. This derivation patches HandBrake to use Nix closure
# dependencies.
#
# NOTE: 2019-07-19: This derivation does not currently support the native macOS
# GUI--it produces the "HandbrakeCLI" CLI version only. In the future it would
# be nice to add the native GUI (and/or the GTK GUI) as an option too, but that
# requires invoking the Xcode build system, which is non-trivial for now.

{
  stdenv,
  lib,
  fetchFromGitHub,
  # For tests
  testers,
  runCommand,
  fetchurl,
  # Main build tools
  pkg-config,
  autoconf,
  automake,
  libtool,
  m4,
  xz,
  python3,
  numactl,
  writeText,
  # Processing, video codecs, containers
  ffmpeg_7-full,
  nv-codec-headers,
  libogg,
  x264,
  x265,
  libvpx,
  libtheora,
  dav1d,
  zimg,
  svt-av1,
  # Codecs, audio
  libopus,
  lame,
  libvorbis,
  a52dec,
  speex,
  libsamplerate,
  # Text processing
  libiconv,
  fribidi,
  fontconfig,
  freetype,
  libass,
  jansson,
  libxml2,
  harfbuzz,
  libjpeg_turbo,
  # Optical media
  libdvdread,
  libdvdnav,
  libdvdcss,
  libbluray,
  # Darwin-specific
  darwin,
  # GTK
  # NOTE: 2019-07-19: The gtk3 package has a transitive dependency on dbus,
  # which in turn depends on systemd. systemd is not supported on Darwin, so
  # for now we disable GTK GUI support on Darwin. (It may be possible to remove
  # this restriction later.)
  useGtk ? !stdenv.isDarwin,
  appstream,
  desktop-file-utils,
  meson,
  ninja,
  wrapGAppsHook4,
  intltool,
  glib,
  gtk4,
  libappindicator-gtk3,
  libnotify,
  gst_all_1,
  dbus-glib,
  udev,
  libgudev,
  hicolor-icon-theme,
  # FDK
  useFdk ? false,
  fdk_aac,
}:

let
  inherit (darwin.apple_sdk.frameworks)
    AudioToolbox
    Foundation
    VideoToolbox
    ;
  inherit (darwin) libobjc;
  version = "1.8.2";

  src = fetchFromGitHub {
    owner = "HandBrake";
    repo = "HandBrake";
    # uses version commit for logic in version.txt
    rev = "77f199ab02ff2e3bca4ca653e922e9fef67dec43";
    hash = "sha256-vxvmyo03NcO2Nbjg76JLZqmYw7RiK4FehiB+iE3CgOw=";
  };

  # Handbrake maintains a set of ffmpeg patches. In particular, these
  # patches are required for subtitle timing to work correctly. See:
  # https://github.com/HandBrake/HandBrake/issues/4029
  # base ffmpeg version is specified in:
  # https://github.com/HandBrake/HandBrake/blob/master/contrib/ffmpeg/module.defs
  ffmpeg-version = "7.0.2";
  ffmpeg-hb =
    (ffmpeg_7-full.override {
      version = ffmpeg-version;
      hash = "sha256-6bcTxMt0rH/Nso3X7zhrFNkkmWYtxsbUqVQKh25R1Fs=";
    }).overrideAttrs
      (old: {
        patches = (old.patches or [ ]) ++ [
          "${src}/contrib/ffmpeg/A01-mov-read-name-track-tag-written-by-movenc.patch"
          "${src}/contrib/ffmpeg/A02-movenc-write-3gpp-track-titl-tag.patch"
          "${src}/contrib/ffmpeg/A03-mov-read-3gpp-udta-tags.patch"
          "${src}/contrib/ffmpeg/A04-movenc-write-3gpp-track-names-tags-for-all-available.patch"
          "${src}/contrib/ffmpeg/A05-dvdsubdec-fix-processing-of-partial-packets.patch"
          "${src}/contrib/ffmpeg/A06-dvdsubdec-return-number-of-bytes-used.patch"
          "${src}/contrib/ffmpeg/A07-dvdsubdec-use-pts-of-initial-packet.patch"
          "${src}/contrib/ffmpeg/A08-dvdsubdec-do-not-discard-zero-sized-rects.patch"
          "${src}/contrib/ffmpeg/A09-ccaption_dec-fix-pts-in-real_time-mode.patch"
          "${src}/contrib/ffmpeg/A10-matroskaenc-aac-extradata-updated.patch"
          "${src}/contrib/ffmpeg/A11-videotoolbox-disable-H.264-10-bit-on-Intel-macOS.patch"

          # patch to fix <https://github.com/HandBrake/HandBrake/issues/5011>
          # commented out because it causes ffmpeg's filter-pixdesc-p010le test to fail.
          # "${src}/contrib/ffmpeg/A12-libswscale-fix-yuv420p-to-p01xle-color-conversion-bu.patch"

          "${src}/contrib/ffmpeg/A13-qsv-fix-decode-10bit-hdr.patch"
          "${src}/contrib/ffmpeg/A14-amfenc-Add-support-for-pict_type-field.patch"
          "${src}/contrib/ffmpeg/A15-amfenc-Fixes-the-color-information-in-the-ou.patch"
          "${src}/contrib/ffmpeg/A16-amfenc-HDR-metadata.patch"
          "${src}/contrib/ffmpeg/A17-av1dec-dovi-rpu.patch"
          "${src}/contrib/ffmpeg/A18-avformat-mov-add-support-audio-fallback-track-ref.patch"
        ];
      });

  x265-hb = x265.overrideAttrs (old: {
    # nixpkgs' x265 sourceRoot is x265-.../source whereas handbrake's x265 patches
    # are written with respect to the parent directory instead of that source directory.
    # patches which don't cleanly apply are commented out.
    postPatch =
      (old.postPatch or "")
      + ''
        pushd ..
        patch -p1 < ${src}/contrib/x265/A01-threads-priority.patch
        patch -p1 < ${src}/contrib/x265/A02-threads-pool-adjustments.patch
        patch -p1 < ${src}/contrib/x265/A03-sei-length-crash-fix.patch
        patch -p1 < ${src}/contrib/x265/A04-ambient-viewing-enviroment-sei.patch
        # patch -p1 < ${src}/contrib/x265/A05-memory-leaks.patch
        # patch -p1 < ${src}/contrib/x265/A06-crosscompile-fix.patch
        popd
      '';
  });

  versionFile = writeText "version.txt" ''
    URL=${src.meta.homepage}.git
    HASH=${src.rev}
    SHORTHASH=${lib.substring 0 9 src.rev}
    TAG=${version}
    TAG_HASH=${src.rev}
    REV=0
    BRANCH=
    REMOTE=${src.meta.homepage}.git
    DATE=1970-01-01 00:00:01 +0000
  '';

  inherit (lib)
    optional
    optionals
    optionalString
    versions
    ;

  self = stdenv.mkDerivation rec {
    pname = "handbrake";
    inherit version src;

    postPatch =
      ''
        install -Dm444 ${versionFile} ${versionFile.name}

        patchShebangs scripts
        patchShebangs gtk/data/

        substituteInPlace libhb/hb.c \
          --replace-fail 'return hb_version;' 'return "${version}";'

        # Force using nixpkgs dependencies
        sed -i '/MODULES += contrib/d' make/include/main.defs
        sed -e 's/^[[:space:]]*\(meson\|ninja\|nasm\)[[:space:]]*= ToolProbe.*$//g' \
            -e '/    ## Additional library and tool checks/,/    ## MinGW specific library and tool checks/d' \
            -i make/configure.py
      ''
      + optionalString stdenv.isDarwin ''
        # Prevent the configure script from failing if xcodebuild isn't available,
        # which it isn't in the Nix context. (The actual build goes fine without
        # xcodebuild.)
        sed -e '/xcodebuild = ToolProbe/s/abort=.\+)/abort=False)/' -i make/configure.py
      ''
      + optionalString useGtk ''
        substituteInPlace gtk/module.rules \
          --replace-fail '$(MESON.exe)' 'meson' \
          --replace-fail '$(NINJA.exe)' 'ninja' \
        # Force using nixpkgs dependencies
        substituteInPlace gtk/meson.build \
          --replace-fail \
            "hb_incdirs = include_directories(hb_dir / 'libhb', hb_dir / 'contrib/include')" \
            "hb_incdirs = include_directories(hb_dir / 'libhb')"
        substituteInPlace gtk/ghb.spec \
          --replace-fail "gtk-update-icon-cache" "gtk4-update-icon-cache"
        substituteInPlace gtk/data/post_install.py \
          --replace-fail "gtk-update-icon-cache" "gtk4-update-icon-cache"
      '';

    nativeBuildInputs =
      [
        autoconf
        automake
        libtool
        m4
        pkg-config
        python3
      ]
      ++ optionals useGtk [
        appstream
        desktop-file-utils
        intltool
        meson
        ninja
        wrapGAppsHook4
      ];

    buildInputs =
      [
        a52dec
        dav1d
        ffmpeg-hb
        fontconfig
        freetype
        fribidi
        harfbuzz
        jansson
        lame
        libass
        libbluray
        libdvdcss
        libdvdnav
        libdvdread
        libiconv
        libjpeg_turbo
        libogg
        libopus
        libsamplerate
        libtheora
        libvorbis
        libvpx
        libxml2
        speex
        svt-av1
        x264
        x265-hb
        xz
        zimg
      ]
      ++ optional (!stdenv.isDarwin) numactl
      ++ optionals useGtk [
        dbus-glib
        glib
        gst_all_1.gst-libav
        gst_all_1.gst-plugins-bad
        gst_all_1.gst-plugins-base
        gst_all_1.gst-plugins-good
        gst_all_1.gstreamer
        gtk4
        hicolor-icon-theme
        libappindicator-gtk3
        libgudev
        libnotify
        udev
      ]
      ++ optional useFdk fdk_aac
      ++ optionals stdenv.isDarwin [
        AudioToolbox
        Foundation
        libobjc
        VideoToolbox
      ]
      # NOTE: 2018-12-27: Handbrake supports nv-codec-headers for Linux only,
      # look at ./make/configure.py search "enable_nvenc"
      ++ optional stdenv.isLinux nv-codec-headers;

    configureFlags =
      [
        "--disable-df-fetch"
        "--disable-df-verify"
      ]
      ++ optional (!useGtk) "--disable-gtk"
      ++ optional useFdk "--enable-fdk-aac"
      ++ optional stdenv.isDarwin "--disable-xcode"
      ++ optional stdenv.hostPlatform.isx86 "--harden";

    # NOTE: 2018-12-27: Check NixOS HandBrake test if changing
    NIX_LDFLAGS = [ "-lx265" ];

    # meson/ninja are used only for the subprojects, not the toplevel
    dontUseMesonConfigure = true;
    dontUseMesonInstall = true;
    dontUseNinjaBuild = true;
    dontUseNinjaInstall = true;

    makeFlags = [ "--directory=build" ];

    passthru = {
      # for convenience
      inherit ffmpeg-hb x265-hb;

      tests.basic-conversion =
        let
          # Big Buck Bunny example, licensed under CC Attribution 3.0.
          testMkv = fetchurl {
            url = "https://github.com/Matroska-Org/matroska-test-files/blob/cf0792be144ac470c4b8052cfe19bb691993e3a2/test_files/test1.mkv?raw=true";
            hash = "sha256-CZajCf8glZELnTDVJTsETWNxVCl9330L2n863t9a3cE=";
          };
        in
        runCommand "${pname}-${version}-basic-conversion" { nativeBuildInputs = [ self ]; } ''
          mkdir -p $out
          cd $out
          HandBrakeCLI -i ${testMkv} -o test.mp4 -e x264 -q 20 -B 160
          test -e test.mp4
          HandBrakeCLI -i ${testMkv} -o test.mkv -e x264 -q 20 -B 160
          test -e test.mkv
        '';

      tests.version = testers.testVersion {
        package = self;
        command = "HandBrakeCLI --version";
      };
    };

    meta = with lib; {
      homepage = "https://handbrake.fr/";
      description = "Tool for converting video files and ripping DVDs";
      longDescription = ''
        Tool for converting and remuxing video files
        into selection of modern and widely supported codecs
        and containers. Very versatile and customizable.
        Package provides:
        CLI - `HandbrakeCLI`
        GTK GUI - `ghb`
      '';
      license = licenses.gpl2Only;
      maintainers = with maintainers; [
        Anton-Latukha
        wmertens
      ];
      mainProgram = "HandBrakeCLI";
      platforms = with platforms; unix;
      broken = stdenv.isDarwin; # https://github.com/NixOS/nixpkgs/pull/297984#issuecomment-2016503434
    };
  };
in
self