Zenphoto Setup

Charles Roth, 17 July 2016       (Techblog top)

I. Introduction
For many years, I hosted our family photos on one of my Linux servers using Gallery, an open-source PHP package.

But Gallery finally ran out of steam, and "shuttered" (heh, heh) in 2014.  I was never completely satisified with it, anyway, in particular videos were always troublesome.

So I had a little time this summer, and did some digging around, trying to find equivalent tools that were

  1. Open-Source
  2. Clearly indicated support for videos
  3. Still being actively maintained
In particular, I took a look at these sites:
  1. lychee.electerious.com
  2. piwigo.org
  3. zenphoto.org
  4. www.tinywebgallery.com/en/main.php
  5. www.phtagr.org
  6. coppermine-gallery.net
  7. www.photoshow-gallery.com
  8. en.wikipedia.org/wiki/Comparison_of_photo_gallery_software (A general comparison of packages)
TWG (Tiny Web Gallery), Zenphoto, and PhTagr seemed to have the best support for video, so I installed all of them and fooled around a bit.  But I found TWG hard to work with, and PhTagr has this oh-I'm-so-modern approach where there is no such thing as separate albums, only a huge pile of tags and filters, so I focused on Zenphoto...

...which ends up looking and working a lot like Gallery, but with two key advantages:

II. Installing Zenphoto
Not surprising, there were a number of tweaks and 'gotchas' involved in installing and configuring Zenphoto.  (That's why I bother to write this stuff down!)

  1. Basic install: see www.zenphoto.org/news/installation-and-upgrading.
  2. Create MySQL database.  (You may have to 'yum install php-mysql.x86_64' first!)
  3. Initial config.  Copy zp-core/zenphoto_cfg.txt to zp-data/zenphoto.cfg.php, and edit it according to the comments.  Reload the current page.  (I dimly recall having to change permissions manually... a lot... before I got this right.)

    Important!: Specify a prefix (I used "z_")!  The first time, I left it with the default value ("."), which completely freaking hosed my MySQL database replication to my backup server!  (MySQL hates table names that begin with ".".)

  4. Permissions.  Lots of changing permissions of various directories.  Follow the warnings in pink and just keep reloading the page.  Hit "GO" when they're all resolved.
  5. Create Admin.  Create admin id and password.
  6. Enable plugins.  Zenphoto has a ton of internal plugins and options, and some external (third-party) plugins as well.  I immediately enabled several of them:
    1. Admin / plugins / Users / user_login-out
    2. Admin / plugins / All / class-video
    3. Admin / plugins / All / jplayer
    4. Admin / options / theme / thumb size / 200
    5. Admin / plugins / all / jplayer / gear-icon / player-size jp-video-360p
    6. Admin / options / Image / enable Imagick.  (I found that I needed the ImageMagick PHP extension imagick, otherwise some of my images would not generate thumbnails, and I saw the dreaded "red crack" instead.  See, for example, www.scalescale.com/tips/nginx/install-imagemagick-php-imagick-centos.)
  7. Install Flowplayer5.  This external plugin was key to getting good video display.  Basically, just download from www.zenphoto.org/news/flowplayer5 and drop the result into the "plugins" directory.
  8. Security.  I don't like the way that so many PHP packages handle making installation "easy" by creating a bunch of directores with 777 permissions.  There are better ways, but I understand that the average person using PHP doesn't have much choice.

    In any case, change the setup directory, and setup.php, to 700 when you're done.  (I'm probably missing a few others, but in this case it's entirely my server, so I'm not too worried about other users monkeying around!)

III. Hacking Zenphoto
There were a few things about the Zenphoto "themes" (UI styles) that I hated.  In particular, I'm astonished that none of them show photo titles with the thumbnails -- this seems completely daft.

The PHP pages are relatively obtuse, but enough other users complained that I was able to get enough clues to make the changes I needed.

  1. Add titles to thumbnails.  Edit themes/basic/album.php, look for the
       while (next_image())
    and right before the close-div for imagethumb, add
       <div style="text-align: center;"><?php printImageTitle() ?></div>
  2. Allow 4 thumbnails per row.  There's an options setting for this, but the CSS still insists on having its way.  So I changed themes/basic/styles/light.css (the default) so that #images has "width: 1000px", and #main has "width: 900px".  YMMV, but I found this gave me optimal display of 4 thumbnails per row, 200 px per thumbnail, on a typical laptop screen.
  3. Table-ize.  After living with the previous setup for a while, I hacked album.php to use tables instead of divs, so that I could force the alignment better -- in particular so that I could use "word-wrap: break-word" to force word-wrapping of long image names.  Contact me (see bottom) for details if interested.

IV. MP4 Encoding, and ffmpeg follies
The real fun-and-games in getting Zenphoto to work had nothing to do with Zenphoto per se, and everything to do with video encoding.  Which is a wilderness of bizarre incantations, with the software equivalent of lightning sand and Rodents Of Unusual Size.

In the end, I found it easiest to just convert all of my existing videos to mp4 with H.264 encoding.  (Don't be fooled: not all mp4's are created equal.  Mp4 is a sort of 'container' format that can have different kinds of encoding inside.)

Most Linux distributions have a handy tool called ffmpeg that does a wide variety of translations to and from different formats and encodings.  Unfortunately, for your typical bizarre proprietary-software reasons, the default ffmpeg does not include H.264 encoding (as of this writing).

So, like the joke about Linux Airlines (where each passenger shows up on the tarmac with a different part of the airplane), I had to download and build ffmpeg from source. 

Figuring out which pieces fit together how was challenging, but in the end, the resulting steps were relatively straightforward.  (Most of what I did was cribbed and slightly modified from trac.ffmpeg.org/wiki/CompilationGuide/Centos.)

  1. Remove the existing ffmpeg.  I'm on CENTOS 6 (64 bit), so:
       yum remove ffmpeg-devel.x86_64
       yum remove ffmpeg-libpostproc.x86_64
       yum remove ffmpeg.x86_64
  2. Build x264.  As root:
       yum install lame*
       cd $HOME 
       mkdir ffmpeg_build
       mkdir ffmpeg_sources
       cd    ffmpeg_sources
       git clone git://git.videolan.org/x264.git
       cd x264
       PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" \
          ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
          (If it complains about nasm, install nasm from source from www.nasm.us)
       make install
  3. Build ffmpeg.  As root:
       cd $HOME/ffmpeg_sources
       git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
       cd ffmpeg
       PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" \
          ./configure --prefix="$HOME/ffmpeg_build" --extra-cflags="-I$HOME/ffmpeg_build/include" \
          --extra-ldflags="-L$HOME/ffmpeg_build/lib" --bindir="/usr/local/bin" \
          --pkg-config-flags="--static" --enable-gpl --enable-nonfree --enable-libfreetype \
          --enable-libmp3lame  --enable-libx264
       make install
Once the new ffmpeg is installed (in /usr/local/bin), I created a little shell script that does the conversion for me.  I've tested it successfully against mpg's and (mpeg4 based mp4's), and both get converted to H.264 mp4's such that Zenphoto shows them just fine.

Here's the conversion script, "tomp4":

   #---Converts a video file to an H.264 encoded mp4.
   if test "x$1" = "x"; then
      echo "Usage: tomp4 video-file (e.g. file.mpg or file.mp4)"
   base=`basename $1`
   base=`echo $base | sed "s/\.mpg$//" | sed "s/\.mp4$//"`
   nice /usr/local/bin/ffmpeg -i $1 -vcodec h264 -qscale 3 $base-video.mp4
   ls -l $base-video.mp4

V. Thumbnails of videos
Zenphoto has a nice little feature: if you drop a video into an album directory, and then drop in an image with the same base name, it will use the image as the thumbnail for the video.

So I wrote a tiny shell script that captures a frame of a video as an image, "oneFrame":

   if test "x$1" = "x"; then
      echo "Usage: oneFrame file.mp4"
   base=`basename $1 .mp4`
   nice /usr/local/bin/ffmpeg -i $1 -ss 00:00:01 -vframes 1 $base.png

VI. Footnotes
I had a royal pain getting imagick installed.  Here are some links that were helpful:

VII. Closing
Such were my trials and tributations with Zenphoto.  All that being said, it still seems to be the best of the bunch.

I would be interested in anyone's experience tinkering with Zenphoto and ffmpeg; comments and suggestions welcome, to croth @ this domain (look in the address bar).