23 July, 2011

Synology DNLA transcoding alternative

I am a happy owner of a Synology NAS (a DS411j). The DS offers DNLA support, so I could theoretically just plug my TV into the ethernet, and watch all my accumulated movies and anime easily. Sadly, the TV is too cheap to have any decent codec support. Usually, one would install Serviio or another DNLA server onto the DS, as described here.

But annoyingly, the DS411 only sports a tiny ARM CPU which cannot keep up with transcoding difficult codecs (h.264 to mpeg2). The solution? Do all the transcoding over night, and not while you are watching it. This solves the issue of lack of processing power, and results in a neat directory full of files that actually work. The obvious tradeoff being hard drive space, but then a DS411j has four disk slots and hard drives are dirt cheap.

Follow the directions over there to bootstrap the NAS, install ipkg, wget, ffmpeg and yasm. Also execute these two lines if you get an error message about libraries not found when you try to start ffmpeg:

cp /opt/lib/libbz2.so.1.0 /lib
cp /opt/lib/libz.so.1 /lib

After that, use a script such as this

#! /bin/sh
SOURCE_DIR="/volume1/input"
TARGET_DIR="/volume1/video/transcode"
for a in "$SOURCE_DIR"/*.mp4 "$SOURCE_DIR"/*.avi "$SOURCE_DIR"/*.mkv
do
 if [ -f "$a" ];
 NEW_NAME=$(basename "$a")
 COMPLETE_NAME="$TARGET_DIR"/"$NEW_NAME".avi
 echo $COMPLETE_NAME
 then  
  if [ -e "$COMPLETE_NAME" ]
  then
   echo "Already converted: $a"
  else
   echo "Converting: $a"
   ffmpeg -i "$a" -y -vcodec copy -vbsf h264_mp4toannexb -copyts -acodec ac3 -ab 128k -ac 2 -map 0:0 -map 0:1 -sn -f mpegts "$COMPLETE_NAME"
  fi
 fi
done

to automate the conversion. It will check whether a file was already converted, and if not, automatically start to do so. Note that the parameters for ffmpeg work for my Panasonic Viera, you might have to use a different set of codecs. You can check the Serviio forums for a good selection of transcoding profiles, and then trial and error your way to success.

You can then set up a cron job (more on that later) and make your script run automatically every few hours. If there is nothing to convert, it will immediately terminate.

Open issues:

  • If anyone with more .sh-knowledge than me could improve upon this and add recursive folders and some such, I'd very much appreciate it.
  • I also cannot get my Synology to find these newly created files very quickly, it takes a long time until the DNLA service finally displays them. Is there a quick way to add them to the index?
  • I cannot get .wmv videos to convert, ffmpeg seems to fail to read them. It might be my selection of them, or a general issue, I don't know yet.

10 comments:

  1. dude, thx! i will make it work for ARMv5 (DS111) and Sony 32w5500!

    btw, here is a script for you to add new files to the syno index:

    http://www.naschenweng.info/2010/02/13/synology-automatic-indexing-via-synoindex

    ReplyDelete
  2. i forgot to mention / ask : why didnt you do this using Mencoder/mplayer ? this way you could even add an option to hard (its called mux right?) code subtitles into the video!

    Thats too much for me and my limitid knowledge of .sh and both ffmpeg and Mplayer :(

    ReplyDelete
  3. I used ffmpeg because I already had it compiled and I knew the parameters to get it working on my Panasonic, because I had played around with Serviio before. It was a matter of convenience, really.

    Thanks for the lin, that is what I was searching for. I'll try to get it running tomorrow, and I will post more details on how to get cron working (that was quite the headache).

    ReplyDelete
  4. hi me again, unable to login with google:

    okay, well, you might want to try this command to iterate through the folders with movies (basically, its a find command with execute...)

    find /volume1/video/originals -name *.avi -o -name *.mkv -type f -exec /volume1/scripts/yourtransformscript.sh {} \;

    i havent been able to make this work, but this finds all *.avi or *.mkv executes something after it.. so if you implement this in your script, you will be able to execute ffmpeg for every found *.avi in your folders

    question for you: where did you find the right commands for FFMPEG? i want it to convert to MPEG2 (sony bravia) and i dont know where to start to find the optimal parameters...!

    ReplyDelete
  5. I did play around with serviio (on my computer), which uses ffmpeg internally. That way, I can just test any format by transcoding into it. I have to mention that I am currently looking for a better way to run ffmpeg with more than one set of parameters. Some of my files can be easily and quickly completed (-vcodec copy will copy the video stream), others need a full re-encode (-vcodec mpeg4). The second variant takes ages (about five times as long as it would take watching).

    Also required: -acodec ac3 (Audio codec AAC3 works on Panasonic), -ac 2 (only two channels), -ab 128k (bit rate), -f mpegts (format mpeg-file, again, Panasonic requirement)

    ReplyDelete
  6. okay, for those who are looking for it: here is the ffmpeg command with parameters to convert (at least) xvid to mpeg2 compatible with Sony bravia:


    ffmpeg -i "$input" -vcodec mpeg2video -f mpegts -target pal-dvd -aspect 16:9 "$output"

    -ps 200000 didnt do anything for me, so i removed it.

    Could you post your updated script when you finish it?

    ReplyDelete
  7. good news! i've managed to get things working (including subfolders) it needs two scripts though. 1 scripts that scans and passes his findings to another script.

    file one:
    find /volume1/video/originals -type f \( -name "*.avi" -o -name "*.mkv" -o -name "*.vob" \) -exec sh /volume1/scripts/ffmpeg.sh "{}" \;

    file two:
    TARGET_DIR="/volume1/video/transcoded"
    filename=$(basename "$1")
    echo $filename
    NEW_NAME="$TARGET_DIR"/"$filename".mpeg
    ffmpeg -i "$1" -vcodec mpeg2video -f mpegts -target pal-dvd -aspect 16:9 "$NEW_NAME"

    notice i added the .mpeg because my TV needs it.
    Now to find an option to skip when already exists parameter for ffmpeg and done!

    ReplyDelete
  8. if [ -e "$file" ] then ... else ...

    Will check for existing files. Thanks for the recursion.

    ReplyDelete
  9. not a problem, im starting to like my setup this way :D

    Btw, i found that the check for existing files is optional, unless stated with option '-y' ffmpeg will skip existing files.

    ReplyDelete
  10. Addendum: While this worked some of the time, it was cumbersome to use, and often failed, because ffmpeg needed different parameters for quite a few files. I have bought a WD Live (which I would not recommend), and that works better, though still not perfectly.

    ReplyDelete