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\""