summaryrefslogtreecommitdiff
path: root/record.fish
blob: 7d76d52cad944f4c5e8ef144d2ea74f9810a2e1e (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
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
#!/bin/fish

function get-audio-source
    pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2
end

function get-active-monitor
    hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name'
end

function has-gpu
    test -e /dev/dri/renderD128
end

function supports-codec -a codec
    ffmpeg -hide_banner -encoders | grep -E '^ V' | grep -F '(codec' | grep $codec >/dev/null
end

function supports-gpu-codecs
    supports-codec hevc_vaapi || supports-codec h264_vaapi
end

argparse -n 'caelestia-record' -X 0 \
    'h/help' \
    's/sound' \
    'r/region=?' \
    'c/compression=!_validate_int' \
    'H/hwaccel' \
    -- $argv
or exit

if set -q _flag_h
    echo 'Usage:'
    echo '    caelestia record ( -h | --help )'
    echo '    caelestia record [ -s | --sound ] [ -r | --region ] [ -c | --compression ] [ -H | --hwaccel ]'
    echo
    echo 'Options:'
    echo '    -h, --help                        Print this help message and exit'
    echo '    -s, --sound                       Enable audio capturing'
    echo '    -r, --region [ <region> ]         The region to capture, current monitor if option not given, default region slurp'
    echo '    -c, --compression <compression>   Use given compression level, lower = better quality, higher = better compression'
    echo '    -H, --hwaccel                     Use hardware acceleration if available'

    exit
end

. (dirname (status filename))/util.fish

set storage_dir (xdg-user-dir VIDEOS)/Recordings
set state_dir $C_STATE/record

mkdir -p $storage_dir
mkdir -p $state_dir

set file_ext 'mp4'
set recording_path "$state_dir/recording.$file_ext"
set notif_id_path "$state_dir/notifid.txt"

if pgrep wf-recorder > /dev/null
    pkill wf-recorder

    # Move to recordings folder
    set -l new_recording_path "$storage_dir/recording_$(date '+%Y%m%d_%H-%M-%S').$file_ext"
    mv $recording_path $new_recording_path

    # Close start notification
    if test -f $notif_id_path
        gdbus call --session \
            --dest org.freedesktop.Notifications \
            --object-path /org/freedesktop/Notifications \
            --method org.freedesktop.Notifications.CloseNotification \
            (cat $notif_id_path)
    end

    # Notification with actions
    set -l action (notify-send 'Recording stopped' "Stopped recording $new_recording_path" -i 'video-x-generic-symbolic' -a 'caelestia-record' \
        --action='watch=Watch' --action='open=Open' --action='save=Save As')

    switch $action
        case 'watch'
            xdg-open $new_recording_path
        case 'open'
        	dbus-send --session --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 org.freedesktop.FileManager1.ShowItems array:string:"file://$new_recording_path" string:'' \
                || xdg-open (dirname $new_recording_path)
        case 'save'
        	set -l save_file (uwsm app -- zenity --file-selection --save --title='Save As')
        	test -n "$save_file" && mv $new_recording_path $save_file || warn 'No file selected'
    end
else
    # Set region if flag given otherwise active monitor
    if set -q _flag_r
        # Use given region if value otherwise slurp
        set region -g (test -n "$_flag_r" && echo $_flag_r || slurp)

        # No hardware encoding when smaller than 256x128 cause unsupported
        if set -q _flag_H
            set -l size (echo $region[2] | string split -n -f 2 ' ' | string split x)
            if test $size[1] -lt 256 -o $size[2] -lt 128
                warn 'Hardware encoding unsupported below size 256x128. Falling back to software encoding.'
                set -e _flag_H
            end
        end
    else
        set region -o (get-active-monitor)
    end

    # Sound if enabled
    set -q _flag_s && set audio --audio=(get-audio-source)

    # Codec stuff
    if set -q _flag_H && has-gpu && supports-gpu-codecs
        # Hardware encoding (GPU)
        supports-codec hevc_vaapi && set codec hevc_vaapi || set codec h264_vaapi
        set -q _flag_c && set compression -p qp=$_flag_c -p rc_mode=CQP
        set codec_flags -d /dev/dri/renderD128
    else
        # Software encoding (CPU)
        set -q _flag_H && warn 'Unable to use hardware acceleration. Falling back to software encoding.'
        supports-codec libx265 && set codec libx265 || set codec libx264
        set -q _flag_c && set compression -p crf=$_flag_c
        set codec_flags -x yuv420p
    end

    wf-recorder -c $codec $codec_flags $compression $region $audio -f $recording_path & disown

    notify-send 'Recording started' 'Recording...' -i 'video-x-generic-symbolic' -a 'caelestia-record' -p > $notif_id_path
end