summaryrefslogtreecommitdiff
path: root/users/kassouni/rip.nix
blob: 4fd8f7689c07b1b49cebae21025483f8824bfd87 (plain)
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
{ pkgs, pkgs-unstable, ... }:
let
  # Java 8 is the runtime that drives libbluray's BD-J menus; 17/21 hit
  # reflection/AWT failures in disc Xlets.
  bdjJdk = pkgs.jdk8;
  # libbluray reads JAVA_HOME and locates the JVM at
  # <home>/jre/lib/<arch>/server/libjvm.so. On nixpkgs that dir is the `.home`
  # attribute (…/lib/openjdk), not the package store root.
  bdjJavaHome = bdjJdk.home;

  # libbluray's BD-J classes are Java 1.4 bytecode, so the stock jars load on any
  # JVM — no recompile needed. LIBBLURAY_CP must be a SINGLE jar path (the j2se
  # jar); libbluray auto-loads the matching AWT jar from the same directory.
  # A ':'-joined classpath is treated as one filename and fails to open.
  libbluray = pkgs.libbluray-full;
  bdjJar = "${libbluray}/share/java/libbluray-j2se-${libbluray.version}.jar";

  # Wrap every vlc entrypoint so BD-J playback uses jdk8. libbluray keys off
  # JAVA_HOME; BDJ_JAVA_HOME is set too for good measure.
  vlc-bluray = pkgs.symlinkJoin {
    name = "vlc-bluray";
    paths = [ pkgs.vlc ];
    nativeBuildInputs = [ pkgs.makeWrapper ];
    postBuild = ''
      for prog in vlc cvlc nvlc qvlc rvlc svlc; do
        if [ -e "$out/bin/$prog" ]; then
          rm "$out/bin/$prog"
          makeWrapper ${pkgs.vlc}/bin/$prog "$out/bin/$prog" \
            --set JAVA_HOME "${bdjJavaHome}" \
            --set BDJ_JAVA_HOME "${bdjJavaHome}" \
            --set LIBBLURAY_CP "${bdjJar}" \
            --prefix PATH : "${bdjJavaHome}/bin"
        fi
      done
    '';
  };

  # rip.sh, verbatim — wrapped so bd_info/makemkvcon/mkisofs resolve from the
  # Nix store instead of the ambient PATH. writeShellApplication supplies the
  # shebang + `set -euo pipefail` and shellchecks the body at build time.
  rip = pkgs.writeShellApplication {
    name = "rip";
    runtimeInputs = [
      libbluray             # bd_info
      pkgs-unstable.makemkv # makemkvcon
      pkgs.cdrkit           # mkisofs
      pkgs.gawk             # awk
      pkgs.coreutils        # tr, mkdir
    ];
    text = ''
      # Remove the decrypted backup folder once the ISO exists and is non-empty.
      # The ISO wraps the same VIDEO_TS/BDMV payload, so the folder is redundant.
      cleanup_backup() {
          local backup="$1" iso="$2"
          if [[ -s "$iso" ]]; then
              rm -rf "$backup"
          else
              echo "ISO $iso missing or empty; keeping backup folder $backup" >&2
              exit 1
          fi
      }

      RIPS_DIR="/home/kassouni/Videos/backups"

      VOLUME_NAME=$(bd_info /dev/sr0 | awk -F': ' '/Volume Identifier/ {print $2}' | tr -d '\r')

      if [[ -z "$VOLUME_NAME" ]]; then
          echo "Could not read volume identifier from /dev/sr0 (no disc?)" >&2
          exit 1
      fi

      BACKUP_PATH="$RIPS_DIR/$VOLUME_NAME"
      mkdir -p "$BACKUP_PATH"

      makemkvcon backup --decrypt --messages=-stdout --progress=-same disc:/dev/sr0 "$BACKUP_PATH"

      mkisofs -udf -iso-level "3" -allow-limited-size -input-charset "utf-8" -o "$BACKUP_PATH.iso" "$BACKUP_PATH/"

      cleanup_backup "$BACKUP_PATH" "$BACKUP_PATH.iso"
    '';
  };
in
{
  home.packages = with pkgs; [
    rip
    cdrkit
    libbluray
    libaacs
    pkgs-unstable.makemkv
    udftools
    vlc-bluray
    bdjJdk
  ];
}