Reworked some of the scripts
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
git-honney333-work-cred
|
||||||
|
git-tub
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import os
|
import os
|
||||||
import ffmpeg
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
|||||||
@@ -357,169 +357,4 @@ elif [ -f "$1" ]; then
|
|||||||
else
|
else
|
||||||
echo "Error: $1 is not a valid file or directory."
|
echo "Error: $1 is not a valid file or directory."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# #!/bin/bash
|
|
||||||
|
|
||||||
# # Choose which Extensions are acceptable
|
|
||||||
|
|
||||||
|
|
||||||
# extensions=("mp4" "mkv" "avi" "mov" "m4v" "flv" "lrv")
|
|
||||||
|
|
||||||
# # Language code translation associative array
|
|
||||||
# declare -A LANG_CODES=(
|
|
||||||
# ["eng"]="English"
|
|
||||||
# ["en"]="English"
|
|
||||||
# ["spa"]="Spanish"
|
|
||||||
# ["es"]="Spanish"
|
|
||||||
# ["fra"]="French"
|
|
||||||
# ["fr"]="French"
|
|
||||||
# ["deu"]="German"
|
|
||||||
# ["ger"]="German"
|
|
||||||
# ["de"]="German"
|
|
||||||
# ["jpn"]="Japanese"
|
|
||||||
# ["ja"]="Japanese"
|
|
||||||
# ["ita"]="Italian"
|
|
||||||
# ["it"]="Italian"
|
|
||||||
# ["por"]="Portuguese"
|
|
||||||
# ["pt"]="Portuguese"
|
|
||||||
# ["rus"]="Russian"
|
|
||||||
# ["ru"]="Russian"
|
|
||||||
# ["chi"]="Chinese"
|
|
||||||
# ["zh"]="Chinese"
|
|
||||||
# ["kor"]="Korean"
|
|
||||||
# ["ko"]="Korean"
|
|
||||||
# ["dut"]="Dutch"
|
|
||||||
# ["nl"]="Dutch"
|
|
||||||
# ["swe"]="Swedish"
|
|
||||||
# ["sv"]="Swedish"
|
|
||||||
# ["fin"]="Finnish"
|
|
||||||
# ["fi"]="Finnish"
|
|
||||||
# ["pol"]="Polish"
|
|
||||||
# ["pl"]="Polish"
|
|
||||||
# ["ara"]="Arabic"
|
|
||||||
# ["ar"]="Arabic"
|
|
||||||
# ["hin"]="Hindi"
|
|
||||||
# ["hi"]="Hindi"
|
|
||||||
# ["tur"]="Turkish"
|
|
||||||
# ["tr"]="Turkish"
|
|
||||||
# ["und"]="Undefined"
|
|
||||||
# [" "]="Undefined"
|
|
||||||
# )
|
|
||||||
|
|
||||||
# # Function to translate language codes
|
|
||||||
# translate_language() {
|
|
||||||
# local code="$1"
|
|
||||||
# # Sanitize input: remove spaces and convert to lowercase
|
|
||||||
# code=$(echo "$code" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')
|
|
||||||
|
|
||||||
# # Debugging output
|
|
||||||
# # echo "DEBUG: Translating code: '$code'" >&2
|
|
||||||
|
|
||||||
# # Check for valid subscript and handle fallback
|
|
||||||
# if [[ -z "$code" || ! ${LANG_CODES[$code]+_} ]]; then
|
|
||||||
# echo "Undefined"
|
|
||||||
# else
|
|
||||||
# echo "${LANG_CODES[$code]}"
|
|
||||||
# fi
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # Function to format file size in human-readable form
|
|
||||||
# format_file_size() {
|
|
||||||
# local size_bytes="$1"
|
|
||||||
# if [ "$size_bytes" -lt 1024 ]; then
|
|
||||||
# echo "${size_bytes}B"
|
|
||||||
# elif [ "$size_bytes" -lt 1048576 ]; then
|
|
||||||
# echo "$((size_bytes / 1024))KB"
|
|
||||||
# elif [ "$size_bytes" -lt 1073741824 ]; then
|
|
||||||
# echo "$((size_bytes / 1048576))MB"
|
|
||||||
# else
|
|
||||||
# echo "$((size_bytes / 1073741824))GB"
|
|
||||||
# fi
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # Function to extract video, audio, and subtitle details for a single file
|
|
||||||
# process_file() {
|
|
||||||
# local file="$1"
|
|
||||||
# local file_size
|
|
||||||
# file_size=$(stat --printf="%s" "$file")
|
|
||||||
# formatted_size=$(format_file_size "$file_size")
|
|
||||||
|
|
||||||
# # Extract video codec, width, height, and pixel format (like yuv420p(tv, bt709))
|
|
||||||
# video_info=$(ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,width,height,pix_fmt,color_space \
|
|
||||||
# -of default=noprint_wrappers=1:nokey=1 "$file")
|
|
||||||
# codec=$(echo "$video_info" | sed -n '1p')
|
|
||||||
# width=$(echo "$video_info" | sed -n '2p')
|
|
||||||
# height=$(echo "$video_info" | sed -n '3p')
|
|
||||||
# pix_fmt=$(echo "$video_info" | sed -n '4p')
|
|
||||||
# color_space=$(echo "$video_info" | sed -n '5p')
|
|
||||||
|
|
||||||
# # Extract audio information (language, codec, and channel layout)
|
|
||||||
# audio_info=$(ffprobe -v quiet -select_streams a -show_entries stream=codec_name,channel_layout:stream_tags=language \
|
|
||||||
# -of default=noprint_wrappers=1:nokey=1 "$file" | paste -sd "," -)
|
|
||||||
|
|
||||||
# # Extract subtitle information (language)
|
|
||||||
# subtitle_info=$(ffprobe -v quiet -select_streams s -show_entries stream_tags=language \
|
|
||||||
# -of default=noprint_wrappers=1:nokey=1 "$file" | paste -sd "," -)
|
|
||||||
|
|
||||||
# # Format video output
|
|
||||||
# video_output="Video: ${codec} (${width}x${height}), ${pix_fmt} (${color_space})"
|
|
||||||
|
|
||||||
# # Format audio output
|
|
||||||
# audio_output="Audio: "
|
|
||||||
# IFS=',' read -r -a audio_streams <<< "$audio_info"
|
|
||||||
# for (( i=0; i<${#audio_streams[@]}; i+=3 )); do
|
|
||||||
# audio_codec="${audio_streams[i]}"
|
|
||||||
# channel_layout="${audio_streams[i+1]}"
|
|
||||||
# lang_code="${audio_streams[i+2]}"
|
|
||||||
# lang=$(translate_language "${lang_code:-" "}")
|
|
||||||
# audio_output+="${lang} ${audio_codec} ${channel_layout}"
|
|
||||||
# if (( i+3 < ${#audio_streams[@]} )); then
|
|
||||||
# audio_output+=", "
|
|
||||||
# fi
|
|
||||||
# done
|
|
||||||
|
|
||||||
# # Format subtitle output
|
|
||||||
# subtitle_output="Subtitles: "
|
|
||||||
# if [ -n "$subtitle_info" ]; then
|
|
||||||
# IFS=',' read -r -a subtitle_streams <<< "$subtitle_info"
|
|
||||||
# for lang in "${subtitle_streams[@]}"; do
|
|
||||||
# subtitle_output+=$(translate_language "$lang")
|
|
||||||
# subtitle_output+=", "
|
|
||||||
# done
|
|
||||||
# # Remove the last comma
|
|
||||||
# subtitle_output=${subtitle_output%, }
|
|
||||||
# else
|
|
||||||
# subtitle_output="Subtitles: None"
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# # Output the result for the file
|
|
||||||
# echo "$file ($formatted_size):"
|
|
||||||
# echo -e "\t$video_output"
|
|
||||||
# echo -e "\t$audio_output"
|
|
||||||
# echo -e "\t$subtitle_output"
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # Main script logic
|
|
||||||
# if [ -z "$1" ]; then
|
|
||||||
# for ext in "${extensions[@]}"; do
|
|
||||||
# # No argument provided, process all video files in the current directory
|
|
||||||
# for file in *."$ext"; do
|
|
||||||
# [ -e "$file" ] || continue # Skip if no matching files
|
|
||||||
# process_file "$file"
|
|
||||||
# done
|
|
||||||
# done
|
|
||||||
# elif [ -d "$1" ]; then
|
|
||||||
# # Argument is a directory, process all video files in that directory
|
|
||||||
# for file in "$1"/*.{mp4,mkv,avi,mov}; do
|
|
||||||
# [ -e "$file" ] || continue # Skip if no matching files
|
|
||||||
# process_file "$file"
|
|
||||||
# done
|
|
||||||
# elif [ -f "$1" ]; then
|
|
||||||
# # Argument is a single file, process only that file
|
|
||||||
# process_file "$1"
|
|
||||||
# else
|
|
||||||
# echo "Error: $1 is not a valid file or directory."
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
130
video-audio
Executable file
130
video-audio
Executable file
@@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
def run(cmd):
|
||||||
|
print(f"[*] Running: {' '.join(map(str, cmd))}")
|
||||||
|
subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
def get_tracks(video):
|
||||||
|
result = subprocess.run(
|
||||||
|
["mkvmerge", "-J", str(video)],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
data = json.loads(result.stdout)
|
||||||
|
return [t for t in data["tracks"] if t["type"] == "audio"]
|
||||||
|
|
||||||
|
def codec_to_ext(codec):
|
||||||
|
codec = codec.lower()
|
||||||
|
if "aac" in codec: return "aac"
|
||||||
|
if "ac-3" in codec or "ac3" in codec: return "ac3"
|
||||||
|
if "dts" in codec: return "dts"
|
||||||
|
if "flac" in codec: return "flac"
|
||||||
|
if "opus" in codec: return "opus"
|
||||||
|
return "mka"
|
||||||
|
|
||||||
|
def clean(text):
|
||||||
|
return "".join(c if c.isalnum() or c in "-_." else "_" for c in text)
|
||||||
|
|
||||||
|
def extract(vdir, outdir):
|
||||||
|
outdir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
for video in vdir.iterdir():
|
||||||
|
if not video.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = video.stem
|
||||||
|
print(f"\n=== Scanning {video.name} ===")
|
||||||
|
|
||||||
|
for track in get_tracks(video):
|
||||||
|
tid = track["id"]
|
||||||
|
props = track.get("properties", {})
|
||||||
|
lang = props.get("language", "und")
|
||||||
|
tname = props.get("track_name", "")
|
||||||
|
codec = track.get("codec", "")
|
||||||
|
|
||||||
|
ext = codec_to_ext(codec)
|
||||||
|
|
||||||
|
suffix = lang
|
||||||
|
if tname:
|
||||||
|
suffix += "-" + clean(tname)
|
||||||
|
|
||||||
|
outfile = outdir / f"{name}-{suffix}.{ext}"
|
||||||
|
|
||||||
|
print(f"Extracting track {tid}: lang={lang}, name={tname}, codec={codec}")
|
||||||
|
run(["mkvextract", "tracks", str(video), f"{tid}:{outfile}"])
|
||||||
|
|
||||||
|
def include(vdir, adir):
|
||||||
|
for video in vdir.iterdir():
|
||||||
|
if not video.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = video.stem
|
||||||
|
tmp = video.with_name(name + "-tmp.mkv")
|
||||||
|
|
||||||
|
print(f"\n=== Processing {video.name} ===")
|
||||||
|
|
||||||
|
audios = list(adir.glob(f"{name}-*"))
|
||||||
|
if not audios:
|
||||||
|
print("No matching audio found.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
unknown = []
|
||||||
|
known = []
|
||||||
|
|
||||||
|
for a in audios:
|
||||||
|
meta = a.stem[len(name)+1:] # remove "name-"
|
||||||
|
parts = meta.split("-", 1)
|
||||||
|
lang = parts[0]
|
||||||
|
tname = parts[1] if len(parts) > 1 else ""
|
||||||
|
|
||||||
|
entry = (a, lang, tname)
|
||||||
|
if lang in ("und", "unknown", ""):
|
||||||
|
unknown.append(entry)
|
||||||
|
else:
|
||||||
|
known.append(entry)
|
||||||
|
|
||||||
|
cmd = ["mkvmerge", "-o", str(tmp), str(video)]
|
||||||
|
|
||||||
|
for file, lang, tname in unknown + known:
|
||||||
|
print(f"Adding {file.name} lang={lang} name={tname}")
|
||||||
|
cmd += ["--language", f"0:{lang}"]
|
||||||
|
if tname:
|
||||||
|
cmd += ["--track-name", f"0:{tname}"]
|
||||||
|
cmd.append(str(file))
|
||||||
|
|
||||||
|
run(cmd)
|
||||||
|
shutil.move(tmp, video)
|
||||||
|
print(f"Finished {video.name}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("Usage:")
|
||||||
|
print(" script extract <video_dir> [audio_out_dir]")
|
||||||
|
print(" script include <video_dir> [audio_dir]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
action = sys.argv[1]
|
||||||
|
vdir = Path(sys.argv[2]).resolve()
|
||||||
|
adir = Path(sys.argv[3]).resolve() if len(sys.argv) > 3 else vdir
|
||||||
|
|
||||||
|
if not vdir.is_dir():
|
||||||
|
print("Video directory not found.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if action == "extract":
|
||||||
|
extract(vdir, adir)
|
||||||
|
elif action == "include":
|
||||||
|
include(vdir, adir)
|
||||||
|
else:
|
||||||
|
print("Unknown action.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user