Repository 32bit  Forum
Repository 64bit  Wiki

ToZenAviMencoder (en): differenze tra le versioni

Da Slacky.eu.
(Introduction)
(Introduction)
Riga 14: Riga 14:
Due to this problem with ffmpeg, I used mplayer/mencoder.
Due to this problem with ffmpeg, I used mplayer/mencoder.
'''Note''': during my last experiments with gnomad2, I verified that the movie length doesn't get transfered along with the movie on the Zen, making it impossible to pause a video and resume playing it back at a later time from the same position it was at. Instead, the movie length is correcly transfered along with the movie if you use the Windows software which comes alongside with the Zen.
+
'''Note''': during my last experiments with gnomad2, I verified that the movie length doesn't get transfered along with the movie on the Zen, making it impossible to pause a video and resume playing it back at a later time from the same position it was at. Instead, the movie length is correctly transfered along with the movie if you use the Windows software which comes alongside with the Zen.
= Description =
= Description =

Versione delle 20:30, 2 ott 2008


Indice

Introduction

As a shiny new Creative Zen knocked to the door of my house, I immediately began searching for the right settings in order to convert videos from any format they were to a Zen-able format.

The Zen has the ability to play XVID and Windows Media Video (WMV) movies, with little restrictions.

For details, see this sheet published by Creative itself.

At first I made some conversion experiments using ffmpeg (I like it more than mencoder), but all the movies it converted had the problem of skipping the last 6/7 seconds of the video, as they were played on the Zen. After some searching, what I came to is that this is due to ffmpeg producing always VBR videos (variable bitrate), instead of CBR (constant bitrate) ones, which the Zen requires. If someone knows a way to make ffmpeg produce CBR movies (it seems to not work setting minrate and maxrate to the same value), please post here how to do it.

Due to this problem with ffmpeg, I used mplayer/mencoder.

Note: during my last experiments with gnomad2, I verified that the movie length doesn't get transfered along with the movie on the Zen, making it impossible to pause a video and resume playing it back at a later time from the same position it was at. Instead, the movie length is correctly transfered along with the movie if you use the Windows software which comes alongside with the Zen.

Description

This script is able to convert one or more movies from any video format to a Zen-compatible AVI format, but is not restricted to only that. If you modify it, you can adjust it to your own transcoding needs. For example, you can adjust it so it can re-encode a bunch of movies so that you can play them on your DVD-Divx player attached to the TV etc.

The encoding process is made in 2 pass.

You can use this script alongside my other script to display the progress of the encoding process. You can find it here.

Current version

Current version is 1.02, released on 02/10/2008 (date is in dd/mm/yyyy format).

Dependencies

GNU Bash 
In order to execute the script.
Mplayer/mencoder 
Used to encode. It must be compiled against the lame library, in order to encode audio tracks in mp3 format.
awk, grep and other programs 
They're used to gather/elaborate information. An initial check inside the script looks for them and, if one's missing, it alerts you.

Configuration

Inside an appropriate section (Editable Section) of the script there are some parameters, which are already set to the right values to produce Zen playable movies. In case you need this script to encode movies which are not to play on the Zen, you probably just need to adjust only these parameters.

RESOLUTION 
The desired resolution. The display of the Zen has a 320x240 pixel resolution. To the conversion extents, only the X resolution will be used, because the Y resolution will be automatically determined by mencoder, in order to preserve the aspect ratio of the original movie.
EXTENSION 
Contains the extension of the file to be produced. It's set to "avi" by default.
ARATE 
Contains the audio bitrate in thousands of bits per second (kb/s). Only in case the movie needs a great audio quality (live performance, musical video), it should be set to 128 (kb/s). Otherwise, you can set it to 64 or 32.
OUTDIR 
Points to the folder in which the converted movies will be put. If you don't declare it as an enviroment variable before you fire up the script, it will be set to "~/ZenOut", where ~ means the user's home folder. If this folder doesn't exist yet, it will be created.
MAXFRAMERATE 
Contains the maximum framerate which the destination target supports, in frames per second (fps). The Zen supports movies with a framerate up to 30 fps. If the source content has a greater framerate, it will be set to the value contained inside this variable during the encoding process.
FOURCC 
Contains the FOURCC to force in the converted movie header. The Zen requires the FOURCC to be XVID, but most Divx players requires it to be DIVX, DX40, DX50 etc. For a list of the available FOURCCs, see here.
VCODEC 
The video codec to use. By default it is set to mpeg4, in order to use the libavcodec library and its options. If you change it to "xvid" or something else, you'll have to adjust the encoding parameters used below by the script.
BITRATE 
The video bitrate to use, in bit per second (b/s). The Zen supports videos with a bitrate up to 1 Mb/s.
LOGFILE 
Points to the log file which will contain error messages (if any) and other info.
PROGRESS_SCRIPT 
Contains the name of the script to use to display the progress of the conversion. If it's set and it's contained inside the PATH, it will be used. Otherwise mencoder's output will be shown with no filter on standar output. If you want to use my script, go here.

Script

#!/bin/bash
#
# Script to convert one or more movies to a Zen-able format, but others too ;).
# Made for you by 414N <414N atATat slacky dotDOTdot it>
# 02/10/2008
# Version 1.02

# ~~~~~~~~~~~~~~~~~~~~~~~Editable Section~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# The display resolution.
# Only the X resolution will be used, as mencoder automatically sets
# the Y resolution to mantain the aspect ratio of the original movie.

RESOLUTION="320x240"

# The file extension

EXTENSION="avi"

# The audio bitrate (in kb/s)

ARATE="128"

# The output directory. It will be created if it doesn't exist

OUTDIR=${OUTDIR:-~/ZenOut}

if ! [ -d "$OUTDIR" ]
then
	echo "Creating folder $OUTDIR ."
	mkdir -p "$OUTDIR"
fi

# The maxim framerate allowed.

MAXFRAMERATE="30"

# The FOURCC to force.

FOURCC="XVID"

# The video codec to use.

VCODEC="mpeg4"

# The video bitrate (in b/s).

BITRATE="800000"

# Log file.

LOGFILE=/tmp/mencoder-conversion.log

# The script used to show the conversion progress.
# In order to NOT use it, set it to blank ("") or launch this script
# setting SHOW_PROGRESS=0

PROGRESS_SCRIPT="mencoderprogress.sh"

#~~~~~~~~~~~~~~~~~~~~~~~Editable Section End~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#~~~~~~~~~~~~~~~~~~~~~~~~~Functions Block Start~~~~~~~~~~~~~~~~~~~~~~~~~~


# Function delete_leftovers
# Deletes the intermediate files of the conversion process
# Parameters: N/A

function delete_leftovers ()
{
	if [ -e divx2pass.log ]
	then 
		rm divx2pass.log
	fi
	return 0
}

# Function print
# Prints a message to video, either using dialog or echo.
# Parameters:
# $1 : message to print

function print ()
{
	if [ "$USE_DIALOG" = 0 ]
	then
		echo "$1"
	else
		dialog --msgbox "$1" 10 50
	fi
}

# Function to abort the conversion process.
# Parameters:
# $1 : message to show, if any.

function abort ()
{
	delete_leftovers
	if [ "$FILENAME" ]
	then
		rm "$OUTDIR/$FILENAME.$EXTENSION" 2>/dev/null
		print "Conversion Aborted\n$1\nHit Ok to exit."
	fi
	exit 1
}

#~~~~~~~~~~~~~~~~~~~~~~~~~End of Funcion Block~~~~~~~~~~~~~~~~~~~~~~~~~~~~



#~~~~~~~~~~~~~~~~~~~~~~~~~~~Script Start~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



#~~~~~~~~~~~~~~~~~~~~~~~~~Checks Block Start~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# Flag used to determine if dialog is to be used or not

if [ -z `which dialog 2>/dev/null` ]
then
	USE_DIALOG=0
else
	USE_DIALOG=${USE_DIALOG:-1}
fi

# Flag used to determine if a progress script is to be used or not

if [ -z `which "$PROGRESS_SCRIPT" 2>/dev/null` ]
then
	SHOW_PROGRESS=0
else
	SHOW_PROGRESS=${SHOW_PROGRESS:-1}
fi


# Check if the required programs are inside the PATH

PROGRAMS="mplayer mencoder awk file grep egrep rev cut basename rm mkdir"
for PROGRAM in $PROGRAMS
do
	if [ -z "`which "$PROGRAM" 2>/dev/null`" ]
	then
		print "Could not find $PROGRAM in your path."
		exit 1
	fi
done

# Check if we have write access to the log file and, if so, we
# initialize it.


if [ -w "$LOGFILE" -o ! -e "$LOGFILE" ]
then
	echo -e "`date` \
	\n Job started on files: \n$@" > "$LOGFILE"
else
	print "You don't have write permission on $LOGFILE"
	exit 1
fi

# Script arguments check.

if [ $# -eq 0 ]
then
	print "You must specify at least one file."
	exit 1
fi

# Check if all the files specified on the command line exist and if they're
# movies.

MOVIES=""

for I in "$@"
do
	if [ -f "$I" ]
	then
		if [ -z "`file -L "$I" | egrep -i '(video|movie|asf|matroska|mp4)'`" ]
		then
			echo "$I is not a movie file. It will not be processed." >> "$LOGFILE"
		else
			MOVIES+="$I"$'\t'
		fi
	fi
done

if [ "$MOVIES" = "" ]
then
	print "No movies to convert."
	exit 0
fi



#~~~~~~~~~~~~~~~~~~~~~~~~~~~End of Checks Block~~~~~~~~~~~~~~~~~~~~~~~~~

# Capture of the CTRL+C signal

trap abort INT

# Resolution components split.

RESX=`echo "$RESOLUTION" | cut -dx -f1`
RESY=`echo "$RESOLUTION" | cut -dx -f2`

( echo "$MOVIES" | while read -d $'\t' MOVIE
do

# Extraction of the filename (with no extension and absolute path)


	FILENAME=`basename "$MOVIE" | rev | cut -d. -f2- | rev`
	
# Here we read movie information, such as resolution, length and framerate.

	INFO=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$MOVIE"`
	ORESX=`echo "$INFO" | grep VIDEO_WIDTH | cut -d'=' -f2`
	ORESY=`echo "$INFO" | grep VIDEO_HEIGHT | cut -d'=' -f2`
	LENGTH=`echo "$INFO" | grep LENGTH | cut -d'=' -f2`
	FRAMERATE=`echo "$INFO" | grep VIDEO_FPS | cut -d'=' -f2`
	

# Framerate check (must be <= MAXFRAMERATE)

	if [ `echo "$FRAMERATE" | awk '{printf "%.0f", $1}'` -gt "$MAXFRAMERATE" ]
	then
		FRAMERATE="$MAXFRAMERATE"
	fi

# Here we log information about this movies

	echo -e "Converting $MOVIE to $OUTDIR/$FILENAME.$EXTENSION \
	\nOriginal resolution = $ORESX x $ORESY \
	\nTarget maximum resolution = $RESX x $RESY \
	\nFramerate = $FRAMERATE fps \
	\nMovie length = $LENGTH s\
	\n========================================================"  >> "$LOGFILE"
	
# Parameters used for the first pass

FIRST_PASS_PARAMS="-vf scale=$RESX:-10 \
	  	  -ovc lavc \
	  	  -lavcopts vcodec=$VCODEC:vhq:v4mv:trell:mbd=2:turbo=1:dc=10:vbitrate=$BITRATE:vpass=1 \
	  	  -nosound \
	  	  -ofps $FRAMERATE \
	  	  -o /dev/null"
# Parameters used for the second pass

SECOND_PASS_PARAMS="-vf scale=$RESX:-10 \
	  	  -ovc lavc \
	  	  -lavcopts vcodec=$VCODEC:vhq:v4mv:trell:mbd=2:dc=10:vbitrate=$BITRATE:vpass=2 \
	  	  -oac mp3lame \
	  	  -lameopts cbr:mode=2:br=$ARATE -af resample=44100 -srate 44100 \
	  	  -ffourcc $FOURCC \
	  	  -ofps $FRAMERATE"
	
	
# First pass

	if [ "$SHOW_PROGRESS" -eq 1 ]
	then

		mencoder "$MOVIE" $FIRST_PASS_PARAMS 2>>"$LOGFILE" | "$PROGRESS_SCRIPT" "$LENGTH" "First pass on $MOVIE"
	else
		mencoder "$MOVIE" $FIRST_PASS_PARAMS 2>>"$LOGFILE"
	fi

	if [ $? -ne 0 ]
	then
		abort "First pass failed.\nLog file saved to $LOGFILE ."
	else
		echo "Fist pass successfully completed" >> "$LOGFILE"
	fi	
	
# Second pass

	if [ "$SHOW_PROGRESS" -eq 1 ]
	then
	
		mencoder "$MOVIE" $SECOND_PASS_PARAMS -o "$OUTDIR/$FILENAME.$EXTENSION" 2>>"$LOGFILE" | "$PROGRESS_SCRIPT" "$LENGTH" "Second pass on $MOVIE" 
	else
		mencoder "$MOVIE" $SECOND_PASS_PARAMS -o "$OUTDIR/$FILENAME.$EXTENSION" 2>>"$LOGFILE"
	fi
	

	if [ $? -ne 0 ]
	then
		abort "Second pass failed.\nLog file saved to $LOGFILE ."
	else
		echo "Movie converted successfully\
		\n========================================================" >> "$LOGFILE"
	fi	
done )

if [ $? -eq 0 ]
then
	print "All files converted successfully."
else
	abort "Conversion failed.\nLog saved to $LOGFILE"
fi

exit 0

Installation

You just need to put the script inside a path contained in the PATH enviroment variable, and grant it execution permission. I suggest to create a folder (bin, for example) inside your home folder and put it in your PATH, editing/creating the ~/.bashrc and ~/.bash_profile files with the following

export PATH+=":~/bin"

Changelog

1.00 
initial version of the script.
1.01 
fixed a little error regarding the progress script.
1.02 
fixed a little error which prevented files with spaces (' ') inside their name to be correctly saved;
fixed some strings inside the log file.

Feedback

If you've got something to say/report, please do it here. It's an italian Slackware forum.

414n

Strumenti personali
Namespace

Varianti