Last active
March 5, 2026 02:18
-
-
Save HBIDamian/65d081303d75cd3aefaeff4792f9018e to your computer and use it in GitHub Desktop.
Jellyfin - Set English Audio to Default (set -v to see the verbose of ffmpeg)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| FFMPEG="/usr/lib/jellyfin-ffmpeg/ffmpeg" | |
| FFPROBE="/usr/lib/jellyfin-ffmpeg/ffprobe" | |
| VERBOSE=false | |
| SUMMARY="" | |
| COUNT=0 | |
| # --- COLOR PALETTE --- | |
| # Standard | |
| BLACK='\033[0;30m' | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[0;33m' | |
| BLUE='\033[0;34m' | |
| PURPLE='\033[0;35m' | |
| CYAN='\033[0;36m' | |
| GRAY='\033[0;37m' | |
| WHITE='\033[0;38m' | |
| # Bold | |
| B_RED='\033[1;31m' | |
| B_GREEN='\033[1;32m' | |
| B_YELLOW='\033[1;33m' | |
| B_CYAN='\033[1;36m' | |
| # UI Elements | |
| DIM='\033[2m' | |
| UNDERLINE='\033[4m' | |
| BOLD='\033[1m' | |
| XBOLD='\033[21m' | |
| NC='\033[0m' # No Color (Reset) | |
| while getopts "v" opt; do | |
| case $opt in | |
| v) VERBOSE=true ;; | |
| *) echo "Usage: $0 [-v]"; exit 1 ;; | |
| esac | |
| done | |
| # High-Visibility Block Spinner | |
| spinner() { | |
| local pid=$1 | |
| local current=$2 | |
| local total=$3 | |
| local filename=$4 | |
| local delay=0.1 | |
| # This sequence uses fading blocks which are very visible | |
| local spinstr='█▓▒░▒▓' | |
| while kill -0 "$pid" 2>/dev/null; do | |
| for (( i=0; i<${#spinstr}; i++ )); do | |
| if ! kill -0 "$pid" 2>/dev/null; then break; fi | |
| # [█] [1/8] Filename... | |
| printf "\r${B_CYAN}[%s]${NC} ${B_WHITE}%s/%s${NC} %s" "${spinstr:$i:1}" "$current" "$total" "$filename" | |
| sleep $delay | |
| done | |
| done | |
| } | |
| echo -e "${GRAY}---------------------------------------${NC}" | |
| echo -e "${CYAN}[ℹ]${NC} Jellyfin English Default Track Setter" | |
| echo -e "${GRAY}---------------------------------------${NC}" | |
| if ! ls *.mkv >/dev/null 2>&1; then | |
| echo "" | |
| echo -e "${CYAN}[${RED}✖${CYAN}]${NC} No .mkv files found in $(pwd)" | |
| exit 1 | |
| fi | |
| echo "" | |
| echo -e "${GRAY}---------------------------------------${NC}" | |
| echo -e "${CYAN}[ℹ]${NC} Starting batch process in: $(pwd)" | |
| [ "$VERBOSE" = true ] && echo -e "${YELLOW}[⚠]${NC} Verbose mode enabled${NC}" | |
| for f in *.mkv; do | |
| if [ "$VERBOSE" = true ]; then | |
| echo "Processing: $f" | |
| # Silent Probe to find track | |
| LINE_NUM=$($FFPROBE -v error -select_streams a -show_entries stream=index:stream_tags=language -of csv=p=0 "$f" | grep -ni ",eng" | cut -d':' -f1 | head -n 1) | |
| if [ -z "$LINE_NUM" ]; then | |
| SUMMARY+="\n${YELLOW}[⚠] SKIP:${NC} '$f' (No English track)" | |
| continue | |
| fi | |
| TRACK_INDEX=$((LINE_NUM - 1)) | |
| if $FFMPEG -i "$f" -map 0 -c copy -disposition:a 0 -disposition:a:$TRACK_INDEX default "temp_$f" -y; then | |
| mv "temp_$f" "$f" | |
| SUMMARY+="\n${GREEN}[✔] OK:${NC} '$f'" | |
| ((COUNT++)) | |
| else | |
| rm -f "temp_$f" | |
| SUMMARY+="\n${RED}[✖] FAIL:${NC} '$f'" | |
| fi | |
| else | |
| # Run background logic | |
| ( | |
| LINE_NUM=$($FFPROBE -v error -select_streams a -show_entries stream=index:stream_tags=language -of csv=p=0 "$f" | grep -ni ",eng" | cut -d':' -f1 | head -n 1) | |
| [ -z "$LINE_NUM" ] && exit 2 | |
| TRACK_INDEX=$((LINE_NUM - 1)) | |
| if $FFMPEG -i "$f" -map 0 -c copy -disposition:a 0 -disposition:a:$TRACK_INDEX default "temp_$f" -y -loglevel error; then | |
| mv "temp_$f" "$f" | |
| exit 0 | |
| else | |
| rm -f "temp_$f" | |
| exit 1 | |
| fi | |
| ) & | |
| FF_PID=$! | |
| spinner $FF_PID "$f" | |
| wait $FF_PID | |
| EXIT_CODE=$? | |
| # Clean line and print status | |
| printf "\r\033[K" | |
| if [ $EXIT_CODE -eq 0 ]; then | |
| echo -e "${CYAN}[${GREEN}✔${CYAN}]${NC} $f" | |
| SUMMARY+="\n${GREEN}[✔] OK:${NC} '$f'" | |
| ((COUNT++)) | |
| elif [ $EXIT_CODE -eq 2 ]; then | |
| echo -e "${CYAN}[${YELLOW}⚠${CYAN}]${NC} $f (No English track)" | |
| SUMMARY+="\n${YELLOW}[⚠] SKIP:${NC} '$f'" | |
| else | |
| echo -e "${CYAN}[${RED}✖${CYAN}]${NC} $f (Error)" | |
| SUMMARY+="\n${RED}[✖] FAIL:${NC} '$f'" | |
| fi | |
| fi | |
| done | |
| echo "" | |
| echo -e "${GRAY}---------------------------------------${NC}" | |
| echo -e "\n${CYAN}Final Report:${NC}" | |
| echo -e "${GRAY}---------------------------------------${NC}" | |
| echo -e "${SUMMARY:-No files processed.}" | |
| echo -e "${GRAY}---------------------------------------${NC}" | |
| echo -e "Done! Updated ${GREEN}$COUNT${NC} files." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment