Making my own torrent streaming service
Few weeks back Microsoft came to my college for the annual Code.Fun.Do hackathon. I was planning to make an app that extracted text from photographs taken by the phone camera and then does something. The idea had a lot of potential but initial tests were not very successful, primarily because text extraction was messed up nearly 8/10 times. It was clear that a lot more training and traindata was required for this to work and that demanded time but there was dearth of it and even more considering that mine was a one man team. So I decided to make an app that can be used to watch movies from torrents on mobile phone.
Microsoft guys were very excited to see it work but of course they can’t be supportive of it because it is not enitrely legal.
Note: Since the MAFIAA (quite literally) recently shut down YTS API which I was using for this app, you’ll have to use some other service like this one for aggregating torrents and this one for displaying the movie data. I won’t publish the code for this app since it is obsolete now.
Lets get started (no code)
Step1: Deciding the functionality
- The app should present movies in a Netflix/PopcornTime -ish interface.
- Tapping on the movie tile should bring up its page and display the relevant metadata.
- From there we should be able to watch the movie.
Step2: Deciding the technology stack
- The mobile app is built using Apache Corodova.
- For styling I used Bootstrap3, app logic is written in vanilla JS. The app had to run on WindowsPhone8. Alternatively, Ionic is a very good choice for styling and writing app logic using AngularJS; but given the time constraints, I did not opt for this.
- An intermediary API is setup on a DigitalOcean server using the Bottle Microframework in python. It is necessary to enable CORS because the app has to use AJAX calls.
- Torrenting is blocked by my ISP so transmission-daemon should run on the DO server to handle the requests related to torrents.
- Nodejs is used to stream the movie. vid-streamer is a good choice for that as it does a lot of heavy-lifting for us, like using correct MIME types and psuedo-streaming as well.
Step3: Implementing the program flow
- The app interacts directly with the YTS API (now defunct, see Note above) to fetch the latest movies filtered by ratings > 6 and sorted by date in descending order. The API responds with movies and some corresponding metadata like cover image which is used to display movies in tiles in a vertical layout.
- Tapping any movie tile takes us to the dedicated page where the expanded metadata is nicely presented and a
Preload Torrentbutton is present. Tapping it takes us to the downloads page where current ‘preloads’ are listed and sends the torrent file link to python server. The python server now talks to the transmission-daemon and delivers it the torrent using transmission-rpc. For that I used this python wrapper which has a very good documentation.
- Transmission-daemon downloads the torrent to a pre-designated directory based on the UUID of the device (there is a Corodova plugin to use that) which is also sent with each request to the python server to identify the user. This UUID is mapped to a userID in a sqlite3 database.
- The downloads page displays a progress bar which can be updated by tapping the ‘Check Status’ button which sends a request to python server which in turn talks to transmission-daemon for torrent status and returns the result in json format to the mobile app. Pressing the Home button takes us back to the main page.
- The vid-streamer configuration takes the directory input that houses the media files to stream. So if
file.mp4is present in
mydir/userID/movieNameand vid-streamer is running at
mydir, the url
$serverIP:8000/userID/movieName/file.mp4will correspond to the movie file.
- Tapping the movie name on downloads page sends a request to the python server to check if the movie preload is complete. If yes, the server returns the streaming URL which is then embedded in a
<video>tag on the app and video streaming starts!
Note: While its worth noting that pre-loading the movie on the DigitalOcean server takes only 3-4 minutes (and is recommended if the app is used by a small group or for personal use), there is another way to stream the movie i.e. directly from the torrent. For that you can use peerflix. Transmission cannot be used here as it only supports downloading. Be careful with the file encoding though. Browsers (Corodova apps are nothing but a wrapper over a browser), especially mobile ones, can only play a very limited set of encodings. Either look for an mp4 torrent or use FFMPEG on the server side or ditch the Corodova idea and make a native app and use libvlc. If you are feeling extra adventurous and don’t want to use peerflix, write your own implementation of the Bittorent protocol.
Going through the procedure produced this app: