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" 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"; then echo " ✖ Video failed for $SKIN_NAME" 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 warning \ -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"; then echo " ✖ Screenshot failed for $SKIN_NAME" 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 0.3 \ -out="${SKIN_NAME}_thumb" -skin="$SKIN_NAME"; then echo " ✖ Thumbnail screenshot failed for $SKIN_NAME" 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]"