How to Handle Clips from Steam Game Recordings on Steam Deck

How to Handle Clips from Steam Game Recordings on Steam Deck

How Clips are Stored on Steam Deck

On the Steam Deck, game clips are stored in the directory: /home/deck/.steam/steam/Steam/userdata/$STEAM_USER_ID/gamerecordings/clips. The folders are named in the format clip_$appID_$date_$time, such as clip_1887840_20240703_213601. And video is stored in a subfolder named video in the m4s format, split into multiple sections. The m4s files are categorized into two types:

  • Video files: filenames follow the pattern *-stream0*.m4s.
  • Audio files: filenames follow the pattern *-stream1*.m4s.

Converting m4s into a Single mp4

For clips longer than one minute, manual conversion to mp4 is required. The process involves merging the video files into one mp4 file, the audio files into another mp4 file, and then combining them into a single mp4 file with both video and audio using ffmpeg.

If we are in the directory /home/deck/.steam/steam/Steam/userdata/$STEAM_USER_ID/gamerecordings/clips/clip_1887840_20240703_213601, we can use the find command to list all m4s files and sort them by the numerical suffix indicating the timeline order. Then, use the cat command to combine all stream files into one mp4.

find . -type f -name '*-stream0*.m4s' | sort -t '-' -k2 -V | xargs cat > tmp_video.mp4  

find . -type f -name '*-stream1*.m4s' | sort -t '-' -k2 -V | xargs cat > tmp_audio.mp4  

After that, use ffmpeg to merge them into the final result.

ffmpeg -i tmp_video.mp4 -i tmp_audio.mp4 -c copy final_result.mp4

Creating a Script to Sync Clips Back to a Local Device and Convert Them

Here is a shell script (for zsh) example for:

  1. Syncing all clips back to a local device.
  2. Converting each clip into a single mp4 file, naming it with $app_name-$seconds.mp4, and storing the final result in $output_dir.
  3. Removing temporary files and the clip folder.
local deck_address=deck@10.10.10.10  
local local_path="/Users/MyName"  
local game_recordings_path=/home/deck/.steam/steam/Steam/userdata/$STEAM_USER_ID/gamerecordings  

normalizing_timestamp() {  
  local timestamp=$1  
  date -j -f "%Y%m%d_%H%M%S" "$timestamp" "+%s"  
}  
get_app_name() {  
  local app_id=$1  
  local api_url="https://store.steampowered.com/api/appdetails?l=tchinese&appids=$app_id"  
  local app_name  
  
  # Fetch API response and extract app name  
  app_name=$(curl -s "$api_url" | jq -r ".\"$app_id\".data.name")  
  
  # If app name is not found or null, use app ID instead  
  if [[ -z "$app_name" || "$app_name" == "null" ]]; then  
    echo "$app_id"  
  else  
    # Replace spaces with underscores for filename  
    echo "$app_name" | tr ' ' '_'  
  fi  
}  
  
rsync -avz $deck_address:$game_recordings_path/clips $local_path/  
  
for folder in $local_path/clips/*; do  
  if [[ -d $folder ]]; then  
    echo "Processing folder: $folder"  
  
    # Extract folder name and app ID
    folder_name=$(basename $folder)  
    app_id=$(echo $folder_name | cut -d'_' -f2)  
    timestamp=$(echo $folder_name | cut -d'_' -f3,4)  
  
    # Convert timestamp to unix time
    seconds=$(normalizing_timestamp $timestamp)  
  
    # Get app name from Steam API
    app_name=$(get_app_name $app_id)  
  
    # Create app-specific output directory    
    output_dir="$local_path/Videos/$app_name"  
    mkdir -p "$output_dir"  
  
    # Create output filename  
    output_file="$output_dir/$app_name-$seconds.mp4"  
  
    # Merge video streams  
    echo "Merging video streams..."  
    find "$folder" -type f -name '*-stream0*.m4s' | sort -t '-' -k2 -V | xargs cat > "$output_dir/tmp_video.mp4"  
  
    # Merge audio streams  
    echo "Merging audio streams..."  
    find "$folder" -type f -name '*-stream1*.m4s' | sort -t '-' -k2 -V | xargs cat > "$output_dir/tmp_audio.mp4"  
  
    # Combine video and audio  
    echo "Combining video and audio..."  
    ffmpeg -i "$output_dir/tmp_video.mp4" -i "$output_dir/tmp_audio.mp4" -c copy "$output_file"  
  
    # Clean up temporary files & remove clip folder  
    rm "$output_dir/tmp_video.mp4" "$output_dir/tmp_audio.mp4" && rm -rf $folder
  
    echo "Finished processing: $output_file"  
  fi  
done

You can create a function in your ~/.zshrc or create an executable .sh file to handle the sync and conversion process.


References

https://www.reddit.com/r/SteamDeckTricks/comments/1dpj1zv/game_recording_how_it_works_and_how_you_can_get/