Info

🌱 來自: shell scripts

generate video

# 檢查參數是否足夠
if [ $# -lt 1 ]; then
    echo "Usage: $0 -f <input_file>"
    exit 1
fi
 
# 取得參數值
while [ $# -gt 0 ]; do
    case "$1" in
        -f)
            shift
            input_file="$1"
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
    shift
done
 
# 設定輸出目錄和檔名
output_dir="${input_file%.md}.tmp"
output_file="${input_file%.md}.mp4"
mkdir -p "$output_dir"
 
# 產生 png 圖片檔案
marp --theme-set ./themes --images png "$input_file" --image-scale 2 -o "$output_dir/${input_file%.md}.png"
 
# 分割 markdown 檔案並儲存
awk -v output_dir="$output_dir" -v input_file="$input_file" 'BEGIN { RS = "---\n"; FS = "\n" } NR > 2 { split(input_file, input_parts, "."); output_file = output_dir "/" input_parts[1] "." sprintf("%03d", NR-2) ".md"; print $0 > output_file }' "$input_file"
 
# 產生 ↪ 語音檔案和字幕檔案,並產生 ↪ 影片檔案
process_file() {
    local input_file="$1"
    local base_name="${input_file%.md}"
 
    # 轉換 markdown 檔案成為純文字檔案
    sed 's/<!--\([^>]*\)-->/[\1]/g' "$1" >> "${base_name}_mod.md"
 
    # 移除圖片設定
    sed -i '' '/!\[.*\](.*)/d' ${base_name}_mod.md
 
    # 產生 ↪ 語音檔案
    marp "${base_name}_mod.md" -o "${base_name}.txt"
    edge-tts --rate=+25% --voice zh-TW-YunJheNeural -f "${base_name}.txt" --write-media "${base_name}.mp3" --write-subtitles "${base_name}.vtt"
 
    # 處理字幕檔案
    sed -i "" 's/\([^A-Za-z]\)[[:space:]]\([^A-Za-z]\)/\1\2/g' "${base_name}.vtt"
    sed -i "" 's/\([^A-Za-z]\)[[:space:]]\([^A-Za-z]\)/\1\2/g' "${base_name}.vtt"
    perl -i -pe 's/(?<=\S)-->(?=\S)/ --> /g' "${base_name}.vtt"
    ffmpeg -y -i "${base_name}.vtt" "${base_name}.srt" -hide_banner
 
    # 取得圖片和音訊的寬度和長度
    input_image="${base_name}.png"
    image_width=$(sips -g pixelWidth "$input_image" | grep pixelWidth | awk '{print $2}')
    input_audio="${base_name}.mp3"
    output_video="${base_name}.mp4"
    duration=$(ffprobe -i "$input_audio" -show_entries format=duration -v quiet -of csv="p=0")
 
    # 設定影片檔案的格式和參數
    settings="-c:v libx264 -tune stillimage -c:a aac -b:a 96k -r 30 -pix_fmt yuv420p -t $duration"
    sub_settings="-vf subtitles=${base_name}.srt:force_style='Fontname=PingFangTC-Regular,OutlineColour=&000000000,BorderStyle=3,Outline=3,Shadow=0,MarginV=20'"
    ffmpeg -y -loop 1 -i "$input_image" -i "$input_audio" $settings $sub_settings "$output_video"
}
 
# 處理分割後的 markdown 檔案,產生 ↪ 影片檔案
for file in "$output_dir"/*.md; do
    if [ -f "$file" ]; then
        process_file "$file"
    fi
done
 
# 合併所有的影片檔案
input_list="input_list.txt"
rm -f "$input_list"
for input_file in "$output_dir"/*.mp4; do
    echo "file '$input_file'" >> "$input_list"
done
 
ffmpeg -y -f concat -safe 0 -i "$input_list" -c:v libx264 -c:a aac -strict experimental "$output_file"
 
# 顯示完成訊息
echo "🟢 DONE 🟢"
message="$output_file"
title="影片輸出已完成"
osascript -e "display notification \"$message\" with title \"$title\" sound name \"default\""