#!/bin/sh mic_device="alsa_input.pci-0000_00_1f.3.analog-stereo" system_device="alsa_output.pci-0000_00_1f.3.analog-stereo.monitor" save_path="$HOME/Videos/rofi-recorder" datetime=$(date +"%d.%m.%Y %H:%M:%S") lockfile="/tmp/.rofi-recorder" if [[ -z $lockfile ]]; then notify-send --hint int:transient:1 -t 1000 "Recorder" "Lockfile is present!" exit 1 fi check_total_time() { target_prefix=$1 mkdir -p $save_path ( cd $save_path && for f in $target_prefix*.mkv; do ffmpeg -i "$f" 2>&1 | grep "Duration" | awk '{print $2}' | tr -d ,; done | awk -F: '{ total += $1 * 3600 + $2 * 60 + $3 } END { print int(total/3600)":"int((total%3600)/60)":"int(total%60) }' ) } merge_videos() { target_prefix=$1 result_prefix=$2 touch $lockfile mkdir -p $save_path local files=("$save_path"/$target_prefix*.mkv) if [[ ${#files[@]} -eq 0 ]] || [[ ! -f "${files[0]}" ]]; then notify-send "Error" "No MKV files found in $save_path" rm $lockfile return 1 fi # Create output filename with timestamp local output_file="$save_path/$result_prefix-$datetime.mkv" local file_list="$save_path/$target_prefix_list.txt" # Create file list in creation order (oldest first) find "$save_path" -maxdepth 1 -name "*$target_prefix*.mkv" -not -name "$result_prefix*.mkv" -type f -printf "%T@ %p\n" | \ sort -n | \ cut -d' ' -f2- > "$file_list" # Convert file paths to ffmpeg concat format sed -i 's/^/file /' "$file_list" # Escape single quotes and wrap paths in single quotes for ffmpeg sed -i "s|file \(.*\)|file '\1'|" "$file_list" # Show ongoing notification notify-send -u low -i video-x-generic "Merging Videos" "Merging $(wc -l < "$file_list") video files..." & local notify_pid=$! # Merge videos using ffmpeg concat demuxer if ffmpeg -f concat -safe 0 -i "$file_list" -c copy "$output_file" -y 2>/dev/null; then # Kill the ongoing notification kill $notify_pid 2>/dev/null # Clean up temporary file rm -f "$file_list" # Remove lockfile rm $lockfile action=$(notify-send -A "Nice" -A "Delete clips" "Merge Complete" \ "Videos merged successfully into $(basename "$output_file")") if [[ "$action" == "1" ]]; then # Delete all original MKV files except the merged one find "$save_path" -maxdepth 1 -name "$target_prefix*.mkv" -not -name "$result_prefix*.mkv" -type f -exec gio trash {} + notify-send --hint int:transient:1 -t 1000 "Recorder" "Stopping" fi else # Kill the ongoing notification kill $notify_pid 2>/dev/null # Clean up on failure rm -f "$file_list" rm -f "$output_file" notify-send -u critical "Merge Failed" "Failed to merge video files" return 1 fi } # Check if wf-recorder is already running if pgrep -x "wf-recorder" > /dev/null; then current_file=$(ps -o args= -C wf-recorder | head -n1 | grep -oE '[^ ]+\.mp4' | tail -n1) notify-send --hint int:transient:1 -t 1000 "Recorder" "Stopping" pkill -2 wf-recorder sleep 1 # Force kill if still running pkill wf-recorder 2>/dev/null exit 0 fi clips_total_duration=$(check_total_time clip) merges_total_duration=$(check_total_time merged) # The modes are video only, +mic, +system audio, full. mode=$(echo -e "Video only\nMicrophone\nMerge clips" | rofi \ -modes drun,run,calc \ -dmenu -p "Clips duration: $clips_total_duration / Merges duration: $merges_total_duration" \ -theme "$HOME/.config/rofi/styles/style-recorder.rasi" \ -markup-rows \ -drun-use-desktop-cache \ ) if [[ -z "$mode" ]]; then notify-send --hint int:transient:1 -t 1000 "Recorder" "Aborting" exit 1 fi case "$mode" in "Video only") # Video only - no audio wf-recorder -c libx264rgb -r 30 -f "$save_path/clip_$datetime.mkv" & ;; "Microphone") # With mic only wf-recorder -c libx264rgb -r 30 -a "$mic_device" --audio-backend=pulse -f "$save_path/clip_$datetime.mkv" & ;; "Merge clips") merge_videos clip merged ;; *) notify-send --hint int:transient:1 -t 1000 "Recorder" "Invalid mode selected" exit 1 ;; esac recorder_pid=$! sleep 1 if ps -p $recorder_pid > /dev/null; then else notify-send --hint int:transient:1 -t 3000 "Recorder" "Failed to start recording" exit 1 fi # Wait for the recording process to finish wait $recorder_pid if [ $? -eq 0 ]; then notify-send --hint int:transient:1 -t 3000 "Recorder" "Video saved $save_path/clip_$datetime.mkv" else notify-send --hint int:transient:1 -t 3000 "Recorder" "Recording failed or was interrupted" fi