Youtube

From Blue-IT.org Wiki

Revision as of 19:20, 9 January 2012 by WikiSysOp (talk | contribs)

Youtube upload script

Thanks to an article on the german website "Linux und ich" , I decided to make my own upload script. I makes heavy usage of the source code provide youtube-upload.py, a python script. It also uses the split-tool provided in the examples directory!

Legal notice

This script is given AS IS. I am not responsible for loss of data (which is really not what I want and not likely to happen). But furthermore I am not responsible, if your google data is hacked using an insecure network or given away your data otherwise or using the third party software youtube-upload used by this script.

Prerequisites

  • have an ogv video (gtkRecordMyDesktop), e.g myvideo_name.ogv
  • you like to convert and upload it to Youtube using Nautilus (or in batch mode in bash)
  • provide your Youtube account data (which are the same like for google) in the code of the script
  • login into youtube in your browser (this will open you video page, when the script finished)
  • prepare a file named e.g. myvideo_name.meta - if you like - in the same directory as the video with the following content:
TITLE="Your title here"
DESCRIPTION="Description here"
# Valid categories: Tech Education Animals People Travel Entertainment Howto Sports Autos Music News Games Nonprofit Comedy Film
CATEGORY="Category here"
KEYWORDS="Keywords (colon separated here)"

It will be used for uploading the file. If you don't have such a file, a new one will be created when you enter your data (you will be asked)

  • have split_video_for_youtube.sh in your path and youtube_upload.py somewhere (get it here: youtube-uploade at google code )
  • have a wrapperfile called youtube-upload in your path:
#!/bin/bash
python /wherever/is/youtube_upload.py "${@}"

in your path, and made them executable (chmod +x filename)!!!

  • have mencoder installed

This is a nautilus script, can be turned into normal script

Put the given script into

~/gnome2/nautilus-scripts

and make it executable.

chmod +x scriptname

Beeing a nautilus script it can be easily turned into shell script changing the line

cd "$NAUTILUS_SCRIPT_CURRENT_URI"

into

cd "$(pwd)"

This might be also handy for troubleshooting!!!

If you like to like to make everything without interaction, you can alter the last part of the script beginning with:

if [ -f ${MYBASENAME}.part*.${MYCONVTYPE} ]
then
# Converted video exists

delete it until the end and substitude it with:

[ -f ${MYBASENAME}.meta ] || set_youtube_metadata
split_it
upload_it

This way the script will run through without asking you.

So here we go

#!/bin/bash

# Convert any given Video to a youtube compatible format ... and upload it
# Uses https://code.google.com/p/youtube-upload/ to upload to youtube

# version 0.0.1, 01-05-2012 - Axel Pospischil, http://www.blue-it.org
# version 0.0.3, 01-06-2012 - Axel Pospischil, http://www.blue-it.org
#       - if ffmpeg fails, mencoder is used
#       - ogv, ogg and mkv is allowed for input (if you are using tibesti)
#       - if mkv exists not conversion is done, only splitting

########################################################################################

MYCONVTYPE="mkv"	  			# Used by the split tool
#YOUTUBE_EMAIL="myname@googlemail.com"
#YOUTUBE_PASSWORD="secret_password"
#YOUTUBE_CHANNEL="MyChannelName"

VALID_CATEGORY="Tech Education Animals People Travel Entertainment Howto Sports Autos Music News Games Nonprofit Comedy Film"

########################################################################################
## Change this for toggling beeing a bash-script or a nautilus-script
cd "$NAUTILUS_SCRIPT_CURRENT_URI"
#cd "$(pwd)"

MYFILE="${1}"
# Filename correction
MYFILE_CORRECTED="$(echo $MYFILE | sed -e 's/\:/-/g')"
mv -f "${MYFILE}" "${MYFILE_CORRECTED}"
MYFILE="${MYFILE_CORRECTED}"

VIDEOTYPE_IS_OK="false"
file "${MYFILE}" | grep -v grep | grep ".ogv: Ogg data"  && VIDEOTYPE_IS_OK="true"
file "${MYFILE}" | grep -v grep | grep ".ogg: Ogg data"  && VIDEOTYPE_IS_OK="true"
file "${MYFILE}" | grep -v grep | grep ".mkv: data" && VIDEOTYPE_IS_OK="true"
MYTYPE=""
file "${MYFILE}" | grep -v grep | grep ".ogg: Ogg data"  && MYTYPE="ogg"
file "${MYFILE}" | grep -v grep | grep ".ogv: Ogg data"  && MYTYPE="ogv"
file "${MYFILE}" | grep -v grep | grep ".mkv: data" && MYTYPE="mkv"

MYBASENAME="$(basename ${MYFILE} .${MYTYPE})"
TITLE="Titel eingeben..."
DESCRIPTION="Beschreibung hinzufügen..."
CATEGORY="Howto"
KEYWORDS="Stichwörter (kommagetrennt)..."
[ -f ${MYBASENAME}.meta ] && source ${MYBASENAME}.meta
VIDEO_COUNT=0



split_it() {
	
        if test split_video_for_youtube.sh ${MYBASENAME}.${MYTYPE}
	then
		echo "Files splitted ..."
	else
		if [ "${MYTYPE}" = "mkv" ]
		then		
			# no conversion, but move to special pattern ...
			mv "${MYBASENAME}.${MYTYPE}" "${MYBASENAME}.part001.${MYCONVTYPE}"

		        notify-send  "Konvertierung nicht notwendig" \
		                -i /local/share/icons/kino.png \
		                "Das Video ${MYBASENAME} wird jetzt hochgeladen."

		else
			# Mencoder produces smaller files, but I had some troubles with audio synchronisation
			#mencoder ${MYBASENAME}.${MYTYPE} -o ${MYBASENAME}.part001.${MYCONVTYPE} -oac mp3lame -ovc lavc

	  		# FFmpeg tries it best preserving the quality
			if ffmpeg -y -i "${MYBASENAME}.${MYTYPE}" \
				-vcodec mpeg4 -acodec libfaac -sameq \
				"${MYBASENAME}.part001.${MYCONVTYPE}"
			then
			        notify-send  "Konvertierung erfolgreich" \
			                -i /local/share/icons/kino.png \
			                "Das Video ${MYBASENAME} wird jetzt hochgeladen."
			else
				if mencoder ${MYBASENAME}.${MYTYPE} -o ${MYBASENAME}.part001.${MYCONVTYPE} -oac mp3lame -ovc lavc
				then
				        notify-send  "Konvertierung erfolgreich" \
			                -i /local/share/icons/kino.png \
			                "Das Video ${MYBASENAME} wird jetzt hochgeladen."
				else

				        notify-send  "Konvertierung fehlgeschlagen" \
			                -i /local/share/icons/kino.png \
			                "Das Video ${MYBASENAME} konnte nicht konvertiert werden!"

				zenity --info --text "Versuchen sie in einem Terminal:\n\nffmpeg -i ${MYBASENAME}.${MYTYPE} -vcodec mpeg4 -acodec libfaac -sameq ${MYBASENAME}.part001.${MYCONVTYPE}"
				exit 1
				
				fi
			fi
		fi
	fi
        VIDEO_COUNT=$(ls ${MYBASENAME}.part*.${MYCONVTYPE} | wc | awk '{print $1}')


}

upload_it() {

COUNT=$VIDEO_COUNT
while ( [ $COUNT -gt 0 ] );
do

	if [ $VIDEO_COUNT -eq 1 ]
	then PART=""
	else PART=" - Part $COUNT - $VIDEO_COUNT"
	fi

	youtube-upload 	--email="${YOUTUBE_EMAIL}" \
			--password="${YOUTUBE_PASSWORD}" \
			--title="${TITLE}${PART}" \
			--description="${DESCRIPTION}" \
			--category="${CATEGORY}" \
			--keywords="${KEYWORDS}" \
			${MYBASENAME}.part*${COUNT}.${MYCONVTYPE} | \
	zenity  --progress --auto-close --pulsate --no-cancel \
                --title "Lade hoch ..." \
                --text  "Lade ${MYBASENAME}${PART} auf Youtube hoch ..." && \
        notify-send  "Hochladen von Videodatei" \
                -i /local/share/icons/ktorrent.png \
                "Hochladen von ${MYBASENAME}.${PART} erfolgreich."

	COUNT=$(expr $COUNT - 1)
	echo "COUNT is: $COUNT"
done

sync

# If you like to delete the generated videos for upload, uncomment the following
[ "${MYTYPE}" = "mkv" ] || rm -f ${MYBASENAME}.part*.${MYCONVTYPE}
#[ "${MYTYPE}" = "mkv" ] || zenity --info --"${MYBASENAME}.part*.${MYCONVTYPE} gelöscht"

# Channel
#exec firefox "http://www.youtube.com/user/${YOUTUBE_CHANNEL}/videos" &

# You have to be logged in to see this site:
exec firefox "http://www.youtube.com/my_videos?feature=mhee" &

}

set_youtube_metadata() {

	if [ -f ${MYBASENAME}.meta ] 
	then
		source ${MYBASENAME}.meta
	else
		echo "TITLE=\"${TITLE}\"" > "${MYBASENAME}.meta"
		echo "DESCRIPTION=\"${DESCRIPTION}\"" >> "${MYBASENAME}.meta"
		echo "# Valid categories: ${VALID_CATEGORY}"  >> "${MYBASENAME}.meta"
		echo "CATEGORY=\"${CATEGORY}"\" >> "${MYBASENAME}.meta"
		echo "KEYWORDS=\"${KEYWORDS}\"" >> "${MYBASENAME}.meta"
	fi

}

#edit_metadata() {
#
#	[ -f ${MYBASENAME}.meta ] || set_youtube_metadata
#	EDITNAME="$(echo ${MYBASENAME}.meta)"
#	gedit "${EDITNAME}"
#	source "${MYBASENAME}.meta"
#
#}

edit_metadata() {

	[ -f ${MYBASENAME}.meta ] ||  set_youtube_metadata
	
	TITLE="$(zenity --entry --text "Titel:" --entry-text="${TITLE}")"
	DESCRIPTION="$(zenity --text "Beschreibung:" --entry --entry-text="${DESCRIPTION}")"
	CATEGORY="$(zenity --text "Kategorie:\n\n${VALID_CATEGORY}" --entry --entry-text="${CATEGORY}")"
	KEYWORDS="$(zenity --text "Stichwörter:" --entry --entry-text="${KEYWORDS}")"
	source "${MYBASENAME}.meta"

}


###################################
# Main

if [ "${VIDEOTYPE_IS_OK}" = "true" ]
then
	echo "Filecheck OK"
else
	zenity --info --title "Fehler" --text "Dies scheint keine ${MYTYPE}- oder ${MYCONVTYPE}-Datei zu sein! Bitte überprüfen.\n\nAusgabe $(file ${MYFILE})"
	exit 0
fi

# Edit metadata
EDIT_META="false"
zenity  --question --title "Metadata" \
--text "Do you like to edit a file containing the Youtube-Metadata?" \
&& EDIT_META="true"

if [ "${EDIT_META}" = "true" ]
then
	edit_metadata
else
	set_youtube_metadata
fi

# Check if a mkv already exists
MKV_EXISTS="false"
[ -f ${MYBASENAME}.part*.${MYCONVTYPE} ] && MKV_EXISTS="true"
[ -f ${MYBASENAME}.${MYTYPE} ] && MKV_EXISTS="true"

if [ "${MKV_EXISTS}" = "true" ]
then
# Converted video exists
	if zenity --question --title "Existierendes Video auf Youtube hochladen" \
		--text "Die Datei(en) ${MYBASENAME}.partX existiert(en) bereits.\nBitte umbenennen oder löschen\n\nOder sie können die Datei jetzt auf Youtube hochladen?\n\nMetadaten:\nTitel: ${TITLE}"
	then
		split_it
		upload_it
	else
		exit 0
	fi
else
# Converted video does not exist

if zenity --question --title "Video konvertieren und auf Youtube hochladen?" \
	--text "${MYBASENAME}.${MYTYPE} in ${MYCONVTYPE} umwandeln und auf Youtube hochladen?\n\nTitel: ${TITLE}"
then

	[ -f ${MYBASENAME}.meta ] || set_youtube_metadata

	split_it
	upload_it

fi

fi

Batch-convert videos with avidemux

Avidemux is a very handy tool. Sometimes you have a lot of files of the same type laying around and you like to apply all the same filters to them. I use it to convert the videos form my camera (mov) into a compatible format for e.g. Openshot (avi).

The solution is very simple. There is a tool called avidemux_cli (command line interface). It can use the project-files created with the Avidemux graphical user interface. Simply save your settings with Avidemux-GUI to a file with the ending ".proj" alongside with your videos and run the follwoing script.

Special version for a certain project

There are only some things to edit:

  • a folder name where to save the converted files
  • the name of the video filetype to be converted (here mp4)
  • the name of the output video, this MUST match the type given in avidemux
  • the exact name of the avidemuxproject-file

For the script to run you need to install avidemux-cli and avidemux:

sudo apt-get install avidemux-cli avidemux
#!/bin/bash
FOLDER="Converted"
IN_TYPE="mp4"
OUT_TYPE="avi"
PROJECT="convert_to_mjpeg.proj"

##########################################

mkdir -p $FOLDER

cat "${PROJECT}" | \
fgrep -v app.load  | \
fgrep -v app.clearSegments  | \
fgrep -v app.addSegment  | \
fgrep -v app.markerA  | \
fgrep -v app.markerB \
> "${PROJECT}.cli"

cat "${PROJECT}.cli"

BASE=""
for InputItem in *.${IN_TYPE}
do 
	#BASE="$(basename $InputItem .${IN_TYPE})"
	BASE="$(basename $InputItem)"
	avidemux2_cli --load  "$InputItem" --run "$PROJECT.cli" --save "${FOLDER}/${BASE}.${OUT_TYPE}" 
done

General purpose version

I also created a version for batch processing and general purpose:

#!/bin/bash

which avidemux2_cli > /dev/null || echo "Please install: sudo apt-get install avidemux-cli"
which avidemux2_cli > /dev/null || exit 1

[ "$4" ] || cat <<EOF

 USAGE: $(basename $0) 
		<OUTPUT_FOLDER_NAME> 
		<IN_TYPE OUT_TYPE> 
		<OUTPUT_FILETYPE> 
		<AVIDEMUX_PROJECT_FILE_NAME>

 e.g.

 $> $(basename $0) ConvertedFiles mp4 avi myavidemux.proj

EOF

[ "$1" ] || exit 1
[ "$2" ] || exit 1
[ "$3" ] || exit 1
[ "$4" ] || exit 1

FOLDER="$1"
IN_TYPE="$2"
OUT_TYPE="$3"
PROJECT="$4"
LOGFILE="conversion.log"

##########################################

mkdir -p $FOLDER

cat "${PROJECT}" | \
fgrep -v app.load  | \
fgrep -v app.clearSegments  | \
fgrep -v app.addSegment  | \
fgrep -v app.markerA  | \
fgrep -v app.markerB \
> "${PROJECT}.cli"

cat "${PROJECT}.cli"

BASE=""
ERROR="0"
for InputItem in *.${IN_TYPE}
do 
BASE="$(basename $InputItem .$IN_TYPE)"

cat <<EOF
#######################################################################
#######################################################################
## avidemux2_cli 
## --load  "$InputItem"
## --run "$PROJECT.cli" 
## --save "${FOLDER}/${BASE}.${OUT_TYPE}
##
EOF

avidemux2_cli --load  "$InputItem" --run "$PROJECT.cli" --save "${FOLDER}/${BASE}.${OUT_TYPE}" || ERROR="1"

cat <<EOF
#######################################################################

EOF

done

[ "$ERROR" = "1" ] && zenity --info --title "Conversion ended" --text "There have been ERRORS" 
[ "$ERROR" = "0" ] && zenity --info --title "Conversion ended" --text "OK"

Changelog

  • [Update] Changed converter from mencoder to ffmpeg due to audio sync problems - --Apos 01:49, 6 January 2012 (CET)
  • [Update] Major version update of script - --Apos 04:33, 6 January 2012 (CET)