Walkman X – Video encoding in Linux / Mac OS X

This was tested in a i386 Ubuntu Jaunty Jackalope 9.04 with ffmpeg svn rev. 19439. I do not have Mac OS X to confirm everything right now, this is based on the principle that OS X runs over a BSD kernel and libx264, ffmpeg are both supported in it with the same interface.

I WILL TRY AND WRITE A SCRIPT/PROGRAM FOR ALL OF THIS OK?

UPDATE: FOR AN EASIER SOLUTION I WILL POST handbrake AND avidemux PROFILES LATER

For a command line encoding let’s get started.

Context

The new Sony Walkman X series models {x1050,x1060,x1051,x1061,x1051-BI,x1061-BI, maybe more} do not include support for Mac OS X or Linux. Namely without Windows and WMP 11 one cannot encode video for it because WMV3, the codec officially used in this device for native resolution, only exists in Windows. Also, one could use one of the many tutorials to encode video for the ipod in 320×240 resolution. But despite what is written in the manual, you can encode video in the native resolution of 432×240 to enjoy this OLED beauty ;) . This device is begging for high quality video, yet officially even in Windows can be hard to get it to work… Also by using a CLI interface you can run this on a PS3 connected by ssh to your PC.

Setup

Requirements:

  1. libx264
  2. ffmpeg with x264 support

Ubuntu users will find a detailed guide to achieve this here. To check for ffmpeg with x264 support run the following in a shell:

ffmpeg -formats

Somewhere you should be getting the lines (not necessarily next to each other…):

E    mp4             MP4 format
EA    libfaac         libfaac AAC (Advanced Audio Codec)
EV    libx264         libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10

Assuming everything is working, run the following in a shell:

mkdir ~/.ffmpeg
nano ~/ffmpeg/libx264-walkmanx.ffpreset

nano is just an editor, use any text editor you like to create “~/.ffmpeg/libx264-walkmanx.ffpreset” (from your home account) and paste the following text to it and save it:

coder=0
flags=+loop
cmp=+chroma
partitions=+parti8x8+parti4x4+partp8x8+partb8x8
me_method=hex
subq=6
me_range=16
g=250
keyint_min=25
sc_threshold=40
i_qfactor=0.71
b_strategy=1
qcomp=0.6
qmin=10
qmax=51
qdiff=4
bf=0
refs=2
directpred=3
trellis=0
flags2=+bpyramid+fastpskip
level=13

Hit Ctrl+x, then type ‘y’ and ‘Enter’ to save it.

Now there are many ways to encode a video file. We select three.

Encoding

Method 1: 1-pass CRF

If you don’t care about filesize and just want a good quality and fast encoding, this is the way to go. Below, replace ${MOVIE} with the movie file you want to encode, for instance “~/Downloads/Star Wars XVIII – Revenge of the whatever.avi”(if it has spaces then include the quotes).

ffmpeg -i "${MOVIE}" -f mp4 -acodec libfaac -ab 192k -ac 2 \
-ar 48000 -vcodec libx264 -vpre walkmanx -crf 22 -s 432x240 \
 -threads 0 output.mp4

For better quality replace 22 with a lower value, no lower than 16. This obviously will result in a larger file. The opposite goes for a higher crf.

Method 2: 1-pass encoding – variable bit rate

If you do care about filesize but don’t have the time for a 2-pass, this is a good option. In this example we ask for a video bitrate of 768k but you can ask up to 1500k. More than that will probably be unreadable and it’s useless on a 3in screen.

ffmpeg -i "${MOVIE}" -f mp4 -acodec libfaac -ab 192k -ac 2 \
-ar 48000 -vcodec libx264 -vpre walkmanx -s 432x240 \
-b 768k -bt 768k -threads 0 output.mp4

Method 3: 2-pass encoding – variable bit rate

The best, yet slower method. Use only if you have very high quality sources.

ffmpeg -i "${MOVIE}" -f mp4 -an\
 -pass 1 -vcodec libx264 -vpre fastfirstpass -b 768k -bt 768k -bf 0\
 -s 432x240 -threads 0 output-2pass.mp4 && \
ffmpeg -i "${MOVIE}" -y -f mp4 -acodec libfaac -ab 192k -ac 2 -pass 2\
 -vcodec libx264 -vpre walkmanx -b 768k -bt 768k -s 432x240 \
-threads 0 output-2pass.mp4

EXTRAS:

Optimizations

You may be losing quality over the original file, or you may be occupying space unnecessarily by using a bitrate higher than the original. To see the original file quality do

ffmpeg -i "${MOVIE}"

Audio : these examples encode audio in 192k, you may want more (officially you can encode up to 288k per channel), or less to decrease filesize (I never use less then 96k). Same goes to the 48000 Hz frequency (which is the maximum, you can lower to 44100, 32000 and 22050). Check a decent guide here.

Video thumbnails

Here’s a script to capture a jpeg of the 4th second of MOVIE in a format that Walkman understands. Copy it next to your video and you will see a thumbnail in the player.

#!/bin/bash
 
BASENAME=${MOVIE%.*}
ffmpeg  -itsoffset -4  -i "${MOVIE}" -vcodec mjpeg -vframes 1 -an -f rawvideo -s 160x120 "${BASENAME}".jpg

Multiple files encoding

Say you have a whole directory ${DIR} of movie files (ending in .avi). The following script encodes all the avi files in the current current directory in CRF.

#!/bin/bash
 
ls -1 *.avi | while read FILE
do
	BASENAME=${FILE%.*}
	ffmpeg -i "${FILE}" -f mp4 -acodec libfaac -ab 192k -ac 2 \
	-ar 48000 -vcodec libx264 -vpre walkmanx -crf 22 -s 432x240 \
	 -threads 0 "${BASENAME}".mp4 </dev/null
done

For other methods just replace everything after “do” (leaving the variables ${FILE}, etc intact). I promise a decent script later lol.

TODO:

  1. Video optimizations. -sameq gives the original video quality
  2. Make Handbrake profile…
  3. Thumbnail should pick random instant of the movie
  4. Native spect ratio option: -aspect 1.8
  5. Create table in a wiki of combinations known to work!
  6. Subtitles support with Avisynth: http://avisynth.org/mediawiki/Main_Page
  7. Use PS3 optimizations: Link 1 Link 2
  8. Add GUI: Avidemux script see 1 and 2.
  9. Solve RMVB problem with ffmpeg, low framerate
  10. Add python script that has no interaction {checks ffmpeg support or includes ffmpeg, checks original quality and decides best, has cli option to overwrite, checks if dirs and files exist, chooses more appropriate encoding method without interaction, checks if flv file has mp3 or aac to encode audio or not, if original quality > device max quality then encode, else preserve quality with -sameq} and which supports multiple files. SEE THIS getparams and this which seems better supported and doesn’t depend on ffmpeg.

Thanks:

Links:


About this entry