#!/bin/bash # # 20090202 jens heine # # Download videos from youtube and convert them to # a mpeg or mp3 file. # # # Variables # TMP_FILE="~youtube-suck.$$.tmp" TMP_FLV_FILE="" KEEP_TMP_FLV_FILE=0 YOUTUBE_URL="" VIDEO_URL="" OUT_FILENAME_VIDEO="" OUT_VIDEO_SIZE="" OUT_VIDEO_BITRATE="" OUT_VIDEO_FRAMERATE="24" OUT_FILENAME_AUDIO="" OUT_AUDIO_BITRATE="160k" OUT_AUDIO_SAMPLE_FREQ="22050" CONVERT_TO_MP3=0 VERBOSE=0 OUT_FILENAME_MANUAL_SET=0 # # Functions # function showUsage { echo echo " NAME" echo echo " youtube-suck - Download and convert youtube videos to mpeg/mp3" echo echo " SYNOPSIS" echo echo " youtube-suck \"youtube_url\" [OPTIONS]" echo echo " OPTIONS" echo echo " -b rate - Set output video bitrate in bits/s: \"-b 500k\"" echo " Default is to take the rate from the source video" echo " -f framerate - Set output video frame rate: \"-f 30\"" echo " Default is set to 24" echo " -B rate - Set output audio bitrate in bits/s: \"-B 56k\"" echo " Default is set to 160k" echo " -F freq - Set output audio sampling frequency in Hz: \"-F 44100\"" echo " Default is set to 22050" echo " -k - Keep youtube flv file" echo " Default is to delete it after converting" echo " -m - Convert youtube video only to mp3" echo " Default is to convert it only to mpeg" echo " -o filename - Set output filename" echo " Default is to generate one" echo " -s size - Set output video size: \"-s 320x240\"" echo " Default is to take the size from the source video" echo " -v - Be verbose, print more info" echo echo " EXAMPLES" echo echo " Download a youtube video and convert it to mpeg" echo " youtube-suck \"http://de.youtube.com/watch?v=yphwzD1XaBY\"" echo echo " Download a youtube video and convert it to mp3" echo " youtube-suck \"http://de.youtube.com/watch?v=yphwzD1XaBY\" -m" echo echo " Download a youtube video, convert it to mp3 and keep the original .flv file" echo " youtube-suck \"http://de.youtube.com/watch?v=yphwzD1XaBY\" -m -k" echo echo " If you run into errors, try to get more info with the -v option" echo " youtube-suck \"http://de.youtube.com/watch?v=yphwzD1XaBY\" -v" echo echo " INFO" echo echo " This is youtube-suck, version 0.2. Written in Feb 2009" echo " by Jens Heine . Feel free to send bugreports" echo " or comments." echo } function checkDeps { type wget >/dev/null 2>&1 || { echo "Error: wget not found. Please install it first."; exit 1; } type ffmpeg >/dev/null 2>&1 || { echo "Error: ffmpeg not found. Please install it first."; exit 1; } type sed >/dev/null 2>&1 || { echo "Error: sed not found. Please install it first."; exit 1; } } # # Main # checkDeps if [ $# -lt 1 ];then showUsage exit 1 fi # Parse Options # Check if youtube URL seems to be valid YOUTUBE_URL="$1" if [ "$YOUTUBE_URL" != "-?" -a "$YOUTUBE_URL" != "-h" ];then CHECKSTRING=${YOUTUBE_URL:0:4} if [ "$CHECKSTRING" != "http" ];then echo "Error: Youtube URL \"$YOUTUBE_URL\" seems not to be a valid http URL." echo "Use `basename $0` -? for help." exit 1 fi shift fi while getopts f:F:B:s:b:vko:mh? options;do case $options in s) OUT_VIDEO_SIZE="$OPTARG" ;; b) OUT_VIDEO_BITRATE="$OPTARG" ;; f) OUT_VIDEO_FRAMERATE="$OPTARG" ;; B) OUT_AUDIO_BITRATE="$OPTARG" ;; F) OUT_AUDIO_SAMPLE_FREQ="$OPTARG" ;; k) KEEP_TMP_FLV_FILE=1 ;; v) VERBOSE=1 ;; m) CONVERT_TO_MP3=1 ;; o) OUT_FILENAME_VIDEO="$OPTARG" OUT_FILENAME_AUDIO="$OPTARG" OUT_FILENAME_MANUAL_SET=1 ;; h) showUsage exit ;; ?) showUsage exit ;; esac done echo -n "Loading youtube url... " rm -rf "$TMP_FILE" >/dev/null 2>&1 if [ 0 -eq $VERBOSE ]; then wget -q -O "$TMP_FILE" "${YOUTUBE_URL}" || { echo "ERROR"; exit 1; } else wget -O "$TMP_FILE" "${YOUTUBE_URL}" || { echo "ERROR"; exit 1; } fi echo "OK" echo -n "Parsing website for flv url... " TMP_URL=`grep fullscreenUrl $TMP_FILE | sed -e 's/.*video_id=//g' | sed -e "s/'\;//g"` [ "$TMP_URL" ] || { echo "ERROR"; exit 1; } VIDEO_URL="http://www.youtube.com/get_video?video_id=${TMP_URL}" echo "OK" echo -n "Parsing website for video title... " # YOUTUBE_TITLE=`grep fullscreenUrl $TMP_FILE | sed -e 's/.*title=//g' | sed -e "s/'\;//g" | sed -e 's/ /_/g' | sed -e 's/,//g' | sed -e "s/'//g" | sed -e 's/\\\//g'` YOUTUBE_TITLE=`grep fullscreenUrl $TMP_FILE | sed -e 's/.*title=//g' | tr -d -c [:alnum:]` [ "$YOUTUBE_TITLE" ] || { echo "ERROR"; exit 1; } echo "OK" rm -rf "$TMP_FILE" >/dev/null 2>&1 # Generate download filenames from original title... if [ 0 -eq $OUT_FILENAME_MANUAL_SET ];then OUT_FILENAME_VIDEO="${YOUTUBE_TITLE}.mpeg" OUT_FILENAME_AUDIO="${YOUTUBE_TITLE}.mp3" fi TMP_FLV_FILE="${YOUTUBE_TITLE}.flv" # Check if youtube flv file already exists if [ -f $TMP_FLV_FILE ];then echo "\"$TMP_FLV_FILE\" alread exists." echo -n "Download it again (y/N)? " read ANSWER if [ "y" = "$ANSWER" -o "Y" = "$ANSWER" ];then rm -rf $TMP_FLV_FILE >/dev/null 2>&1 fi fi # Download youtube flv file if needed if [ ! -f $TMP_FLV_FILE ];then echo -n "Downloading youtube video to \"$TMP_FLV_FILE\"... " if [ 0 -eq $VERBOSE ]; then wget -q -O "${TMP_FLV_FILE}" "${VIDEO_URL}" || { echo "ERROR"; exit 1; } else echo wget -O "${TMP_FLV_FILE}" "${VIDEO_URL}" || { echo "ERROR"; exit 1; } fi echo "OK" fi # File conversion from flv to mpeg or mp3 if [ 0 -eq $CONVERT_TO_MP3 ];then # FLV -> MPEG echo -n "Converting video to \"$OUT_FILENAME_VIDEO\"... " rm -f ${OUT_FILENAME_VIDEO} >/dev/null 2>&1 FFMPEG_OPT="" [ "$OUT_VIDEO_SIZE" ] && { FFMPEG_OPT="$FFMPEG_OPT -s $OUT_VIDEO_SIZE"; } [ "$OUT_VIDEO_BITRATE" ] && { FFMPEG_OPT="$FFMPEG_OPT -b $OUT_VIDEO_BITRATE"; } FFMPEG_CMD="ffmpeg -i "${TMP_FLV_FILE}" -ar 22050 $FFMPEG_OPT -r $OUT_VIDEO_FRAMERATE "${OUT_FILENAME_VIDEO}"" if [ 0 -eq $VERBOSE ]; then $FFMPEG_CMD >/dev/null 2>&1 || { echo "ERROR"; exit 1; } else echo $FFMPEG_CMD || { echo "ERROR"; exit 1; } fi else # FLV -> MP3 echo -n "Converting video to \"$OUT_FILENAME_AUDIO\"... " rm -f ${OUT_FILENAME_AUDIO} >/dev/null 2>&1 FFMPEG_CMD="ffmpeg -i "${TMP_FLV_FILE}" -ar $OUT_AUDIO_SAMPLE_FREQ -ab $OUT_AUDIO_BITRATE -ac 2 ${OUT_FILENAME_AUDIO}" if [ 0 -eq $VERBOSE ]; then $FFMPEG_CMD >/dev/null 2>&1 || { echo "ERROR"; exit 1; } else $FFMPEG_CMD || { echo "ERROR"; exit 1; } fi fi [ 0 -eq $KEEP_TMP_FLV_FILE ] && rm -f "${TMP_FLV_FILE}" >/dev/null 2>&1 echo "OK" exit 0