OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
main @ 205 LINES
 
[ HISTORY ]  [ UP ]
 

{
  pkgs,
  ...
}: let
  discordify = pkgs.writeShellApplication {
    name = "discordify";
    runtimeInputs = [pkgs.ffmpeg pkgs.bc pkgs.gum];
    text =
      # bash
      ''
        TARGET_SIZE_MB=15
        OUTPUT_SUFFIX="_compressed"
        AUDIO_BITRATE="128k"
        verbose=""

        log() {
          local type="$1"
          local message="$2"
          if [ "$type" = "verbose" ]; then
            if [ -n "$verbose" ]; then
              gum log --structured --level debug "$message"
            fi
            return
          fi
          if [ "$type" = "abort" ]; then
            gum log --structured --level error "$message"
            exit 1
          else
            gum log --structured --level "$type" "$message"
          fi
        }

        show_usage() {
            echo "Usage: $0 <input_video> [target_size_mb] [output_name]"
            echo ""
            echo "Examples:"
            echo "  $0 video.mp4                    # Compress to 15MB"
            echo "  $0 video.mp4 25                 # Compress to 25MB"
            echo "  $0 video.mp4 15 my_video.mp4    # Compress to 15MB with custom
 name"
            echo ""
            echo "Options:"
            echo "  target_size_mb: Target file size in MB (default: 15)"
            echo "  output_name: Custom output filename (default: input_compressed
.mp4)"
            echo "  -v, --verbose: Show debug output"
        }

        # parse verbose flag
        while [[ $# -gt 0 ]]; do
          case $1 in
            -v|--verbose)
              verbose="true"
              shift
              ;;
            *)
              break
              ;;
          esac
        done

        # check arguments
        if [ $# -lt 1 ]; then
            show_usage
            exit 1
        fi

        INPUT_FILE="$1"

        # check if input file exists
        if [ ! -f "$INPUT_FILE" ]; then
            log "abort" "Input file '$INPUT_FILE' not found"
        fi

        # parse arguments
        if [ $# -ge 2 ]; then
            TARGET_SIZE_MB="$2"
        fi

        if [ $# -ge 3 ]; then
            OUTPUT_FILE="$3"
        else
            # Generate output filename - using different variable names to avoid n
ix interpolation
            input_filename=$(basename "$INPUT_FILE")
            file_extension="''${input_filename##*.}"
            file_name="''${input_filename%.*}"
            OUTPUT_FILE="''${file_name}''${OUTPUT_SUFFIX}.''${file_extension}"
        fi

        log "info" "Input file: $INPUT_FILE"
        log "info" "Target size: ''${TARGET_SIZE_MB}MB"
        log "info" "Output file: $OUTPUT_FILE"

        # Get video duration in seconds
        gum spin --spinner dot --title "Analyzing input video..." -- sh -c "
          DURATION=\$(ffprobe -v error -show_entries format=duration -of default=n
oprint_wrappers=1:nokey=1 '$INPUT_FILE' 2>/dev/null)
          echo \"\$DURATION\" > /tmp/discordify_duration_$
        "
        DURATION=$(cat "/tmp/discordify_duration_$")
        rm -f "/tmp/discordify_duration_$"

        if [ -z "$DURATION" ] || [ "$(echo "$DURATION < 0" | bc -l 2>/dev/null)" =
 "1" ]; then
            log "abort" "Could not determine video duration"
        fi

        # Calculate target bitrate
        # Formula: (target_size_mb * 8192) / duration - audio_bitrate
        # 8192 = 8 * 1024 (convert MB to kilobits)
        AUDIO_BITRATE_NUM="''${AUDIO_BITRATE//k/}"
        TARGET_BITRATE=$(echo "scale=0; ((''${TARGET_SIZE_MB} * 8192) / $DURATION)
 - $AUDIO_BITRATE_NUM" | bc -l)

        # Ensure minimum bitrate
        MIN_BITRATE=64
        if [ "$(echo "$TARGET_BITRATE < $MIN_BITRATE" | bc -l)" = "1" ]; then
            log "warn" "Calculated bitrate is very low (''${TARGET_BITRATE}k). Set
ting to minimum ''${MIN_BITRATE}k"
            TARGET_BITRATE=$MIN_BITRATE
        fi

        log "info" "Video duration: ''${DURATION}s"
        log "info" "Calculated video bitrate: ''${TARGET_BITRATE}k"

        # Two-pass encoding for better quality at target bitrate
        log "info" "Starting two-pass encoding..."

        # Pass 1 - with spinner
        if [ -n "$verbose" ]; then
          log "info" "Pass 1/2: Analyzing video..."
          if ! ffmpeg -y -i "$INPUT_FILE" \
              -c:v libx264 \
              -b:v "''${TARGET_BITRATE}k" \
              -pass 1 \
              -an \
              -f null \
              /dev/null; then
              log "abort" "First pass failed"
          fi
        else
          if ! gum spin --spinner dot --title "Pass 1/2: Analyzing video..." -- sh
 -c "
            ffmpeg -y -i \"$INPUT_FILE\" \
              -c:v libx264 \
              -b:v \"''${TARGET_BITRATE}k\" \
              -pass 1 \
              -an \
              -f null \
              /dev/null >/dev/null 2>&1
          "; then
              log "abort" "First pass failed"
          fi
        fi

        # Pass 2 - with spinner
        if [ -n "$verbose" ]; then
          log "info" "Pass 2/2: Encoding video..."
          if ! ffmpeg -i "$INPUT_FILE" \
              -c:v libx264 \
              -b:v "''${TARGET_BITRATE}k" \
              -pass 2 \
              -c:a aac \
              -b:a "$AUDIO_BITRATE" \
              -movflags +faststart \
              "$OUTPUT_FILE"; then
              log "abort" "Second pass failed"
          fi
        else
          if ! gum spin --spinner dot --title "Pass 2/2: Encoding video..." -- sh 
-c "
            ffmpeg -i \"$INPUT_FILE\" \
              -c:v libx264 \
              -b:v \"''${TARGET_BITRATE}k\" \
              -pass 2 \
              -c:a aac \
              -b:a \"$AUDIO_BITRATE\" \
              -movflags +faststart \
              \"$OUTPUT_FILE\" >/dev/null 2>&1
          "; then
              log "abort" "Second pass failed"
          fi
        fi

        # Clean up pass files
        rm -f ffmpeg2pass-0.log ffmpeg2pass-0.log.mbtree

        # Check final file size
        if [ -f "$OUTPUT_FILE" ]; then
            FINAL_SIZE=$(stat -f%z "$OUTPUT_FILE" 2>/dev/null || stat -c%s "$OUTPU
T_FILE" 2>/dev/null)
            FINAL_SIZE_MB=$(echo "scale=2; $FINAL_SIZE / 1048576" | bc -l)

            log "info" "Compression complete!"
            log "info" "Final file size: ''${FINAL_SIZE_MB}MB"
            log "info" "Output saved as: $OUTPUT_FILE"

            # Check if we're close to target - escape the hash for nix
            DIFF=$(echo "scale=2; $FINAL_SIZE_MB - ''${TARGET_SIZE_MB}" | bc -l)
            abs_diff="''${DIFF#-}"
            if [ "$(echo "$abs_diff > 1" | bc -l)" = "1" ]; then
                log "warn" "Final size differs from target by ''${DIFF}MB"
            fi
        else
            log "abort" "Output file was not created"
        fi
      '';
  };
in {
  config = {
    home.packages = [discordify];
  };
}

{
  pkgs,
  ...
}: let
  discordify = pkgs.writeShellApplication {
    name = "discordify";
    runtimeInputs = [pkgs.ffmpeg pkgs.bc pkg
s.gum];
    text =
      # bash
      ''
        TARGET_SIZE_MB=15
        OUTPUT_SUFFIX="_compressed"
        AUDIO_BITRATE="128k"
        verbose=""

        log() {
          local type="$1"
          local message="$2"
          if [ "$type" = "verbose" ]; then
            if [ -n "$verbose" ]; then
              gum log --structured --level d
ebug "$message"
            fi
            return
          fi
          if [ "$type" = "abort" ]; then
            gum log --structured --level err
or "$message"
            exit 1
          else
            gum log --structured --level "$t
ype" "$message"
          fi
        }

        show_usage() {
            echo "Usage: $0 <input_video> [t
arget_size_mb] [output_name]"
            echo ""
            echo "Examples:"
            echo "  $0 video.mp4            
        # Compress to 15MB"
            echo "  $0 video.mp4 25         
        # Compress to 25MB"
            echo "  $0 video.mp4 15 my_video
.mp4    # Compress to 15MB with custom name"
            echo ""
            echo "Options:"
            echo "  target_size_mb: Target f
ile size in MB (default: 15)"
            echo "  output_name: Custom outp
ut filename (default: input_compressed.mp4)"
            echo "  -v, --verbose: Show debu
g output"
        }

        # parse verbose flag
        while [[ $# -gt 0 ]]; do
          case $1 in
            -v|--verbose)
              verbose="true"
              shift
              ;;
            *)
              break
              ;;
          esac
        done

        # check arguments
        if [ $# -lt 1 ]; then
            show_usage
            exit 1
        fi

        INPUT_FILE="$1"

        # check if input file exists
        if [ ! -f "$INPUT_FILE" ]; then
            log "abort" "Input file '$INPUT_
FILE' not found"
        fi

        # parse arguments
        if [ $# -ge 2 ]; then
            TARGET_SIZE_MB="$2"
        fi

        if [ $# -ge 3 ]; then
            OUTPUT_FILE="$3"
        else
            # Generate output filename - usi
ng different variable names to avoid nix int
erpolation
            input_filename=$(basename "$INPU
T_FILE")
            file_extension="''${input_filena
me##*.}"
            file_name="''${input_filename%.*
}"
            OUTPUT_FILE="''${file_name}''${O
UTPUT_SUFFIX}.''${file_extension}"
        fi

        log "info" "Input file: $INPUT_FILE"
        log "info" "Target size: ''${TARGET_
SIZE_MB}MB"
        log "info" "Output file: $OUTPUT_FIL
E"

        # Get video duration in seconds
        gum spin --spinner dot --title "Anal
yzing input video..." -- sh -c "
          DURATION=\$(ffprobe -v error -show
_entries format=duration -of default=noprint
_wrappers=1:nokey=1 '$INPUT_FILE' 2>/dev/nul
l)
          echo \"\$DURATION\" > /tmp/discord
ify_duration_$
        "
        DURATION=$(cat "/tmp/discordify_dura
tion_$")
        rm -f "/tmp/discordify_duration_$"

        if [ -z "$DURATION" ] || [ "$(echo "
$DURATION < 0" | bc -l 2>/dev/null)" = "1" ]
; then
            log "abort" "Could not determine
 video duration"
        fi

        # Calculate target bitrate
        # Formula: (target_size_mb * 8192) /
 duration - audio_bitrate
        # 8192 = 8 * 1024 (convert MB to kil
obits)
        AUDIO_BITRATE_NUM="''${AUDIO_BITRATE
//k/}"
        TARGET_BITRATE=$(echo "scale=0; ((''
${TARGET_SIZE_MB} * 8192) / $DURATION) - $AU
DIO_BITRATE_NUM" | bc -l)

        # Ensure minimum bitrate
        MIN_BITRATE=64
        if [ "$(echo "$TARGET_BITRATE < $MIN
_BITRATE" | bc -l)" = "1" ]; then
            log "warn" "Calculated bitrate i
s very low (''${TARGET_BITRATE}k). Setting t
o minimum ''${MIN_BITRATE}k"
            TARGET_BITRATE=$MIN_BITRATE
        fi

        log "info" "Video duration: ''${DURA
TION}s"
        log "info" "Calculated video bitrate
: ''${TARGET_BITRATE}k"

        # Two-pass encoding for better quali
ty at target bitrate
        log "info" "Starting two-pass encodi
ng..."

        # Pass 1 - with spinner
        if [ -n "$verbose" ]; then
          log "info" "Pass 1/2: Analyzing vi
deo..."
          if ! ffmpeg -y -i "$INPUT_FILE" \
              -c:v libx264 \
              -b:v "''${TARGET_BITRATE}k" \
              -pass 1 \
              -an \
              -f null \
              /dev/null; then
              log "abort" "First pass failed
"
          fi
        else
          if ! gum spin --spinner dot --titl
e "Pass 1/2: Analyzing video..." -- sh -c "
            ffmpeg -y -i \"$INPUT_FILE\" \
              -c:v libx264 \
              -b:v \"''${TARGET_BITRATE}k\" 
\
              -pass 1 \
              -an \
              -f null \
              /dev/null >/dev/null 2>&1
          "; then
              log "abort" "First pass failed
"
          fi
        fi

        # Pass 2 - with spinner
        if [ -n "$verbose" ]; then
          log "info" "Pass 2/2: Encoding vid
eo..."
          if ! ffmpeg -i "$INPUT_FILE" \
              -c:v libx264 \
              -b:v "''${TARGET_BITRATE}k" \
              -pass 2 \
              -c:a aac \
              -b:a "$AUDIO_BITRATE" \
              -movflags +faststart \
              "$OUTPUT_FILE"; then
              log "abort" "Second pass faile
d"
          fi
        else
          if ! gum spin --spinner dot --titl
e "Pass 2/2: Encoding video..." -- sh -c "
            ffmpeg -i \"$INPUT_FILE\" \
              -c:v libx264 \
              -b:v \"''${TARGET_BITRATE}k\" 
\
              -pass 2 \
              -c:a aac \
              -b:a \"$AUDIO_BITRATE\" \
              -movflags +faststart \
              \"$OUTPUT_FILE\" >/dev/null 2>
&1
          "; then
              log "abort" "Second pass faile
d"
          fi
        fi

        # Clean up pass files
        rm -f ffmpeg2pass-0.log ffmpeg2pass-
0.log.mbtree

        # Check final file size
        if [ -f "$OUTPUT_FILE" ]; then
            FINAL_SIZE=$(stat -f%z "$OUTPUT_
FILE" 2>/dev/null || stat -c%s "$OUTPUT_FILE
" 2>/dev/null)
            FINAL_SIZE_MB=$(echo "scale=2; $
FINAL_SIZE / 1048576" | bc -l)

            log "info" "Compression complete
!"
            log "info" "Final file size: ''$
{FINAL_SIZE_MB}MB"
            log "info" "Output saved as: $OU
TPUT_FILE"

            # Check if we're close to target
 - escape the hash for nix
            DIFF=$(echo "scale=2; $FINAL_SIZ
E_MB - ''${TARGET_SIZE_MB}" | bc -l)
            abs_diff="''${DIFF#-}"
            if [ "$(echo "$abs_diff > 1" | b
c -l)" = "1" ]; then
                log "warn" "Final size diffe
rs from target by ''${DIFF}MB"
            fi
        else
            log "abort" "Output file was not
 created"
        fi
      '';
  };
in {
  config = {
    home.packages = [discordify];
  };
}
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET