Webtorrent

In this post I explain how to set-up webtorrent for streaming video files.

WebTorrent

As a university teacher I now produce quite some videos for my courses. This trend is actually emphasized by the current sanitary conditions.

These videos usually have a rather low number of views (200) but it can actually prove problematic if all viewers arrive on my web server at the same time. This is particularly true as some time-slots are now reserved for viewing course videos.

One solution to this problem is to turn it into asset. If all viewers arrive at the same time then we can turn them into peers. This will have an added benefit to reduce the strain on the network, especially if all viewers are located in the same rooms.

Peer to peer, large files ? Of course we want to do some BitTorrent. Now Bittorrent works by cutting a file into pieces and giving different pieces to each downloader so that they can then exchange between themselves. This means that the classical BitTorrent protocol is not well suited for streaming because receiving random pieces means you are very likely to have a missing piece near the beginning of the stream.

Here comes webtorrent. Webtorrent will skew the blocks distribution so that you can start viewing your video immediately while the download takes place. Better than that, your client will be a 400kb javascript client transparently embedded into a web page.

The last remaining problem is about seeding. Normally you want to seed your video 24h/24h and keep a torrent client running on your machine. It is however now possible to seed torrents using a web server. We just need to indicate a file url when creating the torrent and we will be able to let the university’s web server do the seeding for us.

Preparation

Ok, let’s get started. We need:

  • a torrent creator. I now use mktorrent. Not all torrent creators support web seeds. Another possibility I know of is create-torrent but this one is not available for my distribution.

  • the embedded webtorrent client

  • eventually a video encoder. I use ffmpeg which is included in every linux distribution.

Now what do we need to do ? It comes in three steps:

  1. Encode the video
  2. Create the torrent
  3. Create the webpage

Video Encoding

So you need two things. First, not all video formats can be used in html video tags. I usually encode in mp4. For my screencasts I record using vokoscreen which directly records an mp4.

However something else is needed. You need to have the video index at the beginning of the file so that the streaming can start immediately. For me vokoscreen does not do that so I need to re-encode my video which is as simple as:

ffmpeg -i input.mp4 -movflags faststart output.mp4

After a rather lengthy process your video is ready. You can now create the torrent.

Torrent creation

This step is easy, we just need to use mktorrent with the right option.

-w url in order to give the web seed. This url must the final place where the video file will be uploaded.

Since i have a hugo website, I use a small script to create torrents for any file I upload easily.

#!/bin/sh

if [[ $# -eq 0 ]] ; then
    echo 'give file in ./content'
    exit 0
fi

content=$1
file=`basename -s .mp4 $content`
dir=`dirname $content`
torrent_file="$dir/$file.torrent"
base_url=`echo $content | cut -d\/ -f3-`
url="http://datamove.imag.fr/frederic.wagner/$base_url"
mktorrent -a udp://tracker.coppersurfer.tk:6969/announce \
          -a udp://tracker.ccc.de:80/announce \
          -a udp://tracker.publicbt.com:80 \
          -a udp://tracker.istole.it:80 \
          -a http://tracker.openbittorrent.com:80/announce \
          -a http://tracker.ipv6tracker.org:80/announce \
          -v -w $url $content -o $torrent_file

Webpage

Final and last step, the webpage. We need to:

  • have a video element in the page
  • have a script launching the client, loading the torrent and feeding the video file to the video element

My webpages are usually written in markdown but for this operation I need to include some html code in my markdown pages.

<center>
<video controls/>
</center>

<script src="/webtorrent.min.js"></script>
<script>
var client = new WebTorrent()

var torrentId = 'http://datamove.imag.fr/frederic.wagner/posts/rust_intro/intro_rust.torrent'

client.add(torrentId, function (torrent) {
  // Torrents can contain many files. Let's use the .mp4 file
  var file = torrent.files.find(function (file) {
    return file.name.endsWith('.mp4')
  })

  // Display the file by adding it to the DOM. Supports video, audio, image, etc. files
  file.renderTo('video', {autoplay: false})
})
</script>

You just need to put the right urls for the location of the webtorrent.min.js file and the location of your torrent file.