Skip to content

Instantly share code, notes, and snippets.

@metaColin
Created August 29, 2023 08:42
Show Gist options
  • Save metaColin/8e892f43cf4657e949b566907a620f99 to your computer and use it in GitHub Desktop.
Save metaColin/8e892f43cf4657e949b566907a620f99 to your computer and use it in GitHub Desktop.
This script uses FFMPEG to convert videos to formats compatible with various iPods based on encoding profiles described in Apple technical specifications.
t#!/bin/bash
#
# Script Name: Colin's iPod Video Encoding Tool
# Version 0.2
# Description: This script uses FFMPEG to convert videos to formats compatible with various iPods based on encoding profiles described in Apple technical specifications.
# Author: Colin Steinmann
# Contact: https://github.com/metaColin
# Date: August 29, 2023
#
# License:
# This script is provided under the following terms:
#
# - You are free to use and distribute this script in any free (non-commercial) product.
# - If you wish to use this script in a commercial or monetized product, please contact the author to obtain a license.
#
# This script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# Without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Release Notes
# Only iPod gen 5.5 has been implemented (see TODO).
# Don't forget to 'chmod u+x ipod-video-encode.sh'
# FFMPEG must be installed/added to PATH to use this script
# Misc Notes
# Get video FPS: 'ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate file.mp4'
# AtomicParsley file.mp4 --DeepScan --iPod-uuid 1200
# Weird modification of 'atoms' was not yeielding good results
# In the end encoding with the '.m4v' file extension instead of '.mp4' made the iPod 5.5 accept H.264 video, up to 1.5 Mbps, 640 x 480 video
# References
# iPod 5.5 - Fifth Generation iPod (Late 2006) - Technical Specifications
# https://support.apple.com/kb/SP26?viewlocale=en_US&locale=en_US
# H.264 video, up to 1.5 Mbps, 640 by 480 pixels, 30 frames per sec, Baseline Low-Complexity Profile with AAC-LC audio up to 160 Kbps, 48 kHz, stereo audio in .m4v, .mp4, and .mov file formats
# H.264 video, up to 768 Kbps, 320 by 240 pixels, 30 frames per sec., Baseline Profile up to Level 1.3 with AAC-LC audio up to 160 Kbps, 48 kHz, stereo audio in .m4v, .mp4, and .mov file formats
# MPEG-4 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per sec., Simple Profile with AAC-LC audio up to 160 Kbps, 48 kHz, stereo audio in .m4v, .mp4, and .mov file formats
# Wikipedia - iPod Model Table
# https://en.wikipedia.org/wiki/IPod_Classic#Models
# Forum Posts
# https://www.reddit.com/r/ipod/comments/qnrurh/how_can_i_convert_video_for_the_ipod_5th_gen/
# https://stackoverflow.com/questions/59297824/ffmpeg-cli-set-r-30-if-input-30-fps-else-r-to-take-input-fps-if-30-fps
# https://stackoverflow.com/questions/27792934/get-video-fps-using-ffprobe
# https://www.reddit.com/r/ipod/comments/e3694n/encoding_for_video_5g_with_recent_handbrake/
# https://i.imgur.com/ORhKSGV.png
# https://www.reddit.com/r/ipod/comments/e8qevg/cant_add_any_mp4_480p_h264_videos_to_ipod_video/
# TODO
# Add subtitle default extraction/burn-in flags as an option for all encoding profiles.
# Add multi-track audio default extraction flags as an option for all encoding profiles.
# Add option to restore 4:3 video that had been pillarboxed for 16:9. (Thus returning it to it's former glory.)
# Add option to letterbox 16:9 movies into a 4:3 frame and then put the subs in the lettbox. Maybe push the video to allow for a bigger caption area.
# Implement additional iPod encoding profiles
# Implement iPod Nano encoding profiles (3rd, 4th, 5th, and 7th Generation)
# Implement iPod Touch encoding profiles (All Generations)
# Stretch goal: Audio encoding profiles for all iPods evar!?!!
# TODO Encoding Profiles
# iPod 5.0 - Fifth Generation iPod (iPod with video) 30 GB, 60 GB - Technical Specifications
# https://support.apple.com/kb/SP41?viewlocale=en_US&locale=en_US
# H.264 video: up to 768 Kbps, 320 x 240, 30 frames per sec., Baseline Profile up to Level 1.3 with AAC-LC up to 160 Kbps, 48 Khz, stereo audio in .m4v, .mp4 and .mov file formats
# MPEG-4 video: up to 2.5 mbps, 480 x 480, 30 frames per sec., Simple Profile with AAC-LC up to 160 Kbps, 48 Khz, stereo audio in .m4v, .mp4 and .mov file formats
# iPod 6.0 - iPod classic - Technical Specifications
# https://support.apple.com/kb/SP15?viewlocale=en_US&locale=en_US
# H.264 video, up to 1.5 Mbps, 640 by 480 pixels, 30 frames per second, Low-Complexity version of the H.264 Baseline Profile with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# H.264 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Baseline Profile up to Level 3.0 with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# MPEG-4 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Simple Profile with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# iPod 6.5 - iPod classic (120GB) - Technical Specifications
# https://support.apple.com/kb/SP498?viewlocale=en_US&locale=en_US
# H.264 video, up to 1.5 Mbps, 640 by 480 pixels, 30 frames per second, Low-Complexity version of the H.264 Baseline Profile with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# H.264 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Baseline Profile up to Level 3.0 with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# MPEG-4 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Simple Profile with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# iPod 7.0 - iPod classic 160GB (Late 2009) - Technical Specifications
# https://support.apple.com/kb/SP572?viewlocale=en_US&locale=en_US
# H.264 video, up to 1.5 Mbps, 640 by 480 pixels, 30 frames per second, Low-Complexity version of the H.264 Baseline Profile with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# H.264 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Baseline Profile up to Level 3.0 with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
# MPEG-4 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Simple Profile with AAC-LC audio up to 160 Kbps, 48kHz, stereo audio in .m4v, .mp4, and .mov file formats
echo "**************************"
echo "iPod Video Encoding Tool"
echo "**************************"
echo
echo "Select a device:"
echo " 5.0) Fifth Generation iPod"
echo " 5.5) Fifth Generation iPod (Late 2006)"
echo " 6.0) iPod classic"
echo " 6.5) iPod classic (120GB)"
echo " 7.0) iPod classic 160GB (Late 2009)"
echo
read device
echo
# Set encoding options based on the selected profile
if [[ "$device" == "5" || "$device" == "5.0" ]]; then
echo "iPod 5.0 - Fifth Generation iPod (iPod with video) 30 GB, 60 GB"
echo "Sorry, encoding profiles for this iPod have not been implemented yet"
exit 1
elif [ "$device" == "5.5" ]; then
echo "iPod 5.5 - Fifth Generation iPod (Late 2006)"
echo
echo "Select an encoding profile: " profile
echo " 1) H.264 video, up to 1.5 Mbps, 640 x 480 pixels"
echo " 2) H.264 video, up to 768 Kbps, 320 x 240 pixels"
echo " 3) MPEG-4 video, up to 2.5 Mbps, 640 x 480 pixels"
echo
read profile
echo
if [ "$profile" == "1" ]; then
echo "H.264 video, up to 1.5 Mbps, 640 by 480 pixels, 30 frames per sec, Baseline Low-Complexity Profile with AAC-LC audio up to 160 Kbps, 48 kHz, stereo audio in .m4v, .mp4, and .mov file formats"
ffmpeg_command="ffmpeg -i \"\$input_file\" -c:v libx264 -profile:v baseline -level 2.0 -b:v 0 -maxrate 1500k -bufsize 1500k -vf \"scale=w=min(640\\,iw):h=min(480\\,ih),select='eq(n,0)+if(gt(t-prev_selected_t,1/30.50),1,0)'\" -c:a aac -b:a 160k -ar 48000 -ac 2 \"converted/\$output_file.m4v\""
elif [ "$profile" == "2" ]; then
echo "H.264 video, up to 768 Kbps, 320 by 240 pixels, 30 frames per sec., Baseline Profile up to Level 1.3 with AAC-LC audio up to 160 Kbps, 48 kHz, stereo audio in .m4v, .mp4, and .mov file formats"
ffmpeg_command="ffmpeg -i \"\$input_file\" -c:v libx264 -profile:v baseline -level 1.3 -b:v 0 -maxrate 768k -vf \"scale=w=min(320\\,iw):h=min(240\\,ih),select='eq(n,0)+if(gt(t-prev_selected_t,1/30.50),1,0)'\" -c:a aac -b:a 160k -ar 48000 -ac 2 \"converted/\$output_file.mp4\""
elif [ "$profile" == "3" ]; then
echo "MPEG-4 video, up to 2.5 Mbps, 640 by 480 pixels, 30 frames per sec., Simple Profile with AAC-LC audio up to 160 Kbps, 48 kHz, stereo audio in .m4v, .mp4, and .mov file formats"
ffmpeg_command="ffmpeg -i \"\$input_file\" -c:v mpeg4 -b:v 0 -maxrate 2500k -vf \"scale=w=min(640\\,iw):h=min(480\\,ih),select='eq(n,0)+if(gt(t-prev_selected_t,1/30.50),1,0)'\" -c:a aac -b:a 160k -ar 48000 -ac 2 \"converted_mpeg4_640x480/\$output_file.mp4\""
else
echo "Invalid encoding profile selected"
exit 1
fi
elif [[ "$device" == "6" || "$device" == "6.0" ]]; then
echo "iPod 6.0 - iPod classic"
echo "Sorry, encoding profiles for this iPod have not been implemented yet"
exit 1
elif [ "$device" == "6.5" ]; then
echo "iPod 6.5 - iPod classic (120GB)"
echo "Sorry, encoding profiles for this iPod have not been implemented yet"
exit 1
elif [[ "$device" == "7" || "$device" == "7.0" ]]; then
echo "iPod 7.0 - iPod classic 160GB (Late 2009)"
echo "Sorry, encoding profiles for this iPod have not been implemented yet"
exit 1
else
echo "Invalid device selected"
exit 1
fi
echo
echo "You chose ipod gen $device, with encoding profile $profile"
echo
# echo "$ffmpeg_command"
# Create a subdirectory for converted files if it doesn't exist
mkdir -p converted
function batch_convert() {
# Loop through each file in the current directory
for input_file in *; do
# Check if the item is a file (not a directory)
if [ -f "$input_file" ]; then
# Check if the file has a video extension (you can add more extensions if needed)
if [[ "$input_file" == *.mp4 || "$input_file" == *.mkv || "$input_file" == *.avi ]]; then
# Remove the file extension using parameter expansion
output_file="${input_file%.*}"
eval "$ffmpeg_command"
fi
fi
done
}
function single_convert() {
input_file="$1"
output_file="${input_file%.*}"
eval "$ffmpeg_command"
}
echo "Choose an operation:"
echo " 1) Convert a single file"
echo " 2) Batch convert all files in the current directory"
read operation
if [ "$operation" == "1" ]; then
echo "Enter the name of the input file:"
read input_file
single_convert "$input_file"
elif [ "$operation" == "2" ]; then
batch_convert
else
echo "Invalid operation selected"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment