video without SMC - first success + tutorial for linux and windows

I’d like to report my first successful video conversion without SMC:

  • using ffmpeg and mencoder (on Linux) to convert from MPEG-PS (MPEG1 Video, MPEG1-Layer2 Audio) to AVI

  • modifying the AVI file with avi-mux (under wine on Linux)

  • playing (and seeking) a 90 seconds movie on the Fuze :smileyvery-happy:

Please consider this as a first informal post only. I need to do more testing and it needs a bit of time to put things together until I get at least a half-decent recipe or howto.

Well, it was kind of puzzling. I’m not a video expert at all, in fact when I started my investigation about two weeks ago I didn’t know anything about AVI file structure, I-, P- or B-frames and alike. I am not keen on watching video or tv. I mostly consider this a waste of time … But I must confess I am a Linux addict and I love my fuze. And I know there are powerful tools for almost any video format conversion available on Linux. So I tried to find a solution for video conversion without SMC.

After reading some documentation and a lot of articles on the web I digged down deeper into some working videos. My first understanding was that it is necessary to separate two problems apart: the specifics of video stream format and the specifics of the avi container. Finally that was the clue other people probably have not considered hard enough!

Edit:    The tutorial is out! It provides solutions for both Linux and Windows. Please follow this link.

Message Edited by ewelot on 08-20-2009 03:01 PM

Message Edited by ewelot on 08-20-2009 03:06 PM

Message Edited by ewelot on 08-25-2009 10:11 PM

Message Edited by ewelot on 08-25-2009 10:13 PM

where’s the tutorial? :wink:

The procedure which I used is as follows:

  1. Convert video/audio to proper format:

In a Linux terminal running bash I define the following function

tofuze () {  
 size="224:176"  
 fps=20  
 vbit=683 # in kbit/s  
 abit=128 # in kbit/s  
  
 vopts="-vcodec libxvid -r $fps -b 1000k"  
 aopts="-acodec copy"  
 ffmpeg -i $1 $vopts $aopts -y temp.avi  
  
 vopts="-ofps $fps -vf scale=$size -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=$vbit"  
 aopts="-oac mp3lame -lameopts cbr:br=$abit"  
 pass1="keyint=15:turbo:vpass=1"  
 pass2="keyint=15:vpass=2"  
 mencoder $vopts:$pass1 $aopts temp.avi -o $2  
 mencoder $vopts:$pass2 $aopts temp.avi -o $2  
 rm temp.avi  
}

 and use it like in the following command:

tofuze invideo.mpg outvideo.avi

I’m pretty sure most Windows users can translate the code to proper command line calls … :wink:

Only a few notes on the conversion steps. I found that mencoder sometimes does odd things if it is asked to do video frame rate conversion. The resulting AVI files seem to contain some garbage which AVI-Mux cannot handle. Therefore I decided to let ffmpeg handle the frame rate conversion first. The following two-pass video conversion with mencoder is fairly standard.

I prefer mencoder over ffmpeg because it is packaged with all necessary codecs on debian-multimedia.org (I run Debian 5.0 Lenny) and it has more finegrained options for I-,P-,B-Frames I fiddled around during my tests.

On Ubuntu 9.04 I have succeeded without the initial ffmpeg step but the resulting video was quite choppy on the Fuze.

  1. Adjust AVI Container properties:

The main step is to remux the video to generate OpenDML indexes. Also I adjusted the audio interleaving between video frames. The most suitable free (GPL) software I found for these tasks is AVI-Mux. This site has a lot of useful documentation too. The software is for M$ Windows but runs fine under wine. You don’t need any codecs (as with Virtualdub) because you are not de- or encoding anything.

For the settings I disabled anything under Output/AVI file structure but:

  • use Open-DML output
  • standard indices per stream: auto
  • RIFF-AVI 800MB
  • audio interleave 2 frames
  • preload 0ms

Note that the Fuze does not handle extended AVI chunks, although that is the main purpose of the OpenDML specification. The audio interleave interval is copied from some working example videos for the Fuze. It is probably not the only working value but you should certainly not take values too large because the Fuze’s decoder would require larger buffers.

Hope that helps in a first step and some users can reproduce the outlined procedure. I did not go into technical details right now. Also I should have added some notes about other software I found very useful for analyzing my test data.

Anyway, good luck …

I have a few additions to the video conversion function beecause

  • you have to avoid null frames by using the harddup directive in the video filter

  • you might need to apply audio sample rate conversion

The function now is as follows:

tofuze () { size="224:176" fps=20 vbit=683 # in kbit/s abit=128 # in kbit/s keyint=15 vopts="-vcodec libxvid -r $fps -b 1000k" aopts="-acodec copy" ffmpeg -i $1 $vopts $aopts -y temp.avi vopts="-ofps $fps -vf scale=$size,harddup -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=$vbit" aopts="-srate 44100 -af resample=44100:0:1 -oac mp3lame -lameopts cbr:br=$abit" pass1="keyint=$keyint:turbo:vpass=1" pass2="keyint=$keyint:vpass=2" mencoder $vopts:$pass1 $aopts temp.avi -o $2 mencoder $vopts:$pass2 $aopts temp.avi -o $2 rm temp.avi }

@ewelot wrote:

The procedure which I used is as follows:

 

<snipped to save space>

 

I did not go into technical details right now.

Coulda fooled me! :smileyvery-happy:

@tapeworm wrote:


@ewelot wrote:

The procedure which I used is as follows:

 

<snipped to save space>

 

I did not go into technical details right now.


Coulda fooled me! :smileyvery-happy:

Come on, Sir! No C code, no FourCC’s, no hex dumps, no … :stuck_out_tongue: Look at some documentation like the OpenDML specification and you can imagine it could be much more technical …

:wink: 

@ewelot wrote:


@tapeworm wrote:


@ewelot wrote:

The procedure which I used is as follows:

 

<snipped to save space>

 

I did not go into technical details right now.


Coulda fooled me! :smileyvery-happy:


 

Come on, Sir! No C code, no FourCC’s, no hex dumps, no … :stuck_out_tongue: Look at some documentation like the OpenDML specification and you can imagine it could be much more technical …

:wink: 

Granted . . . it could have been much, much more technical but my head is still swimming after trying to wade through your postings. Maybe this 'ol country boy jest cain’t comp-ree-hend wat ‘yer sayin’.

Oh . . . An ‘ya doesn’t has to call me Sir. I werk fer a livin’!  :stuck_out_tongue:

Tapeworm, sorry for the headache. Maybe you should take a little rest, it’s weekend now and a beautiful summer night. Don’t bother with my posts for a while and enjoy listening to your music on the Fuze …

By the way the “Sir” is according to the reputation in this forum. To bad you have to waste some time by working on something else … :cry: … for money ?!

Some news and a call for help.

I have now succesfully created a couple of videos for the Fuze from different sources with the procedure outlined before. I apologize for testing this on Linux first - I don’t have a M$ Windows PC at hand. The longest video so far is of almost 20 minutes duration. Playback, pause and continue works fine - without A/V sync issues ever.

BUT seeking to above 3-4 minutes freezes the screen and I have to reset the device :cry:. I’m pretty sure it has something to do with the subtle differences in OpenDML indexes between my original Fuze’s test videos and the ones I created my way (well, the AVI-Mux software did it in fact). Unfortunately the working test videos are of about 10 second length only and therefore do not allow to dig into the structure of big index arrays.

Therefore I kindly ask other users who are using the Sansa Media Converter software to create their videos for the Fuze to provide a good working example video of about 6-10 minutes for download which I could check and analyze. This would be really great. Thanks in advance !!!

will do…

 edit:

I don’t think i’m gonna be able to upload a converted video tonight… busy + tired.

 edit:

http://rapidshare.com/files/266019629/fuze\_converted\_videos.zip.html

here you go.

i noticed that after conversion, the SMC adds a .thm file together with the video.  i dunnoe what’s that for…

Message Edited by marqck on 08-11-2009 09:49 AM

marqck,

thanks a lot for your videos!!!

The .thm files are just normal 224x176 JPEG images. They are used as video thumbnail images by the Fuze, but they are not mandatory.

Great news: The seeking problem (to above 3-4 minutes) is solved!

Thanks to the SMC videos provided by marqck I found the OpenDML Standard Index has to be split every 4000 frames - which is 3:20 minutes. This can easily be done by changing the settings in AVI-Mux.

The current settings under Output/AVI file structure are:

  • use Open-DML output

  • standard indices per stream: 1 per 4000 frames

  • RIFF-AVI 800MB

  • audio interleave 2 frames

  • preload 0ms

The next step would be to tighten up the video conversion procedure. Instead of looooong command lines I probably should focus on the Fuze’s video requirements. Users should than try to achieve these with their favoured video conversion programs.

I got today a 4Gb fuze v2 (with latest firmware!  that’s something that never happened to me, with anything), and I’ve tried to put a somple video from youtube in the fuze following your instructions… and it works like a charm!

I’m not a video expert, (in fact, i know near nothing about media codecs, containers and all those things), but if the avimux step could be done via commandline, I could write a little (crossplatform) pyqt GUI for putting videos on the fuze (and eventually it could do more things)

Now I’m a happier new sansa fuse owner :slight_smile: thank you

I’ve just translated tofuze() into python (now windows user would be able to use it, provided they have ffmpeg and mencoder in their path)

Here’s thepython version of tofuze():

#!/usr/bin/env python # -\*- coding: utf-8 -\*- import sys, os from subprocess import call sys.argv if sys.argv[1:] == [] : print """Usage: python video4fuze.pyw INPUTVIDEO.avi""" exit(1) size = "224:176" fps = "20" vbit = "683" # in kbit/s abit = "128" # in kbit/s keyint = "15" tempavi = "temp.avi" pass1 = "keyint=" + keyint + ":turbo:vpass=1" pass2 = "keyint=" + keyint + ":vpass=2" for argument in sys.argv[1:]: call(["ffmpeg","-i",argument,"-vcodec","libxvid","-r",fps,"-b","1000k","-acodec","copy","-y",tempavi]) call(["mencoder","-ofps",fps,"-vf","scale=" + size + ",harddup","-ovc","lavc","-lavcopts","vcodec=mpeg4:vbitrate=" + vbit + ":" + pass1,"-srate","44100","-af","resample=44100:0:1","-oac","mp3lame","-lameopts","cbr:br=" + abit,tempavi,"-o",argument + "remuxed.avi"]) call(["mencoder","-ofps",fps,"-vf","scale=" + size + ",harddup","-ovc","lavc","-lavcopts","vcodec=mpeg4:vbitrate=" + vbit + ":" + pass2,"-srate","44100","-af","resample=44100:0:1","-oac","mp3lame","-lameopts","cbr:br=" + abit,tempavi,"-o",argument + "remuxed.avi"]) os.remove("temp.avi")

 Support for avimux within the script, so we can have apparent 1-step conversion is coming, as well as a GUI :wink:

There seems to be a issue converting videos this way:

All the videos i’ve converted with the bash script or it’s python version (no matter which)  seem to lose the last 3-4 seconds of the video. With videoclips it can be a bit annoying…  It seems it is mencoder who drops those last (but not least ) seconds of video, because the temp.avi created by ffmpeg still has them. Any ideas?

BTW, now my script suports batch conversion of any amount of files you pass ti it, and converts them directly to fuze format without any more interaction, and has been tested ond linux and windows, so it should work on any platform with wine support (that includes intel macosx, and the rest of *nix.

I’ll investigate the last seconds issue…

Some news about the video conversion part.

I tried very hard on getting ffmpeg to do all of the conversion because two conversions in a row would always degrade video quality a bit (and take more time). I even managed to install a newer version on my Debian Lenny system (version 0.5+svn20090609) using additional patches to overcome some libmp3lame runtime errors. But to no avail.

Thereafter I focused on mencoder. There are some conversion tasks which are handled much simpler in mencoder than in ffmpeg, e.g.scaling from other aspect ratios. And finally I succeded in using mencoder exclusively! I still have some rare cases which do not work well and need additional tweaks.

Here is the new conversion function:

tofuze () { w=224 # width in pixel h=176 # height in pixel fps=20 # video frames per second keyint=15 # video keyframe interval vbit=683 # video bit rate in kbps abit=128 # audio bit rate in kbps srate=44100 # audio sample rate in Hz rm -f divx2pass.log  
 vopts="-ofps $fps -vf pp=li,expand=:::::$w/$h,scale=$w:$h,harddup \  
 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=$vbit:vmax\_b\_frames=0"  
 aopts="-srate $srate -af resample=$srate:0:1,format=s16le -oac mp3lame -lameopts cbr:br=$abit"  
 pass1="keyint=$keyint:turbo:vpass=1"  
 pass2="keyint=$keyint:vpass=2"  
 mencoder $TOFUZEOPTS -ffourcc DX50 $vopts:$pass1 $aopts "$1" -o "$2"  
 mencoder $TOFUZEOPTS -ffourcc DX50 $vopts:$pass2 $aopts "$1" -o "$2"  
}

I changed a few things of minor importance:

  • added “pp=li” to deal with interlaced video sources

  • added “expand=:::::$w/$h” to deal with video sources of different aspect ratio

  • added “-fourcc DX50” to please some other video playback devices (not necessary for the Fuze)

  • added variable “$TOFUZEOPTS” which allows to pass additional options from the command line into the function, e.g. to only transcode the first three minutes of the second chapter of a DVD I would run the following:

    TOFUZEOPTS=“-chapter 2 -endpos 00:03:00” tofuze “dvd://1” test.avi

Still the tofuze function is mainly useful for linux users. It is just a wrapper around two calls to the mencoder program. Here is an explicite example which can be run by Windows users:

    mencoder -ffourcc DX50 -ofps 20 -vf pp=li,expand=:::::224/176,scale=224:176,harddup -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=683:vmax_b_frames=0:keyint=15:turbo:vpass=1 -srate 44100 -af resample=44100:0:1,format=s16le -oac mp3lame -lameopts cbr:br=128 invideo.mpg -o outvideo.avi

    mencoder -ffourcc DX50 -ofps 20 -vf pp=li,expand=:::::224/176,scale=224:176,harddup -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=683:vmax_b_frames=0:keyint=15:vpass=2 -srate 44100 -af resample=44100:0:1,format=s16le -oac mp3lame -lameopts cbr:br=128 invideo.mpg -o outvideo.avi

Please note, this is still work in progress and not a foolproof tutorial.

@ssorgatem,

thanks for jumping in and trying out my preliminary procedure.

Your 3-4 seconds loss of video is strange. I checked a few cases from short clips to full DVD movie rips and never have lost more then a few frames (<0.2 seconds).

Well, I solved the last seconds issue just skipping the ffmpeg step, just the mencoder part, and it works nice! (Yep, very strange, I only lost those seconds if I used mencoder on ffmpeg’s output). I haven’t had problems so far with those settings, I’ve tested many videos in different source formats (flv, ogv, mp4, wma) and they have worked.

I’ve just finished the first version of a more or less stable GUI for all the process, check it out at: Google Code Archive - Long-term storage for Google Code Project Hosting.

It should work on OSX and windows too (It does under wine, at least).

It’s using the 2 pass mencoder way, but i’ll update its commandline to mencoder if your new settings prove to be better! :wink:

I just tried the “windows” version of the mencoder only, two pass conversion. My Sansa fuze still reports “unsupported format”.

During poth passes I recieved the following …

“ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.”

Message Edited by RascalRobot on 08-18-2009 12:25 PM

Have you passed the video through avimux GUI?

RascalRobot,

the video conversion using mencoder is only half of the procedure. You must run AVI-Mux GUI with these settings afterwards to add the required OpenDML indexes. You can savely skip the “ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.” message. The vprp header is not required and never created by the official SMC software.