Most video hosting sites have terms of service or usage that are problematic for us. For example there isn't a legal way to have a single "CHTC" YouTube account shared by multiple staff short of making a special arrangement with Google.

The good news is that there is no reason we can't just host the video ourselves!

The following is a general strategy.


Ideally you'll want a real video editing system. In a pinch you can use ffmpeg, but it's a pain in the butt. For free, Blender is pretty good, but the learning curve is terrible; adesmet may be able to offer help. Sony Vegas is quite good, if expensive. Ivan C (student hourly) or johnkn may be able to help.

General work to be done:

  1. Trim the video to the talk itself. Keep questions at the end if appropriate.
  2. Place video of speaker and the slides side-by-side. You might need to get the slides from the original file if video of the slides isn't available or is low quality. Crop the speaker fairly tightly so they are as large as possible but always in frame. The final ratio should be reasonably common, 4:3 or 16:9 are good choices
  3. Adjust the audio. Shoot for the loudest moments just barely clipping and generally in the -5 to -10 dB range.
  4. Target the lowest resolution that the slides are comfortably readable in. Try 640360.
  5. Do not add logos that are present through the entire video; they're distracting and unnecessary.

Here is a good example. Don't do the logos in the top left and lower right. You can see the full video at


Editing with ffmpeg

This is probably unnecessary if you have a full blown video editor, but occasionally quick command line tools are useful.

Lossless Trimming

You can use ffmpeg to do lossless trimming of files (say, to break a single video into multiple videos, or to trim off dead time). source

ffmpeg -ss START -t LENGTH -i ORIGINALFILE.mp4 -codec copy OUTFILE.mp4


You can also crop the video with ffmpeg, which may be useful if part of the video feel is always empty (say, the video is wide enough to handle a 16:9 slide, but only 4:3 slides are shown. This is lossy, so you'll probably want to merge it into the conversion step. source

ffmpeg -i ORIGINALFILE.mp4 -filter:v "crop=out_w:out_h:x:y" OUTFILE.mp4


Creating the video files

We're limiting support to "recent" web browsers (2011 and newer). To cover everyone, we need two files: H.264(baseline)+AAC(low complexity)+MP4 (Safari, Chrome, IE, Android, and iOS) and WebM (Firefox).

If your video editing software will export the required formats, you're good to go. If not, the easiest solution is to use ffmpeg. (Try /u/a/d/adesmet/bin/opt/ffmpeg/bin/ffmpeg )

ffmpeg -i input.mp4 -c:v libvpx -qmax 42 -qmin 10 -b:v 1M -c:a libvorbis -q:a 4 -f webm out.webm
ffmpeg -i input.mp4 -c:v libx264 -profile:v baseline  -movflags faststart -crf 23 -c:a libfdk_aac out.mp4

Warning: iPhones (as of 3S) can apparently only accept video up to 640480. (Maybe? Double check.) If this is true, we may want to also export low-resolution versions and have a link to a different place to view the videos for lower end devices.

By default ffmpeg seems to use a number of threads equal to the number of cores you have minus 1. You can speed things up by specifying your actual number of cores. For example "-threads 2" forces 2 threads.

FastStart and mobile browsers

MP4 files should have the "moov" block (the index correlating times in the video to bytes into the file) before the "mdat" block (the actual video). This is sometimes called "faststart." If you don't do it, many browsers will be unable to quickly seek into the middle of the video. In some cases, especially on mobile devices, the browser will refuse to play the video at all.

The ffmpeg commands above already worry about this ("-movflags faststart"). If you have MP4 files but they aren't correctly set up, the easiest solution is probably to use qtfaststart to fix it. There is a Python version that can be used without installing. ffmpeg may also ship with a qt-faststart.

Notes on creating video files

For a discussion on the general techniques involved as well as how to support even older browsers, you can look at Dive Into HTML5

For more details on the ffmpeg commands used, see This SuperUser question. This version has been modified. It uses the newer libfdk_aac instead of the older libfaac. It adds "-movflags faststart"; see the "FastStart and mobile browsers" section for details.

Extracting a poster

Ideally you want a poster image for the browser to display before the video is loaded. Here is a quick and dirty way to exact the first frame. Instead of "0" for "-ss", you can specify a number of seconds into the video to sample. You can also specify

ffmpeg -i input.mp4 -ss 0 -vframes 1 input.jpg


Put the files up for download! There is no reason to not just offer for download the exact same files created for streaming (below).

One solution:

  1. cd where-ever-your-web-page-is
  2. mkdir download
  3. cd download
  4. ls ../*.mp4 ../*.webm | xargs -n1 --replace ln -s '{}' ./
  5. cat > .htaccess <<END
    AddType application/octet-stream .mp4
    AddType application/octet-stream .webm
    <Files "*">
    	Header set Content-Disposition attachment

The .htaccess file ensures the files are served without a useful MIME type, discouraging browsers from trying to use them, and adds "Content-Disposition: attachment", which tells browsers to default to offering to save the file.

Having the .htaccess file do this requires that the main Apache configuration allow it. As of October 2014, the CSL's web server does.

Creating the HTML

If you're using our normal Mason system (generate_html), there is a module to simplify this. It assumes you have the video as .webm, .mp4, and a .jpg poster in the current directory, and that the download/ subdirectory contains symlinks to the webm and mp4 files. Given this, here is an example of using the video.mas module. It's for Karen's 2014 user tutorial. All of the files are named "Intro_To_Using_HTCondor.*" and the video is 640360.

<%method title2>Tutorial: An Introduction to Using HTCondor</%method>

<p>Presented by Karen Miller, summer of 2014.
<a href="">Download slides.</a>

<& /htcondor/lib/video.mas, name=>'Intro_To_Using_HTCondor', width=>640, height=>360 &>

If you need to do it by hand, check out htcondor/src/lib/video.mas in the htcondor-web repository. Here is a very simple example:

<p><video width="640" height="360" controls poster="FILENAME_GOES_HERE.jpg">
<source src="FILENAME_GOES_HERE.mp4 type="video/mp4; codecs=avc1.42E01E,mp4a.40.2">
<source src="FILENAME_GOES_HERE.webm" type="video/webm; codecs=vp8,vorbis">
Sorry, your web browser does not appear to support HTML5 video.

<p>Download video:
<a href="download/FILENAME_GOES_HERE.mp4">MP4</a>
<a href="download/FILENAME_GOES_HERE.webm">WebM</a>

<p>Download slides:
<a href="SOME_OTHER_PLACE.ppt">Powerpoint</a>
<a href="SOME_OTHER_PLACE.pdf">PDF</a>

Be sure to also include links to download the file and to the slides.

Building ffmpeg

Stock ffmpeg installs may not have functionality you require. The following, derived from worked on a CSL RHEL 6 computer as of October 2014.


mkdir ffmpeg-install
cd ffmpeg-install

curl -O
tar xzvf yasm-1.2.0.tar.gz
pushd yasm-1.2.0
./configure --prefix=$DST
make && make install && make distclean

git clone --depth 1 git://
pushd x264
./configure --prefix=$DST --enable-static
make && make install && make distclean

git clone --depth 1 git://
pushd fdk-aac
autoreconf -fiv
./configure --prefix=$DST --disable-shared
make && make install && make distclean

curl -L -O
tar xzvf lame-3.99.5.tar.gz
pushd lame-3.99.5
./configure --prefix=$DST --disable-shared --enable-nasm
make && make install && make distclean

curl -O
tar xzvf opus-1.1.tar.gz
pushd opus-1.1
./configure --prefix=$DST --disable-shared
make && make install && make distclean

curl -O
tar xzvf libogg-1.3.1.tar.gz
pushd libogg-1.3.1
./configure --prefix=$DST --disable-shared
make && make install && make distclean

curl -O
tar xzvf libvorbis-1.3.4.tar.gz
pushd libvorbis-1.3.4
./configure --prefix=$DST --with-ogg=$DST --disable-shared
make && make install && make distclean

git clone --depth 1
pushd libvpx
./configure --prefix=$DST --disable-examples
make && make install && make distclean

git clone --depth 1 git://
pushd ffmpeg
./configure --prefix=$DST --extra-cflags="-I$DST/include" --extra-ldflags="-L$DST/lib" --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264
make && make install && make distclean

# Excluded:
# --enable-libass - subtitles
# --enable-libfaac - AAC, dupe of libfdk_aac