Consolidate and reorganize video scripts
This commit is contained in:
parent
5317d24bf0
commit
5c73ed7eb9
43
dotfiles_gitea/config/servicemenus/video-scripts.desktop
Normal file
43
dotfiles_gitea/config/servicemenus/video-scripts.desktop
Normal file
@ -0,0 +1,43 @@
|
||||
[Desktop Entry]
|
||||
Type=Service
|
||||
ServiceTypes=KonqPopupMenu/Plugin
|
||||
MimeType=video/*;
|
||||
Icon=video-mp4
|
||||
X-KDE-Submenu=Run script...
|
||||
Actions=extractClip;convertToAV1;convertTo264;convertToMP4;sendToZipline;ClipItAndShipIt;
|
||||
|
||||
[Desktop Action extractClip]
|
||||
Name=Extract clip
|
||||
Icon=video-mp4
|
||||
TryExec=ffmpeg
|
||||
Exec=file=%f; konsole -e /bin/zsh -c 'clip "%f"'
|
||||
|
||||
[Desktop Action convertToAV1]
|
||||
Name=Convert to AV1
|
||||
Icon=video-mp4
|
||||
TryExec=ffmpeg
|
||||
Exec=file=%f; konsole -e /bin/zsh -c 'convert-to-av1 "%f"'
|
||||
|
||||
[Desktop Action convertTo264]
|
||||
Name=Convert to x264
|
||||
Icon=video-mp4
|
||||
TryExec=ffmpeg
|
||||
Exec=file=%f; konsole -e /bin/zsh -c 'convert-to-x264 "%f"'
|
||||
|
||||
[Desktop Action convertToMP4]
|
||||
Name=Remux to MP4
|
||||
Icon=video-mp4
|
||||
TryExec=ffmpeg
|
||||
Exec=file=%f; konsole -e /bin/zsh -c 'convert-to-mp4 "%f"'
|
||||
|
||||
[Desktop Action sendToZipline]
|
||||
Name=Send to Zipline
|
||||
Icon=video-mp4
|
||||
TryExec=ffmpeg
|
||||
Exec=file=%f; konsole -e /bin/zsh -c 'send-to-zipline "%f"'
|
||||
|
||||
[Desktop Action ClipItAndShipIt]
|
||||
Name=Clip it and ship it
|
||||
Icon=video-mp4
|
||||
TryExec=ffmpeg
|
||||
Exec=file=%f; konsole -e /bin/zsh -c 'clip-it-and-ship-it "%f"'
|
@ -1,59 +1,69 @@
|
||||
#!/bin/bash
|
||||
# Takes an input file, a start timestamp, and a duration in seconds
|
||||
# This script should be runnable either from the CLI, or from KDE's Dolphin file manager, or GNOME's Nautilus file manager.
|
||||
# Each file manager handles input file differently.
|
||||
|
||||
DEBUG=false
|
||||
|
||||
usage() { echo "Usage: $0 [--start <timestamp>] [--duration <seconds>] [--file <input file>]" 1>&2; exit 1; }
|
||||
|
||||
args=$(getopt -o s:d:hf: --long start:,duration:,help,file: -n 'clip' -- "$@")
|
||||
|
||||
if [ "$DEBUG" == true ]; then
|
||||
echo "args=$args"
|
||||
# Set the $FILE variable to act on. Varies with file manager, but Dolphin's servicemenus and CLI both use $1
|
||||
if ! [ -z $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ]; then
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
rm ~/.nautilus_script_selected_file_paths
|
||||
INPUT_FILE="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
elif ! [ -z "$1" ]; then
|
||||
INPUT_FILE="$1"
|
||||
else
|
||||
echo "No file selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $? != 0 ] ; then echo "Exiting..." >&2 ; exit 1 ; fi
|
||||
|
||||
eval set -- "$args"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-s | --start ) start="$2"; shift 2 ;;
|
||||
-d | --duration ) duration="$2"; shift 2 ;;
|
||||
-f | --file ) file="$2"; shift 2 ;;
|
||||
-h | --help ) usage; shift ;;
|
||||
-- ) shift; break ;;
|
||||
*) usage ; break ;;
|
||||
esac
|
||||
while [ -z $START_TIMESTAMP ]; do
|
||||
START_TIMESTAMP=$(kdialog --title "Clip: Start timestamp" --inputbox "Timestamp for start of clip \nE.g. 1:23:04 \n(Remember to align to video keyframe)")
|
||||
done
|
||||
|
||||
if [ -z "${start}" ]; then
|
||||
echo "No start time set. Set the start time with the --start flag"
|
||||
fi
|
||||
if [ -z "${duration}" ]; then
|
||||
echo "No duration set. Set the duration with the --duration flag"
|
||||
fi
|
||||
if [ -z "${file}" ]; then
|
||||
echo "No input file set. Set the input file with the --file flag"
|
||||
fi
|
||||
while [ -z $END_TIMESTAMP ]; do
|
||||
END_TIMESTAMP=$(kdialog --title "Clip: End timestamp" --inputbox "Timestamp for end of clip \nE.g. 1:24:44")
|
||||
done
|
||||
|
||||
file=$(realpath "$file")
|
||||
while [ -z $CLIP_NAME ]; do
|
||||
CLIP_NAME=$(kdialog --title "Clip: Name" --inputbox "Name of the clip \nE.g. \"Forecast calls for rain\" will end up like:\n\"[2024-02-09] Forecast calls for rain.mp4\"")
|
||||
done
|
||||
|
||||
FILE_PATH=$(dirname "$file")
|
||||
FILE_NAME=$(basename "$file")
|
||||
# TODO: This variable does not seem to resolve to 0 or 1 as expected, but always returns empty
|
||||
while [ -z $KEEP_CLIP_RANGE ]; do
|
||||
KEEP_CLIP_RANGE=$(kdialog --title "Clip: Keep clip range in filename" --yesno "Do you want to keep the clip range in the resulting filename?\nE.g. \"[2024-02-09] Forecast calls for rain (1:23:04-1:24:44).mp4\"")
|
||||
done
|
||||
|
||||
# We know our raw recordings are named like "[YYYY-MM-DD] HH:mm:ss.mkv"
|
||||
# We want to turn "[YYYY-MM-DD] HH:mm:ss.mkv" into
|
||||
# "[YYYY-MM-DD] Clip Name.mp4"
|
||||
# We want to preserve the date, but we don't need the timestamp.
|
||||
# Break up the input file's parts so we know the:
|
||||
# - absolute path (e.g. /home/user/Videos/MyVideo.mkv)
|
||||
# - file name (with extension) (e.g. MyVideo.mkv)
|
||||
# - file extension (e.g. mkv)
|
||||
# - file name (without extension) (e.g. MyVideo)
|
||||
# - composed output file absolute path (e.g. /home/user/Videos/MyVideo-clip.mp4)
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_PATH=$(dirname "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
OUTFILE=$(echo "$FILE_PATH/$FILE_NAME-clip.$FILE_EXT")
|
||||
|
||||
if [ "$DEBUG" == true ]; then
|
||||
echo "start=$start"
|
||||
echo "duration=$duration"
|
||||
echo "file=$file"
|
||||
echo "command to run:"
|
||||
echo "ffmpeg -i \"$file\" -ss \"$start\" -t \"$duration\" -c:v copy -c:a copy \"$OUTFILE\""
|
||||
FILE_DATESTAMP=$(echo $FILE_NAME | cut -d' ' -f1)
|
||||
FILE_TIMESTAMP=$(echo $FILE_NAME | cut -d' ' -f2)
|
||||
if ! [ -z $CLIP_NAME ]; then
|
||||
FILE_NAME="$FILE_DATESTAMP $CLIP_NAME"
|
||||
else
|
||||
FILE_NAME="$FILE_DATESTAMP $FILE_TIMESTAMP"
|
||||
fi
|
||||
|
||||
ffmpeg -i "$file" -ss "$start" -t "$duration" -map 0 -c:v copy -c:a copy "$OUTFILE"
|
||||
# TODO: See #31
|
||||
if ! [ $KEEP_CLIP_RANGE ]; then
|
||||
CLIPPED_FILE=$(echo "/tmp/$FILE_NAME.$FILE_EXT")
|
||||
else
|
||||
CLIPPED_FILE=$(echo "/tmp/$FILE_NAME ($START_TIMESTAMP-$END_TIMESTAMP).$FILE_EXT")
|
||||
fi
|
||||
CLIPPED_FILE=$(echo "$FILE_PATH/$FILE_NAME.$FILE_EXT")
|
||||
|
||||
echo "======== "
|
||||
echo "File created at: $OUTFILE"
|
||||
echo "======== "
|
||||
notify-send -t 2000 "Clip starting" "$FILE_FULL_PATH"
|
||||
ffmpeg -hide_banner -i "$INPUT_FILE" -ss "$START_TIMESTAMP" -to "$END_TIMESTAMP" -map 0 -c:v copy -c:a copy "$OUTFILE"
|
||||
notify-send -t 4000 "Clip complete" "$FILE_FULL_PATH"
|
||||
|
98
dotfiles_gitea/utility-scripts/ffmpeg/clip-it-and-ship-it
Executable file
98
dotfiles_gitea/utility-scripts/ffmpeg/clip-it-and-ship-it
Executable file
@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -z "$1" ]; then
|
||||
INPUT_FILE="$1"
|
||||
else
|
||||
echo "No file selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
START_TIMESTAMP=""
|
||||
while [ -z "$START_TIMESTAMP" ]; do
|
||||
START_TIMESTAMP=$(kdialog --title "Clip: Start timestamp" --inputbox "Timestamp for start of clip \nE.g. 1:23:04 \n(Remember to align to video keyframe)")
|
||||
# Should validate the value of START_TIMESTAMP here.
|
||||
# Very insecure.
|
||||
done
|
||||
|
||||
END_TIMESTAMP=""
|
||||
while [ -z "$END_TIMESTAMP" ]; do
|
||||
END_TIMESTAMP=$(kdialog --title "Clip: End timestamp" --inputbox "Timestamp for end of clip \nE.g. 1:24:44")
|
||||
# Should validate the value of END_TIMESTAMP here.
|
||||
# Very insecure.
|
||||
done
|
||||
|
||||
CLIP_NAME=""
|
||||
while [ -z "$CLIP_NAME" ]; do
|
||||
CLIP_NAME=$(kdialog --title "Clip: Name" --inputbox "Name of the clip \nE.g. \"Forecast calls for rain\" will end up like:\n\"[2024-02-09] Forecast calls for rain.mp4\"")
|
||||
# Should validate the value of CLIP_NAME here.
|
||||
# Very insecure.
|
||||
done
|
||||
|
||||
# We know our raw recordings are named like "[YYYY-MM-DD] HH:mm:ss.mkv"
|
||||
# We want to turn "[YYYY-MM-DD] HH:mm:ss.mkv" into
|
||||
# "[YYYY-MM-DD] Clip Name.mp4"
|
||||
# We want to preserve the date, but we don't need the timestamp.
|
||||
# Break up the input file's parts so we know the:
|
||||
# - absolute path (e.g. /home/user/Videos/[2024-02-09] 13:45:22.mkv)
|
||||
# - file name (with extension) (e.g. [2024-02-09] 13:45:22.mkv)
|
||||
# - file extension (e.g. mkv)
|
||||
# - file name (without extension) (e.g. [2024-02-09] 13:45:22)
|
||||
# - composed output file absolute path (e.g. /home/user/Videos/MyVideo-clip.mp4)
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_PATH=$(dirname "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
FILE_DATESTAMP=$(echo $FILE_NAME | cut -d' ' -f1)
|
||||
FILE_TIMESTAMP=$(echo $FILE_NAME | cut -d' ' -f2)
|
||||
FILE_NAME="$FILE_DATESTAMP $CLIP_NAME"
|
||||
|
||||
# Create the CLIPPED_FILE from the INPUT_FILE
|
||||
CLIPPED_FILE=$(echo "/tmp/Clipped-$FILE_NAME.$FILE_EXT")
|
||||
# CLIPPED_FILE should be like "/tmp/[2024-02-09] Forecast calls for rain (1:23:04-1:24:44).mkv"
|
||||
# Or "/tmp/[2024-02-09] 13:45:22 (1:23:04-1:24:44).mkv"
|
||||
notify-send -t 4000 "Extracting clip" "$CLIPPED_FILE"
|
||||
ffmpeg -hide_banner -y -i "$INPUT_FILE" -ss "$START_TIMESTAMP" -to "$END_TIMESTAMP" -map 0 -c:v copy -c:a copy "$CLIPPED_FILE"
|
||||
|
||||
# Create the REMUXED_FILE from the CLIPPED_FILE
|
||||
# Then delete the CLIPPED_FILE
|
||||
FILE_EXT="mp4"
|
||||
REMUXED_FILE=$(echo "/tmp/Remuxed-$FILE_NAME.$FILE_EXT")
|
||||
# REMUXED_FILE should be like "/tmp/[2024-02-09] Forecast calls for rain.mp4"
|
||||
# Or "/tmp/[2024-02-09] 13:45:22.mp4"
|
||||
notify-send -t 4000 "Remuxing clip" "$REMUXED_FILE"
|
||||
ffmpeg -hide_banner -y -i "$CLIPPED_FILE" -map 0 -c:v copy -c:a copy "$REMUXED_FILE"
|
||||
rm "$CLIPPED_FILE"
|
||||
|
||||
# Create the TRANSCODED_FILE from the REMUXED_FILE
|
||||
# Then delete the REMUXED_FILE
|
||||
TRANSCODED_FILE=$(echo "/tmp/Transcoded-$FILE_NAME.$FILE_EXT")
|
||||
# TRANSCODED_FILE should be like "/tmp/[2024-02-09] Forecast calls for rain (1:23:04-1:24:44).mp4"
|
||||
# Or "/tmp/[2024-02-09] 13:45:22 (1:23:04-1:24:44).mp4"
|
||||
notify-send -t 4000 "Transcoding clip" "$TRANSCODED_FILE"
|
||||
ffmpeg -hide_banner -y -vaapi_device /dev/dri/renderD128 -i "$REMUXED_FILE" -map 0 -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 18 -c:a copy "$TRANSCODED_FILE"
|
||||
rm "$REMUXED_FILE"
|
||||
|
||||
# Upload the TRANSCODED_FILE with the filename of UPLOADED_FILE
|
||||
# Then delete it.
|
||||
UPLOADED_FILE=$(echo "/tmp/$FILE_NAME.$FILE_EXT")
|
||||
|
||||
mv "$TRANSCODED_FILE" "$UPLOADED_FILE"
|
||||
echo "UPLOADED_FILE=$UPLOADED_FILE"
|
||||
|
||||
notify-send -t 4000 "Uploading clip" "$UPLOADED_FILE"
|
||||
ZIPLINE_HOST_ROOT=https://zipline.jafner.net
|
||||
TOKEN=$(cat ~/.zipline-auth)
|
||||
LINK=$(curl \
|
||||
--header "authorization: $TOKEN" \
|
||||
$ZIPLINE_HOST_ROOT/api/upload -F "file=@$UPLOADED_FILE" \
|
||||
--header "Content-Type: multipart/form-data" \
|
||||
--header "Format: name" \
|
||||
--header "Embed: true" \
|
||||
--header "Original-Name: true")
|
||||
LINK=$(echo "$LINK" | jq -r .'files[0]')
|
||||
echo "[$FILE_NAME]($LINK)" | wl-copy
|
||||
notify-send -t 4000 "Zipline - Upload complete." "Link copied to clipboard: $LINK"
|
||||
rm "$UPLOADED_FILE"
|
||||
|
||||
read -p "Press any key to close."
|
31
dotfiles_gitea/utility-scripts/ffmpeg/convert-to-av1
Executable file
31
dotfiles_gitea/utility-scripts/ffmpeg/convert-to-av1
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set the $FILE variable to act on. Varies with file manager, but Dolphin's servicemenus and CLI both use $1
|
||||
if ! [ -z $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ]; then
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
rm ~/.nautilus_script_selected_file_paths
|
||||
INPUT_FILE="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
elif ! [ -z "$1" ]; then
|
||||
INPUT_FILE="$1"
|
||||
else
|
||||
echo "No file selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Break up the input file's parts so we know the:
|
||||
# - absolute path (e.g. /home/user/Videos/MyVideo.mkv)
|
||||
# - file name (with extension) (e.g. MyVideo.mkv)
|
||||
# - file extension (e.g. mkv)
|
||||
# - file name (without extension) (e.g. MyVideo)
|
||||
# - composed output file absolute path (e.g. /home/user/Videos/MyVideo-clip.mp4)
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_PATH=$(dirname "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
OUTFILE=$(echo "$FILE_PATH/$FILE_NAME.av1.$FILE_EXT")
|
||||
|
||||
notify-send -t 2000 "Transcode starting" "$FILE_NAME"
|
||||
ffmpeg -hide_banner -vaapi_device /dev/dri/renderD128 -i "$INPUT_FILE" -map 0 -vf 'format=nv12,hwupload' -c:v av1_vaapi -crf 18 -b:v 6000k "$OUTFILE" > /dev/null
|
||||
notify-send -t 4000 "Transcode complete" "$FILE_NAME"
|
32
dotfiles_gitea/utility-scripts/ffmpeg/convert-to-mp4
Executable file
32
dotfiles_gitea/utility-scripts/ffmpeg/convert-to-mp4
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set the $FILE variable to act on. Varies with file manager, but Dolphin's servicemenus and CLI both use $1
|
||||
if ! [ -z $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ]; then
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
rm ~/.nautilus_script_selected_file_paths
|
||||
INPUT_FILE="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
elif ! [ -z "$1" ]; then
|
||||
INPUT_FILE="$1"
|
||||
else
|
||||
echo "No file selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Break up the input file's parts so we know the:
|
||||
# - absolute path (e.g. /home/user/Videos/MyVideo.mkv)
|
||||
# - file name (with extension) (e.g. MyVideo.mkv)
|
||||
# - file extension (e.g. mkv)
|
||||
# - file name (without extension) (e.g. MyVideo)
|
||||
# - composed output file absolute path (e.g. /home/user/Videos/MyVideo-clip.mp4)
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_PATH=$(dirname "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
OUTFILE=$(echo "$FILE_PATH/$FILE_NAME.mp4")
|
||||
|
||||
# Actual remuxing happens here:
|
||||
notify-send -t 2000 "Remux starting" "$FILE_NAME"
|
||||
ffmpeg -hide_banner -i "$INPUT_FILE" -map 0 -c:v copy -c:a copy "$OUTFILE"
|
||||
notify-send -t 4000 "Remux complete" "$FILE_NAME"
|
41
dotfiles_gitea/utility-scripts/ffmpeg/convert-to-x264
Executable file
41
dotfiles_gitea/utility-scripts/ffmpeg/convert-to-x264
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Transcodes a file to x264 with VA API acceleration.
|
||||
|
||||
# Set the $FILE variable to act on. Varies with file manager, but Dolphin's servicemenus and CLI both use $1
|
||||
if ! [ -z $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ]; then
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
rm ~/.nautilus_script_selected_file_paths
|
||||
INPUT_FILE="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
elif ! [ -z "$1" ]; then
|
||||
INPUT_FILE="$1"
|
||||
else
|
||||
echo "No file selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RATE_FACTOR=""
|
||||
while [ -z "$RATE_FACTOR" ]; do
|
||||
RATE_FACTOR=$(kdialog --title "Transcode: x264 Rate factor" --inputbox "Rate factor (15-28, lower is higher fidelity, higher bitrate.")
|
||||
if ! (($RATE_FACTOR >= 15 && $RATE_FACTOR <= 28)); then
|
||||
RATE_FACTOR=""
|
||||
fi
|
||||
done
|
||||
|
||||
# Break up the input file's parts so we know the:
|
||||
# - absolute path (e.g. /home/user/Videos/MyVideo.mkv)
|
||||
# - file name (with extension) (e.g. MyVideo.mkv)
|
||||
# - file extension (e.g. mkv)
|
||||
# - file name (without extension) (e.g. MyVideo)
|
||||
# - composed output file absolute path (e.g. /home/user/Videos/MyVideo-clip.mp4)
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_PATH=$(dirname "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
OUTFILE=$(echo "$FILE_PATH/$FILE_NAME.x264.$FILE_EXT")
|
||||
|
||||
# Actual transcoding happens here:
|
||||
notify-send -t 2000 "Transcode starting" "$FILE_NAME"
|
||||
ffmpeg -hide_banner -vaapi_device /dev/dri/renderD128 -i "$INPUT_FILE" -map 0 -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp $RATE_FACTOR -c:a copy "$OUTFILE"
|
||||
notify-send -t 4000 "Transcode complete" "$FILE_NAME"
|
43
dotfiles_gitea/utility-scripts/ffmpeg/quick-ffmpeg
Normal file
43
dotfiles_gitea/utility-scripts/ffmpeg/quick-ffmpeg
Normal file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The purpose of this script is to provide a quick graphical interface
|
||||
# for post-processing video recordings with sensibly-constrained options
|
||||
|
||||
# Is is built initially to be called by a Dolphin Servicemenu onto a specific
|
||||
# file. Not intended for batch processing.
|
||||
|
||||
# 1. Parse input filename into parts.
|
||||
# - Presumes: '[YYYY-MM-DD] HH-mm-ss.ext' format
|
||||
# - Presumes the user wants to name the file without losing the date information
|
||||
# 2. Figure out what the user wants to do with the file.
|
||||
# 2.1. Rename the video? If so, how?
|
||||
# 2.1.1. Set name? (Leave blank for HH-mm-ss).
|
||||
# 2.1.2. Keep date?
|
||||
# 2.2. Transcode the video? If so, how?
|
||||
# 2.2.1. AV1
|
||||
# 2.2.1.1. CRF [15-28]
|
||||
# 2.2.1.2. ABR [2-100 Mbps]
|
||||
# 2.2.2. x264
|
||||
# 2.2.2.1. CQP [15-28]
|
||||
# 2.2.2.2. CBR [2-100 Mbps]
|
||||
# 2.2.3. x265
|
||||
# 2.2.3.1. CQP [15-28]
|
||||
# 2.2.3.2. CBR [2-100 Mbps]
|
||||
# 2.3. Remux the video? If so, how?
|
||||
# 2.3.1. To mp4 (default)
|
||||
# 2.4. Upload the video? If so, how to format resulting share link?
|
||||
# 2.4.1 Markdown (default): [$FILE_NAME]($LINK_TO_FILE)
|
||||
# 2.4.2 Plain link: $LINK_TO_FILE
|
||||
|
||||
INPUT_FILE="$1"
|
||||
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_PATH=$(dirname "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
OUTFILE=$(echo "$FILE_PATH/$FILE_NAME.av1.$FILE_EXT")
|
||||
|
||||
notify-send -t 2000 "Transcode starting" "$FILE_NAME"
|
||||
ffmpeg -hide_banner -vaapi_device /dev/dri/renderD128 -i "$INPUT_FILE" -map 0 -vf 'format=nv12,hwupload' -c:v av1_vaapi -crf 18 -b:v 6000k "$OUTFILE" > /dev/null
|
||||
notify-send -t 4000 "Transcode complete" "$FILE_NAME"
|
35
dotfiles_gitea/utility-scripts/ffmpeg/send-to-zipline
Executable file
35
dotfiles_gitea/utility-scripts/ffmpeg/send-to-zipline
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# Uploads via Curl will not be configured with a correct mimetype unles the server's `UPLOADER_ASSUME_MIMETYPES` env var is set to true.
|
||||
|
||||
# Set the $FILE variable to act on. Varies with file manager, but Dolphin's servicemenus and CLI both use $1
|
||||
if ! [ -z $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ]; then
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
rm ~/.nautilus_script_selected_file_paths
|
||||
INPUT_FILE="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
elif ! [ -z "$1" ]; then
|
||||
INPUT_FILE="$1"
|
||||
else
|
||||
echo "No file selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Break up the input file's parts so we know the:
|
||||
# - absolute path (e.g. /home/user/Videos/MyVideo.mkv)
|
||||
# - file name (without extension) (e.g. MyVideo)
|
||||
INPUT_FILE=$(realpath "$INPUT_FILE")
|
||||
FILE_NAME=$(basename "$INPUT_FILE")
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
|
||||
ZIPLINE_HOST_ROOT=https://zipline.jafner.net
|
||||
TOKEN=$(cat ~/.zipline-auth)
|
||||
LINK=$(curl \
|
||||
--header "authorization: $TOKEN" \
|
||||
$ZIPLINE_HOST_ROOT/api/upload -F "file=@$INPUT_FILE" \
|
||||
--header "Content-Type: multipart/form-data" \
|
||||
--header "Format: name" \
|
||||
--header "Embed: true" \
|
||||
--header "Original-Name: true")
|
||||
LINK=$(echo "$LINK" | jq -r .'files[0]')
|
||||
echo "[$FILE_NAME]($LINK)" | wl-copy
|
||||
notify-send -t 4000 "Zipline - Upload complete." "Link copied to clipboard: $LINK"
|
@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# these are declared in a specific order on purpose lol
|
||||
FILE_PATH=$(dirname "$1")
|
||||
FILE_NAME=$(basename "$1")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
|
||||
#echo "FILE_PATH: $FILE_PATH"
|
||||
#echo "FILE_NAME: $FILE_NAME"
|
||||
#echo "FILE_EXT: $FILE_EXT"
|
||||
|
||||
echo -n "Calling ffmpeg as: "
|
||||
#echo "ffmpeg -i \"$1\" -c:v libaom-av1 -aom-params lossless=1 \"$FILE_PATH/$FILE_NAME.av1.$FILE_EXT\""
|
||||
#ffmpeg -i "$1" -c:v av1_vaapi "$FILE_PATH/$FILE_NAME.av1.$FILE_EXT"
|
||||
if [ $(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$1") == "hevc" ]; then
|
||||
echo "Processing: \"$1\""
|
||||
ffmpeg -vaapi_device /dev/dri/renderD128 -i "$1" -vf 'format=nv12,hwupload' -c:v av1_vaapi -crf 24 -b:v 6000k "$FILE_PATH/$FILE_NAME.av1.$FILE_EXT" > /dev/null
|
||||
else
|
||||
echo "Skipping: \"$1\""
|
||||
fi
|
@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
#["Convert and Share to Zipline"]
|
||||
|
||||
# Takes one AV1-encoded, mkv-contained video file and
|
||||
# transcodes it into x264 in the mp4 container,
|
||||
# then uploads the new file to zipline and copies the link to the clipboard.
|
||||
# The new file is ephemeral to the user, as it is deleted after uploading.
|
||||
|
||||
|
||||
{
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
# Guard statement to exit if multiple files are selected.
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
file="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
# these are declared in a specific order on purpose lol
|
||||
FILE_PATH=$(dirname "$file")
|
||||
FILE_NAME=$(basename "$file")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
FILE_FULL_PATH="$FILE_PATH/$FILE_NAME.$FILE_EXT"
|
||||
FILE_TMP_DIR="/tmp/$FILE_NAME.mp4"
|
||||
|
||||
# Guard statement to ensure source is mkv-contained.
|
||||
if [[ "$FILE_EXT" != "mkv" ]]; then notify-send -u critical "Script error" "Only mkv-contained files are supported."; exit 1; fi
|
||||
|
||||
# Guard statement to ensure source is AV1-encoded.
|
||||
if ! [ $(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$FILE_FULL_PATH") == "av1" ]; then notify-send -u critical "Script error" "Only AV1-encoded video files are supported."; exit 1; fi
|
||||
|
||||
# Actual transcoding happens here:
|
||||
notify-send -t 4000 "Beginning transcode" "$FILE_NAME"
|
||||
ffmpeg -hide_banner -i "$FILE_FULL_PATH" -map 0 -c:v libx264 -crf 21 -preset slow -c:a copy "$FILE_TMP_DIR"
|
||||
notify-send -t 4000 "Transcode complete" "$FILE_NAME"
|
||||
|
||||
} > /dev/null
|
||||
|
||||
{
|
||||
ZIPLINE_HOST_ROOT=https://zipline.jafner.net
|
||||
file="$FILE_TMP_DIR"
|
||||
TOKEN=$(cat ~/.zipline-auth)
|
||||
LINK=$(curl \
|
||||
--header "authorization: $TOKEN" \
|
||||
$ZIPLINE_HOST_ROOT/api/upload -F "file=@$FILE_TMP_DIR" \
|
||||
--header "Content-Type: multipart/form-data" \
|
||||
--header "Format: name" \
|
||||
--header "Embed: true" \
|
||||
--header "Original-Name: true")
|
||||
LINK=$(echo "$LINK" | jq -r .'files[0]')
|
||||
echo "[$FILE_NAME]($LINK)" | wl-copy
|
||||
notify-send -t 4000 "Zipline - Upload complete." "Link copied to clipboard: $LINK"
|
||||
} > /dev/null
|
||||
|
||||
rm "$FILE_TMP_DIR"
|
@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
#["Share to Zipline"]
|
||||
|
||||
# Assumes wayland for copying link after upload.
|
||||
# Uses [wl-clipboard](https://github.com/bugaevc/wl-clipboard).
|
||||
# Depends on `jq` to parse response.
|
||||
|
||||
echo "NAUTILUS_SCRIPT_SELECTED_FILE_PATHS = $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" >> ~/temp.txt
|
||||
|
||||
{
|
||||
ZIPLINE_HOST_ROOT=https://zipline.jafner.net
|
||||
echo "ZIPLINE_HOST_ROOT=$ZIPLINE_HOST_ROOT"
|
||||
TOKEN=$(cat ~/.zipline-auth)
|
||||
#echo "TOKEN=$TOKEN"
|
||||
for file in "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"; do
|
||||
echo "file=$file"
|
||||
LINK=$(curl \
|
||||
--header "authorization: $TOKEN" \
|
||||
$ZIPLINE_HOST_ROOT/api/upload -F "file=@$file" \
|
||||
--header "Content-Type: multipart/form-data" \
|
||||
--header "Format: name" \
|
||||
--header "Embed: true" \
|
||||
--header "Original-Name: true")
|
||||
LINK=$(echo "$LINK" | jq -r .'files[0]')
|
||||
echo "$LINK" | wl-copy
|
||||
notify-send -t 4000 "Zipline - Upload complete." "Link copied to clipboard: $LINK"
|
||||
done
|
||||
} > /dev/null # Replace with: `>> ~/uploaderscript.log 2>&1` for logging.
|
||||
|
||||
# Uploads via Curl will not be configured with a correct mimetype unles the server's `UPLOADER_ASSUME_MIMETYPES` env var is set to true.
|
@ -1,2 +0,0 @@
|
||||
gnome-terminal && cd $(dirname "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS") && SELECTED_FILE="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.selected_file
|
@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
#["Convert and Share to Zipline"]
|
||||
|
||||
# Takes one AV1-encoded, mkv-contained video file and
|
||||
# transcodes it into x264 in the mp4 container,
|
||||
# then uploads the new file to zipline and copies the link to the clipboard.
|
||||
# The new file is ephemeral to the user, as it is deleted after uploading.
|
||||
|
||||
|
||||
{
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
# Guard statement to exit if multiple files are selected.
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
file="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
# these are declared in a specific order on purpose lol
|
||||
FILE_PATH=$(dirname "$file")
|
||||
FILE_NAME=$(basename "$file")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
FILE_FULL_PATH="$FILE_PATH/$FILE_NAME.$FILE_EXT"
|
||||
FILE_TMP_DIR="/tmp/$FILE_NAME.mp4"
|
||||
|
||||
# Guard statement to ensure source is mkv-contained.
|
||||
if [[ "$FILE_EXT" != "mkv" ]]; then notify-send -u critical "Script error" "Only mkv-contained files are supported."; exit 1; fi
|
||||
|
||||
# Guard statement to ensure source is AV1-encoded.
|
||||
if ! [ $(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$FILE_FULL_PATH") == "av1" ]; then notify-send -u critical "Script error" "Only AV1-encoded video files are supported."; exit 1; fi
|
||||
|
||||
# Actual transcoding happens here:
|
||||
notify-send -t 4000 "Beginning transcode" "$FILE_NAME"
|
||||
ffmpeg -hide_banner -i "$FILE_FULL_PATH" -map 0 -c:v libx264 -crf 21 -preset slow -c:a copy "$FILE_TMP_DIR"
|
||||
notify-send -t 4000 "Transcode complete" "$FILE_NAME"
|
||||
|
||||
} > /dev/null
|
||||
|
||||
{
|
||||
ZIPLINE_HOST_ROOT=https://zipline.jafner.net
|
||||
file="$FILE_TMP_DIR"
|
||||
TOKEN=$(cat ~/.zipline-auth)
|
||||
LINK=$(curl \
|
||||
--header "authorization: $TOKEN" \
|
||||
$ZIPLINE_HOST_ROOT/api/upload -F "file=@$FILE_TMP_DIR" \
|
||||
--header "Content-Type: multipart/form-data" \
|
||||
--header "Format: name" \
|
||||
--header "Embed: true" \
|
||||
--header "Original-Name: true")
|
||||
LINK=$(echo "$LINK" | jq -r .'files[0]')
|
||||
echo "[$FILE_NAME]($LINK)" | wl-copy
|
||||
notify-send -t 4000 "Zipline - Upload complete." "Link copied to clipboard: $LINK"
|
||||
} > /dev/null
|
||||
|
||||
rm "$FILE_TMP_DIR"
|
@ -1,62 +0,0 @@
|
||||
#!/bin/bash
|
||||
#["Convert to x264"]
|
||||
# Takes one or more video files (tested with AV1-encoded mkv files) and
|
||||
# re-encodes them into x264 in the mp4 container for sharing on platforms like Discord
|
||||
|
||||
#echo "NAUTILUS_SCRIPT_SELECTED_FILE_PATHS = $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" >> temp.txt
|
||||
#echo "NAUTILUS_SCRIPT_SELECTED_URIS = $NAUTILUS_SCRIPT_SELECTED_URIS" >> temp.txt
|
||||
#echo "NAUTILUS_SCRIPT_CURRENT_URI = $NAUTILUS_SCRIPT_CURRENT_URI" >> temp.txt
|
||||
#echo "NAUTILUS_SCRIPT_WINDOW_GEOMETRY = $NAUTILUS_SCRIPT_WINDOW_GEOMETRY" >> temp.txt
|
||||
|
||||
{
|
||||
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > ~/.nautilus_script_selected_file_paths
|
||||
# Guard statement to exit if multiple files are selected.
|
||||
if (( $(grep -c . <<<"$(cat ~/.nautilus_script_selected_file_paths)") > 1 )); then notify-send -u critical "Script error" "Selecting more than 1 file is not supported."; exit 1; fi
|
||||
file="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
|
||||
# these are declared in a specific order on purpose lol
|
||||
FILE_PATH=$(dirname "$file")
|
||||
FILE_NAME=$(basename "$file")
|
||||
FILE_EXT="${FILE_NAME##*.}"
|
||||
FILE_NAME="${FILE_NAME%.*}"
|
||||
FILE_FULL_PATH="$FILE_PATH/$FILE_NAME.$FILE_EXT"
|
||||
|
||||
# Guard statement to ensure source is mkv-contained.
|
||||
if [[ "$FILE_EXT" != "mkv" ]]; then notify-send -u critical "Script error" "Only mkv-contained files are supported."; exit 1; fi
|
||||
|
||||
# Guard statement to ensure source is AV1-encoded.
|
||||
if ! [ $(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$FILE_FULL_PATH") == "av1" ]; then notify-send -u critical "Script error" "Only AV1-encoded video files are supported."; exit 1; fi
|
||||
|
||||
# Actual transcoding happens here:
|
||||
notify-send -t 2000 "Transcode starting" "$FILE_FULL_PATH"
|
||||
ffmpeg -hide_banner -i "$FILE_FULL_PATH" -map 0 -c:v libx264 -crf 21 -preset slow -c:a copy "$FILE_PATH/$FILE_NAME.mp4"
|
||||
notify-send -t 4000 "Transcode complete" "$FILE_FULL_PATH"
|
||||
|
||||
} > /dev/null
|
||||
|
||||
|
||||
### OLD VERSION
|
||||
# {
|
||||
# if (( $(grep -c . <<<"$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" > 1 )); then exit 1; fi
|
||||
# for file in "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"; do
|
||||
# # these are declared in a specific order on purpose lol
|
||||
# FILE_PATH=$(dirname "$file")
|
||||
# FILE_NAME=$(basename "$file")
|
||||
# FILE_EXT="${FILE_NAME##*.}"
|
||||
# FILE_NAME="${FILE_NAME%.*}"
|
||||
# FILE_FULL_PATH="$FILE_PATH/$FILE_NAME.$FILE_EXT"
|
||||
# if [ $(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$FILE_FULL_PATH") == "av1" ]; then
|
||||
# echo "Processing: \"$FILE_NAME\""
|
||||
# KEYFRAMES=( $(ffprobe -hide_banner -loglevel error -skip_frame nokey -select_streams v:0 -show_entries packet=pts,flags -of csv=print_section=0 "$FILE_FULL_PATH" | grep K | cut -d',' -f 1) )
|
||||
# keyint=$(( ${KEYFRAMES[-1]} - ${KEYFRAMES[-2]} ))
|
||||
# echo "KEYFRAMES: $(declare -p $KEYFRAMES)"
|
||||
# echo "keyint: $keyint"
|
||||
# # actual re-encoding happens here:
|
||||
# #ffmpeg -i "$FILE_FULL_PATH" -map 0 -c:v libx264 -crf 23 -preset slow -g $keyint -c:a copy "$FILE_PATH/$FILE_NAME.mp4"
|
||||
# ffmpeg -hide_banner -i "$FILE_FULL_PATH" -copyts -copytb 0 -map 0 -bf 0 -c:v libx264 -crf 23 -video_track_timescale 1000 -g 60 -keyint_min 60 -bsf:v setts=ts=STARTPTS+N/TB_OUT/60 -c:a copy "$FILE_PATH/$FILE_NAME.mp4"
|
||||
# notify-send -t 4000 "Transcode complete" "$FILE_FULL_PATH"
|
||||
# else
|
||||
# echo "Skipping (no av1 video stream): \"$FILE_FULL_PATH\""
|
||||
# fi
|
||||
# done
|
||||
|
||||
# } > /dev/null
|
@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
#["Share to Zipline"]
|
||||
|
||||
# Assumes wayland for copying link after upload.
|
||||
# Uses [wl-clipboard](https://github.com/bugaevc/wl-clipboard).
|
||||
# Depends on `jq` to parse response.
|
||||
|
||||
echo "NAUTILUS_SCRIPT_SELECTED_FILE_PATHS = $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" >> ~/temp.txt
|
||||
|
||||
{
|
||||
ZIPLINE_HOST_ROOT=https://zipline.jafner.net
|
||||
echo "ZIPLINE_HOST_ROOT=$ZIPLINE_HOST_ROOT"
|
||||
TOKEN=$(cat ~/.zipline-auth)
|
||||
#echo "TOKEN=$TOKEN"
|
||||
for file in "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"; do
|
||||
echo "file=$file"
|
||||
LINK=$(curl \
|
||||
--header "authorization: $TOKEN" \
|
||||
$ZIPLINE_HOST_ROOT/api/upload -F "file=@$file" \
|
||||
--header "Content-Type: multipart/form-data" \
|
||||
--header "Format: name" \
|
||||
--header "Embed: true" \
|
||||
--header "Original-Name: true")
|
||||
LINK=$(echo "$LINK" | jq -r .'files[0]')
|
||||
echo "$LINK" | wl-copy
|
||||
notify-send -t 4000 "Zipline - Upload complete." "Link copied to clipboard: $LINK"
|
||||
done
|
||||
} > /dev/null # Replace with: `>> ~/uploaderscript.log 2>&1` for logging.
|
||||
|
||||
# Uploads via Curl will not be configured with a correct mimetype unles the server's `UPLOADER_ASSUME_MIMETYPES` env var is set to true.
|
Loading…
Reference in New Issue
Block a user