Created
August 29, 2023 08:42
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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