diff --git a/.gitea/actions/generate-previews/action.yml b/.gitea/actions/generate-previews/action.yml index 9e0da85..2c1ed5c 100644 --- a/.gitea/actions/generate-previews/action.yml +++ b/.gitea/actions/generate-previews/action.yml @@ -1,183 +1,203 @@ -name: "Generate Previews" -description: "Generate Danser videos, screenshots, thumbnails, and rename them based on skin.ini" - -inputs: - changed_skins_file: - description: "Path to JSON file containing changed skins" - required: true - -runs: - using: "composite" - steps: - - name: Generate Danser videos and screenshots - shell: bash - run: | - echo "[Danser Job Started]" - - if [ -z "${{ inputs.changed_skins_file }}" ] || [ ! -s "${{ inputs.changed_skins_file }}" ]; then - echo "No skins changed. Skipping generation." - exit 0 - fi - - mapfile -t skins < <(jq -r '.[]' "${{ inputs.changed_skins_file }}") - [ "${#skins[@]}" -eq 0 ] && { echo "No skins to process. Exiting."; exit 0; } - - SKIN_COUNT=${#skins[@]} - INDEX=1 - - for skin_path in "${skins[@]}"; do - [ -z "$skin_path" ] && continue - SKIN_DIR="$DANSER_SKINS_DIR/$skin_path" - [ ! -d "$SKIN_DIR" ] && { echo "Skipping missing skin: $skin_path"; continue; } - - SKIN_NAME="$skin_path" - OUT_VIDEO_DIR="$REPO_SCREENSHOT_DIR/$SKIN_NAME" - OUT_PNG_DIR="$REPO_RANKING_PANEL_DIR/$SKIN_NAME" - OUT_THUMBNAIL_DIR="$REPO_THUMBNAIL_DIR/$SKIN_NAME" - - echo "" - echo "[$INDEX/$SKIN_COUNT] Generating for skin: $SKIN_NAME" - - LOGFILE="/tmp/danser_log_$INDEX.txt" - - echo " → Generating video..." - if ! xvfb-run -a "$DANSER_DIR/danser-cli" \ - -replay "$GAMEPLAY_REPLAY_PATH" -record -skip -start=300 -end=307 -noupdatecheck \ - -out="$SKIN_NAME" -skin="$SKIN_NAME" -settings="skinhub" >"$LOGFILE" 2>&1; then - echo " ✖ Video failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue - fi - - if [ -f "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" ]; then - echo " → Trimming MP4 with ffmpeg..." - ffmpeg -hide_banner -loglevel error \ - -ss 5 -t 6.5 \ - -i "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" \ - -c:v h264_nvenc -preset fast \ - -c:a aac -b:a 128k \ - "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" - - if [ -f "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" ]; then - mv "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" - mkdir -p "$OUT_VIDEO_DIR" - mv "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" "$OUT_VIDEO_DIR/$SKIN_NAME.mp4" - echo " ✓ Trimmed MP4 moved to $OUT_VIDEO_DIR/" - else - echo " ✖ ffmpeg trimming failed for $SKIN_NAME" - fi - else - echo " ✖ No MP4 found for $SKIN_NAME" - fi - - echo " → Taking screenshot..." - if ! xvfb-run -a "$DANSER_DIR/danser-cli" \ - -replay "$PANEL_REPLAY_PATH" -skip -settings="skinhub" -noupdatecheck -ss 28 \ - -out="$SKIN_NAME" -skin="$SKIN_NAME" >>"$LOGFILE" 2>&1; then - echo " ✖ Screenshot failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue - fi - - if [ -f "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" ]; then - mkdir -p "$OUT_PNG_DIR" - mv "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" "$OUT_PNG_DIR/$SKIN_NAME.png" - echo " ✓ PNG moved to $OUT_PNG_DIR/" - else - echo " ✖ No PNG found for $SKIN_NAME" - fi - - echo " → Taking thumbnail screenshot..." - if ! xvfb-run -a "$DANSER_DIR/danser-cli" \ - -replay "$THUMBNAIL_REPLAY_PATH" -skip -settings="skinhub" -noupdatecheck -ss 1.3 \ - -out="${SKIN_NAME}_thumb" -skin="$SKIN_NAME" >>"$LOGFILE" 2>&1; then - echo " ✖ Thumbnail screenshot failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue - fi - - if [ -f "$DANSER_SCREENSHOT_DIR/${SKIN_NAME}_thumb.png" ]; then - mkdir -p "$OUT_THUMBNAIL_DIR" - mv "$DANSER_SCREENSHOT_DIR/${SKIN_NAME}_thumb.png" "$OUT_THUMBNAIL_DIR/$SKIN_NAME.png" - echo " ✓ Thumbnail PNG moved to $OUT_THUMBNAIL_DIR/" - else - echo " ✖ No thumbnail PNG found for $SKIN_NAME" - fi - - INDEX=$((INDEX + 1)) - done - - echo "" - echo "[Danser Job Finished — processed $SKIN_COUNT skins]" - - - name: Rename Generated Assets Based on skin.ini - shell: bash - run: | - echo "[Asset Renaming Job Started]" - - if [ -z "${{ inputs.changed_skins_file }}" ] || [ ! -s "${{ inputs.changed_skins_file }}" ]; then - echo "No skins changed. Skipping asset renaming." - exit 0 - fi - - # Load skins from JSON - mapfile -t skins < <(jq -r '.[]' "${{ inputs.changed_skins_file }}") - [ "${#skins[@]}" -eq 0 ] && { echo "No skins to rename. Exiting."; exit 0; } - - SKIN_COUNT=${#skins[@]} - INDEX=1 - - sanitize_filename() { - echo "$1" | \ - tr -d '\000-\037' | \ - sed -e 's#[\\/:\*\?"<>|]#-#g' | \ - sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' - } - - for skin_path in "${skins[@]}"; do - [ -z "$skin_path" ] && continue - SKIN_DIR_NAME="$skin_path" - SKIN_DIR="$DANSER_SKINS_DIR/$skin_path" - - if [ ! -d "$SKIN_DIR" ]; then - echo "Skipping missing skin directory: $SKIN_DIR" - continue - fi - - echo "Processing skin $INDEX/$SKIN_COUNT: $SKIN_DIR_NAME" - - skin_header="$SKIN_DIR_NAME" - ini_file=$(find "$SKIN_DIR" -maxdepth 1 -iname "skin.ini" | head -n1 || true) - if [ -f "$ini_file" ]; then - name_line=$(grep -i '^[[:space:]]*Name:' "$ini_file" | head -n1 || true) - if [ -n "$name_line" ]; then - val="${name_line#*:}" - val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" - if [ -n "$val" ]; then - sanitized="$(sanitize_filename "$val")" - [ -n "$sanitized" ] && skin_header="$sanitized" - fi - fi - fi - - VIDEO_DIR="$REPO_SCREENSHOT_DIR/$SKIN_DIR_NAME" - PNG_DIR="$REPO_RANKING_PANEL_DIR/$SKIN_DIR_NAME" - THUMBNAIL_DIR="$REPO_THUMBNAIL_DIR/$SKIN_DIR_NAME" - - if [ -f "$VIDEO_DIR/$SKIN_DIR_NAME.mp4" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then - mv -f "$VIDEO_DIR/$SKIN_DIR_NAME.mp4" \ - "$VIDEO_DIR/$skin_header.mp4" || true - echo " ✓ Renamed MP4 to $VIDEO_DIR/$skin_header.mp4" - fi - - if [ -f "$PNG_DIR/$SKIN_DIR_NAME.png" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then - mv -f "$PNG_DIR/$SKIN_DIR_NAME.png" \ - "$PNG_DIR/$skin_header.png" || true - echo " ✓ Renamed PNG to $PNG_DIR/$skin_header.png" - fi - - if [ -f "$THUMBNAIL_DIR/$SKIN_DIR_NAME.png" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then - mv -f "$THUMBNAIL_DIR/$SKIN_DIR_NAME.png" \ - "$THUMBNAIL_DIR/$skin_header.png" || true - echo " ✓ Renamed thumbnail to $THUMBNAIL_DIR/$skin_header.png" - fi - - INDEX=$((INDEX + 1)) - done - - echo "" - echo "[Asset Renaming Complete — processed $SKIN_COUNT skins]" +name: "Generate Previews" +description: "Generate Danser videos, screenshots, thumbnails, and rename them based on skin.ini" + +inputs: + changed_skins_file: + description: "Path to JSON file containing changed skins" + required: true + +runs: + using: "composite" + steps: + - name: Generate Danser videos and screenshots + shell: bash + run: | + echo "[Danser Job Started]" + + retry() { + local n=1 + local max=5 + local delay=2 + while true; do + "$@" && break || { + if [[ $n -lt $max ]]; then + echo "Attempt $n failed. Retrying in $delay seconds..." + sleep $delay + ((n++)) + else + echo "Attempt $n failed. No more retries left." + return 1 + fi + } + done + } + + if [ -z "${{ inputs.changed_skins_file }}" ] || [ ! -s "${{ inputs.changed_skins_file }}" ]; then + echo "No skins changed. Skipping generation." + exit 0 + fi + + mapfile -t skins < <(jq -r '.[]' "${{ inputs.changed_skins_file }}") + [ "${#skins[@]}" -eq 0 ] && { echo "No skins to process. Exiting."; exit 0; } + + SKIN_COUNT=${#skins[@]} + INDEX=1 + + for skin_path in "${skins[@]}"; do + [ -z "$skin_path" ] && continue + SKIN_DIR="$DANSER_SKINS_DIR/$skin_path" + [ ! -d "$SKIN_DIR" ] && { echo "Skipping missing skin: $skin_path"; continue; } + + SKIN_NAME="$skin_path" + OUT_VIDEO_DIR="$REPO_SCREENSHOT_DIR/$SKIN_NAME" + OUT_PNG_DIR="$REPO_RANKING_PANEL_DIR/$SKIN_NAME" + OUT_THUMBNAIL_DIR="$REPO_THUMBNAIL_DIR/$SKIN_NAME" + + echo "" + echo "[$INDEX/$SKIN_COUNT] Generating for skin: $SKIN_NAME" + + LOGFILE="/tmp/danser_log_$INDEX.txt" + + echo " → Generating video..." + if ! retry xvfb-run -a "$DANSER_DIR/danser-cli" \ + -replay "$GAMEPLAY_REPLAY_PATH" -record -skip -start=300 -end=307 -noupdatecheck \ + -out="$SKIN_NAME" -skin="$SKIN_NAME" -settings="skinhub" >"$LOGFILE" 2>&1; then + echo " ✖ Video failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue + fi + + if [ -f "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" ]; then + echo " → Trimming MP4 with ffmpeg..." + if ! retry ffmpeg -hide_banner -loglevel error \ + -ss 5 -t 6.5 \ + -i "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" \ + -c:v h264_nvenc -preset fast \ + -c:a aac -b:a 128k \ + "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4"; then + echo " ✖ ffmpeg trimming failed for $SKIN_NAME" + fi + + if [ -f "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" ]; then + mv "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" + mkdir -p "$OUT_VIDEO_DIR" + mv "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" "$OUT_VIDEO_DIR/$SKIN_NAME.mp4" + echo " ✓ Trimmed MP4 moved to $OUT_VIDEO_DIR/" + else + echo " ✖ No trimmed MP4 created for $SKIN_NAME" + fi + else + echo " ✖ No MP4 found for $SKIN_NAME" + fi + + echo " → Taking screenshot..." + if ! retry xvfb-run -a "$DANSER_DIR/danser-cli" \ + -replay "$PANEL_REPLAY_PATH" -skip -settings="skinhub" -noupdatecheck -ss 28 \ + -out="$SKIN_NAME" -skin="$SKIN_NAME" >>"$LOGFILE" 2>&1; then + echo " ✖ Screenshot failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue + fi + + if [ -f "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" ]; then + mkdir -p "$OUT_PNG_DIR" + mv "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" "$OUT_PNG_DIR/$SKIN_NAME.png" + echo " ✓ PNG moved to $OUT_PNG_DIR/" + else + echo " ✖ No PNG found for $SKIN_NAME" + fi + + echo " → Taking thumbnail screenshot..." + if ! retry xvfb-run -a "$DANSER_DIR/danser-cli" \ + -replay "$THUMBNAIL_REPLAY_PATH" -skip -settings="skinhub" -noupdatecheck -ss 1.3 \ + -out="${SKIN_NAME}_thumb" -skin="$SKIN_NAME" >>"$LOGFILE" 2>&1; then + echo " ✖ Thumbnail screenshot failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue + fi + + if [ -f "$DANSER_SCREENSHOT_DIR/${SKIN_NAME}_thumb.png" ]; then + mkdir -p "$OUT_THUMBNAIL_DIR" + mv "$DANSER_SCREENSHOT_DIR/${SKIN_NAME}_thumb.png" "$OUT_THUMBNAIL_DIR/$SKIN_NAME.png" + echo " ✓ Thumbnail PNG moved to $OUT_THUMBNAIL_DIR/" + else + echo " ✖ No thumbnail PNG found for $SKIN_NAME" + fi + + INDEX=$((INDEX + 1)) + done + + echo "" + echo "[Danser Job Finished — processed $SKIN_COUNT skins]" + + - name: Rename Generated Assets Based on skin.ini + shell: bash + run: | + echo "[Asset Renaming Job Started]" + + if [ -z "${{ inputs.changed_skins_file }}" ] || [ ! -s "${{ inputs.changed_skins_file }}" ]; then + echo "No skins changed. Skipping asset renaming." + exit 0 + fi + + # Load skins from JSON + mapfile -t skins < <(jq -r '.[]' "${{ inputs.changed_skins_file }}") + [ "${#skins[@]}" -eq 0 ] && { echo "No skins to rename. Exiting."; exit 0; } + + SKIN_COUNT=${#skins[@]} + INDEX=1 + + sanitize_filename() { + echo "$1" | \ + tr -d '\000-\037' | \ + sed -e 's#[\\/:\*\?"<>|]#-#g' | \ + sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' + } + + for skin_path in "${skins[@]}"; do + [ -z "$skin_path" ] && continue + SKIN_DIR_NAME="$skin_path" + SKIN_DIR="$DANSER_SKINS_DIR/$skin_path" + + if [ ! -d "$SKIN_DIR" ]; then + echo "Skipping missing skin directory: $SKIN_DIR" + continue + fi + + echo "Processing skin $INDEX/$SKIN_COUNT: $SKIN_DIR_NAME" + + skin_header="$SKIN_DIR_NAME" + ini_file=$(find "$SKIN_DIR" -maxdepth 1 -iname "skin.ini" | head -n1 || true) + if [ -f "$ini_file" ]; then + name_line=$(grep -i '^[[:space:]]*Name:' "$ini_file" | head -n1 || true) + if [ -n "$name_line" ]; then + val="${name_line#*:}" + val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" + if [ -n "$val" ]; then + sanitized="$(sanitize_filename "$val")" + [ -n "$sanitized" ] && skin_header="$sanitized" + fi + fi + fi + + VIDEO_DIR="$REPO_SCREENSHOT_DIR/$SKIN_DIR_NAME" + PNG_DIR="$REPO_RANKING_PANEL_DIR/$SKIN_DIR_NAME" + THUMBNAIL_DIR="$REPO_THUMBNAIL_DIR/$SKIN_DIR_NAME" + + if [ -f "$VIDEO_DIR/$SKIN_DIR_NAME.mp4" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then + mv -f "$VIDEO_DIR/$SKIN_DIR_NAME.mp4" \ + "$VIDEO_DIR/$skin_header.mp4" || true + echo " ✓ Renamed MP4 to $VIDEO_DIR/$skin_header.mp4" + fi + + if [ -f "$PNG_DIR/$SKIN_DIR_NAME.png" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then + mv -f "$PNG_DIR/$SKIN_DIR_NAME.png" \ + "$PNG_DIR/$skin_header.png" || true + echo " ✓ Renamed PNG to $PNG_DIR/$skin_header.png" + fi + + if [ -f "$THUMBNAIL_DIR/$SKIN_DIR_NAME.png" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then + mv -f "$THUMBNAIL_DIR/$SKIN_DIR_NAME.png" \ + "$THUMBNAIL_DIR/$skin_header.png" || true + echo " ✓ Renamed thumbnail to $THUMBNAIL_DIR/$skin_header.png" + fi + + INDEX=$((INDEX + 1)) + done + + echo "" + echo "[Asset Renaming Complete — processed $SKIN_COUNT skins]"